Git:如何编辑具有多个后代分支的旧提交?

时间:2014-04-23 19:47:11

标签: git git-rebase git-rewrite-history

我的git repo的历史看起来像:

* (topic2) commit_11
* (topic1) commit_10
* commit_9
* commit_8
* (HEAD, master) commit_7
* commit_6
* commit_5
* commit_4 <- I wanted to edit this commit.
* commit_3

所以我做了

git rebase -i commit_3

并在编辑器中将pick替换为edit for commit_4。 我用变量名更正了一些拼写错误然后

git add .
git commit --amend
(rename commit)
git rebase --continue

现在历史看起来像:

* (HEAD, master) commit_7.1
* commit_6.1
* commit_5.1
* commit_4.1 <- Edited commit.
| * (topic2) commit_11
| * (topic1) commit_10
| * commit_9
| * commit_8
| * commit_7
| * commit_6
| * commit_5
| * commit_4 <- Original commit.
|/
* commit_3

我想像以前那样让自己的历史变得干净利落。我试着在

之前多次成功使用的方式
git checkout topic1
git rebase master

但是在应用第一个补丁时最终会出现冲突。我手动解决了它们。但是当我尝试git rebase --continue时,它告诉我&#34;没有什么可以提交&#34;。

如何处理问题及其产生的原因?

1 个答案:

答案 0 :(得分:1)

(我冒昧地修改你的图表,表明当你进行rebase时,所有提交都会改变,即使内容没有改变。你的新提交将有不同的shas而不是原件。)

这里最简单的解决方案是使用--onto。看一下这个链接,从文本开始#34;以下是移植主题分支的方法&#34;:git rebase

所以在你的情况下,它将是:

git rebase --onto commit_7.1 commit_7 topic1

换句话说,在 commit_7之后从提交,直到(包括)topic1,并将它们移植到commit_7.1。

但是,您可能仍然会遇到必须手动修复的合并失败。

我建议您在执行此操作时,在topic1提交上创建一个额外的分支。称之为topic1old或其他东西。这样可以让人们更容易回头,以防底板不合适;您可以将主题1重新硬重置回该提交。

编辑:为什么简单的git rebase master无效?

如果你不这么说,那么git rebase就假定你已经对你的上游分支进行了重新定位。

但是从我修改图表的方式看,topic1和master不再有共同之处。如果你对master做了一个简单的rebase,那么topic1会尝试将你所有的提交重新命名为master上的所有提交。这意味着你会得到类似的东西:

  • (topic1)commit_10
  • commit_9
  • commit_8
  • commit_7
  • commit_6
  • commit_5
  • commit_4
  • (HEAD,master)commit_7.1
  • commit_6.1
  • commit_5.1
  • commit_4.1&lt; - 已编辑提交。
  • commit_3

现在Git很聪明,不会重复已经存在的提交。显然,如果您更改X,Y和Z,然后稍后提交再次进行,Git会省略后面的提交,因为这些更改已经存在。

但是什么引发了事情是你提交的改变4.结果是之后的所有提交都提交到一组不同的代码。这留下了很多合并的潜在必要性。

使用--onto修复此问题,因为它允许您使用不同的基础。你说的是:&#34;我不关心commit_4(因为我改了它),也不关心commit_5,_6和_7(因为我已经把它们合并了,而且他们&#39;与我的主题分支基本相同)。所以从commit_8开始,在我已经处理过的东西之上重新调整那些变化。&#34;