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

时间:2012-07-13 15:29:36

标签: git branch git-branch

这与我的另一个问题(Switch to another branch without changing the workspace files)类似,但在那里工作的解决方案现在不起作用。

我需要删除一些很久以前推送到远程主服务器的更改。所以我不想删除master中的提交,但我想更改文件就像这些更改被还原一样。所以我这样做了:

  1. 在主人,git branch limits
  2. git checkout limits
  3. git rebase --interactive <commit before the ones I wanted to remove>
  4. 在交互式控制台中,我删除了我想要还原的更改的提交
  5. 所以现在在limits我的代码就像我在主人那样喜欢它。我如何“移动”它掌握?使用limits中的代码,我想更改为master分支,但不更改工作区中的任何文件,因此我可以将更改作为master的新更改提交。 / p>

4 个答案:

答案 0 :(得分:5)

您所陈述的问题的答案是:

$ 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您尝试撤消的每个更改。

答案 1 :(得分:5)

您可以只恢复您不想要的每个提交,而不是使用交互式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"

这个食谱是这个问题的一个变体:

答案 2 :(得分:1)

这要求revert: - )

我会回到掌握和git-revert每个你想要取消申请的提交。 这会为每个创建一个“取消应用”提交 - 因此没有历史记录更改,但您可以获得所需的效果。

答案 3 :(得分:0)

移动分支指针

如果你真正想要做的是在复杂的rebase之后移动你的分支指针或在一个单独的分支中合并,你可以用各种方式做到这一点。例如,要强制移动某个临时分支以使其成为新的主分支,您可以执行以下操作之一:

# 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中的目标提交,那么您可以使用git-revert(1)。请注意,这会在您的历史记录中保留原始提交和撤消;这通常你想要的。

另外,请注意,git-revert可能会导致您必须手动解决的冲突或不需要的更改,尤其是在您要还原的提交不小的原子更改时。把git-revert想象成一个反向补丁(从根本上说,它是在引擎盖下),你可以看到可能出现潜在冲突的地方。

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