撤消功能分支合并
undo feature branch merge
最近一段时间我一直在研究一个分支的新功能。特性完成后,我将特性分支压缩合并回 master,并删除了特性分支。合并提交的哈希值是 7ba3dc2fea43cd33c4d5ba11baf2765cbbdb0284.
我现在需要还原此合并。具体来说,我想实现的是:
- 新功能的更改已从 master 中删除
- 新功能的更改在功能分支上,随后可以合并到 master
一些可能相关的附加信息:
- 在合并提交之后有一些提交需要掌握,但是如果撤消合并丢失这些提交并不重要,因为重新应用这些更改是微不足道的
- 我没有能力直接提交到master,所以撤消合并的过程必须通过创建分支,提出PR,然后在PR被批准后将分支合并到master来实现.
如何将新功能的更改移回功能分支?
这一次,您使用挤压合并而不是真正的合并会让您的生活更轻松。 (我假设“挤压合并”是指 the --squash
argument to git merge
,或其他 UI 中的等效功能。)
“压缩合并”实际上并没有以任何方式引用原始提交,它只是创建一个新提交,该提交应用了它们本应带来的所有更改。因此要撤消该提交,您可以创建一个新的提交从 master 分支,并使用 git revert 创建一个新提交,撤消 squash 合并提交中的所有更改。
要取回旧分支,您需要找到删除它时指向的提交哈希。如果您在网络 UI (Github / Gitlab / BitBucket) 中使用了“Pull Request”或“Merge Request”,它将列在那里(甚至可能有一个“恢复分支”link).如果您在本地签出它,它可能会在 git reflog
中可见。找到它后,只需键入 git branch feature-foo-resurrected abc123def
,将“abc123def”替换为您找到的提交哈希。
作为最后的手段,您可以基于压缩提交创建一个分支,方法是使用 git cherry-pick 创建一个具有相同内容的新提交。 (仅仅指向那个提交的分支没有帮助,因为它已经在“master”的历史中,所以将显示为“没有要合并的东西”。)
所以整个序列可能看起来像:
git switch master
git pull --ff-only origin
# create a branch which undoes the squash merge
git switch -c revert-feature-foo
git revert 7ba3dc2fea
git push origin
# now create a branch which *redoes* the squash merge on top of that
# only needed if you can't find the original feature branch
git switch -c feature-foo-resurrected
git cherry-pick 7ba3dc2fea
git push origin
您可以试试下面的方法
还原提交
$ git revert --no-commit '<commitnumber>'
# Files that were modified in the commit will be changed in your working directory
$ git commit -a -m "Revert commit <commit number>"
创建功能分支并挑选提交
$ git checkout -b 'Feature Branch name'
$ git cherry-pick '<commitnumber>'
$ git commit
大多数情况下,根据后续提交中 git 存储库中已更改的文件数量,您最终会遇到一些冲突
最近一段时间我一直在研究一个分支的新功能。特性完成后,我将特性分支压缩合并回 master,并删除了特性分支。合并提交的哈希值是 7ba3dc2fea43cd33c4d5ba11baf2765cbbdb0284.
我现在需要还原此合并。具体来说,我想实现的是:
- 新功能的更改已从 master 中删除
- 新功能的更改在功能分支上,随后可以合并到 master
一些可能相关的附加信息:
- 在合并提交之后有一些提交需要掌握,但是如果撤消合并丢失这些提交并不重要,因为重新应用这些更改是微不足道的
- 我没有能力直接提交到master,所以撤消合并的过程必须通过创建分支,提出PR,然后在PR被批准后将分支合并到master来实现.
如何将新功能的更改移回功能分支?
这一次,您使用挤压合并而不是真正的合并会让您的生活更轻松。 (我假设“挤压合并”是指 the --squash
argument to git merge
,或其他 UI 中的等效功能。)
“压缩合并”实际上并没有以任何方式引用原始提交,它只是创建一个新提交,该提交应用了它们本应带来的所有更改。因此要撤消该提交,您可以创建一个新的提交从 master 分支,并使用 git revert 创建一个新提交,撤消 squash 合并提交中的所有更改。
要取回旧分支,您需要找到删除它时指向的提交哈希。如果您在网络 UI (Github / Gitlab / BitBucket) 中使用了“Pull Request”或“Merge Request”,它将列在那里(甚至可能有一个“恢复分支”link).如果您在本地签出它,它可能会在 git reflog
中可见。找到它后,只需键入 git branch feature-foo-resurrected abc123def
,将“abc123def”替换为您找到的提交哈希。
作为最后的手段,您可以基于压缩提交创建一个分支,方法是使用 git cherry-pick 创建一个具有相同内容的新提交。 (仅仅指向那个提交的分支没有帮助,因为它已经在“master”的历史中,所以将显示为“没有要合并的东西”。)
所以整个序列可能看起来像:
git switch master
git pull --ff-only origin
# create a branch which undoes the squash merge
git switch -c revert-feature-foo
git revert 7ba3dc2fea
git push origin
# now create a branch which *redoes* the squash merge on top of that
# only needed if you can't find the original feature branch
git switch -c feature-foo-resurrected
git cherry-pick 7ba3dc2fea
git push origin
您可以试试下面的方法
还原提交
$ git revert --no-commit '<commitnumber>'
# Files that were modified in the commit will be changed in your working directory
$ git commit -a -m "Revert commit <commit number>"
创建功能分支并挑选提交
$ git checkout -b 'Feature Branch name'
$ git cherry-pick '<commitnumber>'
$ git commit
大多数情况下,根据后续提交中 git 存储库中已更改的文件数量,您最终会遇到一些冲突