仅还原特定分支的提交,同时保持 "merged data"

Reverting a commit only a specific branch, while keeping the "merged data"

假设我有两个分支 Amaster。不小心添加并完成了一个功能到分支 A(它也在处理另一个正在工作 state/merged 中掌握但需要稍后继续的不同功能)。

现在我希望从 A 中删除产生新功能的提交,同时将主状态保留在当前 HEAD 中。理想情况下是这样的:

git checkout A
git revert HEAD~2..HEAD

但是这不会也还原 master 分支的 HEAD 吗?

HEAD是指向当前活动分支的指针。

在 运行 宁 git checkout A 之后,作用于 HEAD 将修改 A 而不是 master,
运行宁 git checkout master 之后,作用于 HEAD 将修改 master 而不是 A.


额外说明:

如果你的意图是 "cancel the last two commits from branch A",你可以 运行 :

git checkout A
git reset --hard HEAD~2

# if branch A was pushed,
# you will also need to push the corrected A :
git push origin --force-with-lease A

重写历史的解决方案:

git checkout A
git reset HEAD~2
git push origin A --force

一件重要的事情是,在 git reset 命令之后,您对最近两次提交的所有更改都将在工作目录中可用。它让您有机会创建另一个分支并继续处理它或在需要时隐藏它。

不重写历史的解决方案:

git checkout A
# automatically commits
git revert HEAD~2..HEAD
git push origin A

git checkout A

# doesn't commit automatically 
git revert --no-commit HEAD~2..HEAD

git commit -m 'Revert two last commits'
git push origin A

它将添加一个新的提交来反转最近两次提交的效果。

以上所有解决方案都没有改变master分支!

理论:

HEAD 是指向当前分支引用的指针,它又是指向该分支上最后一次提交的指针。

git checkout [<branch>] 到底是做什么的?

  • 更改 HEAD 以指向新分支 ref
  • 使用该提交的快照填充您的 index(暂存区)
  • index 的内容复制到您的工作目录中

git reset [<commit>] 的真正作用是什么?

  • 移动 HEAD 指向的分支(假设您当前在 master 分支上。运行 git reset [<commit>] 将使 master 指向至 [<commit>])
  • 用快照HEAD指向
  • 的内容更新index(暂存区)