繁体   English   中英

使用 git rebase 编辑合并提交

[英]Edit a merge commit with git rebase

在 Git 中,当我提交时,例如。 A - B - C并且我想编辑B提交,我

  • 使用git rebase -i <A-commit-hash>
  • 在列表中我在B提交前写了edit命令,
  • git rebase 在B提交后立即停止,因此我可以使用git commit --amend修复我想要的任何git commit --amend
  • 然后我继续使用git rebase --continue

据我所知,这是如何做到这一点的最佳实践。 使用这种方法,我可以编辑过去的任何提交(只要它还没有被推送到远程分支),而且使用-p标志我什至可以保留合并。 这太棒了。

我目前的问题是:我在合并提交中的一行上犯了一个错误(错字)(同时在合并两个分支时解决了冲突)。

我想修复它,但我不知道如何让git rebase在合并提交时停止。 git rebase -p -i <blah>列表忽略了合并提交,所以我不能在它前面写edit命令并使git rebase停在那里让我编辑它。

请问有什么帮助吗? 我只想在合并提交中修复这一行,同时保留它之后的所有提交(和合并)。

谢谢。

2020 年的更新答案:

您可以通过break命令(在 Git 2.20 中添加)强制git rebase -i在合并提交处停止。 然后,您可以根据需要通过git commit --amend编辑合并提交。

详细步骤:

  1. 运行git rebase -i --rebase-merges $ancestor_of_merge_commit
  2. 在待办事项列表中找到要编辑的合并提交。
  3. 在仅包含break (或b )的合并提交之后插入一个新行。
  4. 保存更改并退出编辑器。 Git rebase 将检查合并提交,打印如下内容,然后返回到提示:
     Stopped at fb91fab (Merge branch 'foo' into bar)
  5. 使用git commit --amend根据需要编辑合并提交。
  6. 完成编辑合并提交后,运行git rebase --continue

如果您在要编辑的提交之后没有任何合并提交,则采用另一种方法:

  1. 运行git rebase -i $id_of_merge_commit
  2. 在 todo 列表的顶部插入一个仅包含break (或b )的新行。
  3. 保存更改并退出编辑器。 Git rebase 将检查合并提交,打印如下内容,然后返回到提示:
     Stopped at fb91fab (Merge branch 'foo' into bar)
  4. 使用git commit --amend根据需要编辑合并提交。
  5. 完成编辑合并提交后,运行git rebase --continue

2012 年的原始答案( break前):

当涉及合并时,Git 并不能轻松地进行交互式变基。 -p选项在内部使用-i机制,因此将两者混合并不能真正起作用。

然而, git rebase只是一种自动进行大量挑选的方法。 您可以通过手动挑选来复制其行为,以更好地控制该过程。 它不太方便,更容易出现人为错误,但有可能。

这是我建议的方法:

  1. 合并使用git rebase进行提交(合并的子项)
  2. 使用git reset --hard HEAD^手动进入合并
  3. 使用git commit --amend修复合并
  4. 合并后使用git cherry-pick返回提交
  5. 使用git rebase --continue完成

下面是具体步骤:

  1. 请注意要修改的合并提交的 SHA1 ID。 为了讨论,假设它是deadbeef
  2. 请注意在您要修改的合并提交(合并提交的子项)之后提交的 SHA1 ID。 假设它是facef00d
  3. 运行git rebase -i deadbeef
  4. 选择facef00d进行编辑。
  5. 当 rebase 返回提示编辑facef00d ,运行git reset --hard HEAD^ 你现在应该在deadbeefgit rev-parse HEAD应该打印deadbeef )。
  6. 进行编辑以修复不正确的合并冲突并使用git add它们。
  7. 运行git commit --amend将分阶段修复与错误合并提交融合。 结果现在将具有不同的 SHA1(不是deadbeef )。
  8. 运行git cherry-pick facef00dfacef00d所做的更改应用到固定的合并提交。
  9. 运行git rebase --continue完成。

现在使用 Git 2.22 及更高版本中提供的--rebase-merges选项更容易。 此选项保留合并拓扑,并与交互式变基一起使用。

它看起来像这样,假设B是要修改的合并提交:

label onto

... some branch definitions ...

reset onto
merge -C B branch-name # Merge branch 'B' into whatever
pick C

您现在可以在mergepick之间插入b (或break ):

merge -C B branch-name # Merge branch 'xyz' into whatever
break
pick C

在 break commit --amend合并,然后继续 rebase。

这也适用于修复提交。 例如,假设合并修复的提交是D 您可以在合并提交后立即将修复提交 D 移动到:

merge -C B branch-name # Merge branch 'xyz' into whatever
fixup D
pick C

请参阅 git-merge 手册页的变基合并部分。

创建修复提交“D”然后使用“ git rebase -p -i <blah> ”在“B”之后重新排序“D”并将其压缩为“B”可能更容易。

pick A
pick B  <- merge commit to ammend
fixup D
pick C

tl; dr:有时您根本不应该使用git rebase来编辑合并提交。 另一种方法可能更有效。

我刚刚经历过一个这样的场景:我有一个合并提交,它正在一个非常旧的分支中合并,并且在合并提交中解决了许多冲突。 合并后有一些额外的提交,然后发现在一个文件的冲突解决期间在大合并提交中犯了错误。 我按照接受的答案中的描述设置了交互式 rebase,但是当我的机器在 2/59 锁定时,我意识到由于重新组织我的文件系统以匹配旧分支,它正在写入大量文件。 几分钟后我杀死了它,中止了 rebase,然后不得不删除 100K 文件才能回到我开始的地方。 我没有变基,而是这样做了:

  1. 记下我修复合并提交后要重播的提交 ID。
  2. git reset --hard [merge-commit-id]
  3. 进行更改并简单地修改 HEAD 提交(即合并提交)。
  4. Cherry 在合并提交后按顺序选择每个提交 ID,或者使用git rebase --onto和 3 个参数来选择整个范围,如果不仅仅是几个。)

快得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM