在将合并和提交都推送到原始位置之后,在上一次提交之前重做合并?

时间:2019-08-01 17:08:19

标签: git merge

我已经将“开发”合并到我的“功能”分支中,这产生了一些问题,然后我修复并提交了这些问题(“合并修复”)。然后,合并和“合并修订”都被推到原点。此后,合并似乎一开始并不令人满意,并引起了一些问题(事后看来,合并策略可能不是我想要的),并且使我的代码处于可运行但有错误的状态。所以我想回到合并之前,然后再次尝试合并。这是一次大规模的合并,因此手动还原更改并不可行。

我已经阅读了“ git revert”就是我想要的(还原“合并修订”),特别是“ git revert -m”还原了合并本身,但是我也读到这意味着我无法合并将来“发展”回我的“功能”分支,只有自原始合并以来所做的更改。我阅读正确吗?如果可以,我该怎么做再次尝试合并?

基本上,我想返回合并之前的提交,并在保留历史记录的同时再次尝试合并。从合并之前分支(例如'feature2')并再次执行会更容易吗?

非常感谢。

1 个答案:

答案 0 :(得分:3)

您的历史记录可能更复杂,但让我们以下面的历史记录为代表。

*   9a905c0 (HEAD -> feature) Merge branch 'develop' into feature
|\
| * 286195b (develop) Change 3
| * 39fc565 Change 2
* | bff23af Feature change 2
* | 8929388 Feature change 1
|/
* 5229c14 Change 1

您需要一个新的提交,该提交的树(即正在跟踪的所有文件的版本)与“功能更改2”(我的历史记录中的SHA1对象名称bff23af)匹配。管道命令git commit-tree可以做到这一点。这也可能是您在幕后的第一步,也是迈向Git向导的第一步。

要至少暂时返回您的BFF,请运行

git commit-tree -p 9a905c0 -m 'Undo incorrect merge; revert to bff23af' bff23af^{tree}

一次将其粉碎一遍:

  • -p选项为要成为新提交的父提交的提交提供SHA1对象名称。在这种情况下,我们希望父级成为有缺陷的合并。 (请注意,您可以使用多个-p <sha1>选项进行合并提交。)
  • -m与其他几个Git命令一样引入了提交消息
  • <sha1>^{tree}标识与提交 sha1 关联的树对象。您还希望它是与新提交关联的树,从而有效地回到尝试合并之前的状态。

管道命令被设计为由其他程序运行,并且对于用户而言可能有些麻烦。我的存储库中git commit-tree的输出是

16c6ef49aa4f3ea865d76e78b5306c52b14b1f0b

这是Git刚刚创建的新提交的SHA1对象名称。要将其带入功能分支,请运行

git merge --ff-only 16c6ef49aa4f3ea865d76e78b5306c52b14b1f0b

当我希望快速前进时,我喜欢投入--ff-only开关。它传达了我的意图,并且在做任何事情之前都会 失败。

合并后,历史记录变为

* 16c6ef4 (HEAD -> feature) Undo incorrect merge; revert to bff23af
*   9a905c0 Merge branch 'develop' into feature
|\
| * 286195b (develop) Change 3
| * 39fc565 Change 2
* | bff23af Feature change 2
* | 8929388 Feature change 1
|/
* 5229c14 Change 1

如您所见,我们没有重写历史记录,因此其他提交仍然存在。这意味着当您正确获得合并后,就可以推送功能分支。

确认树木与

相同
git diff 16c6ef4 bff23af

无输出表示无差异。考虑git如何代表历史,您也可以确认它们与

相同
$ git rev-parse 16c6ef4^{tree} bff23af^{tree}
d9cc608eedd5d2cc63c262272b7a0f6ab6aed5dd
d9cc608eedd5d2cc63c262272b7a0f6ab6aed5dd

git rev-parse的作用是将解决特定Git对象的任何方式转换为其SHA1对象名称。在这种情况下,我们问:“分别提交16c6ef4和bff23af的树对象的SHA1对象名称是什么?”输出的两行相同,意味着与这两个提交相关联的内容不仅相同但实际上它们是相同。后来的撤消提交和合并之前的提交现在共享同一棵树。

当然,在您的存储库中,提交消息和SHA1对象名称将有所不同,因此请在您的那一侧替换适当的值以获得所需的结果。