Git 更改分支,但不更改工作区中的文件



这与我的另一个问题类似(在不更改工作区文件的情况下切换到另一个分支),但在那里有效的解决方案现在不起作用。

我需要删除一些更改,这些更改很久以前就推送到了远程主机上。所以我不想从master中删除提交,但我想像恢复这些更改一样更改文件。所以我做了这个:

  1. 在主机上时,git branch limits
  2. git checkout limits
  3. git rebase --interactive <commit before the ones I wanted to remove>
  4. 在交互式控制台中,我删除了带有要恢复的更改的提交

所以现在在limits中,我有了我想要的master中的代码。如何将其"移动"到master?使用limits中的代码,我想更改为master分支,但不更改工作区中的任何文件,因此我可以将更改作为新更改提交给master

您提出的问题的答案是:

$ git checkout master             # switch to master branch
$ git reset --hard limits         # hard-reset it to the limits commit
$ git reset --soft master@{1}     # move the reference back to where it was, but
                                  #  don't modify the working tree or index

这将使您的工作树和索引与签出limits时完全一样,但您将在master分支的原始位置。


然而,这样做的正确方法是git revert您试图撤消的每个更改。

您可以恢复您不想要的每个提交,而不是使用交互式rebase。当您使用git revert <object-name-of-commit>时,git将引入一个新的提交,该提交将撤消您命名的提交所引入的更改。因此,假设您要删除的提交是abc123def456,您可以执行以下操作:

git checkout master
git revert abc123
git revert def456

但是,如果要找到这些提交需要大量的工作,并且您对limits的提示感到满意,那么您可以在master上创建一个新的提交,其中包含树的状态。首先,让确保git status是干净的,因为您将使用git reset --hard,这将消除未限制的更改:

git checkout master
git reset --hard limits
git reset --soft HEAD@{1}
git commit -m "Reverting unwanted commits"

这个配方是这个问题的一个变体:

  • https://stackoverflow.com/a/1895095/223092

这要求revert:-)

我会回到master和git-revert,每个您想要取消应用的提交。这会为每个提交创建一个"不适用"的提交,因此不会更改历史记录,但您可以获得所需的效果。

移动分支指针

如果您实际要做的是在一个复杂的重新基准或合并到一个单独的分支后移动master的分支指针,那么您可以通过多种方式来做到这一点。例如,要强制移动某个临时分支,使其成为您的新主分支,您可以执行以下操作之一:

# Use git porcelain to move the branch over top of one that already
# exists.
git branch -M limits master
# Explicitly move the branch pointer to wherever the head for limits
# is pointing.
git reset --hard refs/heads/limits

还有一些方法可以执行各种管道命令,但这并不是一篇详尽的论文。这应该足以让你指向正确的方向。

还原提交

正如其他帖子和评论正确指出的那样,如果您只想从master中撤消目标提交,那么您可以使用gitrevert(1)。请注意,这会在您的历史中留下原始提交和反转;这通常是您想要的。

此外,请注意,git revert可能会导致冲突或不需要的更改,您将不得不手动解决这些更改,特别是如果您正在恢复的提交不是小的原子更改。将git revert视为一个反向补丁(从根本上讲,它是在引擎盖下),您可以看到潜在冲突可能出现的地方。

你的里程肯定会有所不同。

最新更新