将更改移动到不同的提交时进行交互式变基

5

在清理(主要是压缩)某些较大功能的历史记录时,我经常会遇到以下情况:

Commit A:
  - change A.1
  - change A.2
  - change A.3

// EDIT: maybe some more commits

Commit B:
  - change B.1
  - change B.2
  - change B.3

假设现在我想使用交互式变基将"change B.1"移动到提交A。迄今为止,我发现唯一的方法是:
  1. 启动"rebase -i"
  2. 编辑提交B
  3. 将提交B拆分为临时提交和提交B("reset HEAD^"然后"add -p")
  4. 启动"rebase -i"
  5. 在提交A中修正临时提交
这需要两次变基操作,非常繁琐。而且当拆分提交时,我必须重新编写提交B的提交消息。
有没有更好/更有效的方法来实现这一点?
1个回答

2

可能没有太大的改进,但是

  1. git rebase -i A^
  2. git cherry-pick --no-commit B
  3. git add -p
  4. git commit --amend
  5. git reset --hard
  6. git rebase --continue

是另一种选择。


我理解的是,当应用 B 时,这将合并双重更改,因此根据历史记录的复杂性(例如在 AB 之间的其他提交),应用 B 可能会创建不必要的合并冲突,这样对吗? - gzm0
哦,显然可能存在介入提交的情况并不明显。如果在 A 和 B 之间有涉及相同代码的提交,无论您使用何种方法将补丁块复制或移动到 A,您都必须解决冲突。但您可能是正确的,当 rebase 尝试应用提交 B 时,所提出的方法可能会导致另一个冲突。 - Magnus Bäck
谢谢您的分享。我对您使用 git reset --hard 清除未暂存更改非常感兴趣,这相比 git checkout . 有什么优势吗? - jackocnr
一些额外的注意事项:(1)这只适用于将更改移回到早期提交 - 如果您需要将更改向前移动到较新的提交,则必须使用问题中概述的方法。 (2)在 cherry pick 之后,您需要进行 git reset,因为这些更改已经被暂存了。 (3)当应用提交 B 时,您不应该遇到任何冲突,它应该跳过已经应用的任何更改(假设您将移动到 A 的更改与留在 B 中的更改干净地分开)。 - jackocnr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接