如何在git merge之后使用git rebase -i而不会搞砸了?

时间:2010-11-11 09:29:05

标签: git merge rebase

我有以下情况: 我对我的本地存储库进行了一些提交,然后将另一个分支(~150次提交)大量合并到主服务器中 - 它中存在很多冲突。

现在,我想在合并之前将我提交的提交移动到推送之前。

通常情况下,我会使用“rebase -i”。

不幸的是,默认行为是打破我做过的一次合并提交实际上已经将150多次提交添加到单独的提交中(我理解它就像我将使用rebase而不是合并开始) - 这是对我来说不好的行为有几个原因。

我发现了rebase的'-p'标志,它保留了合并,并且非常高兴。 不幸的是,这实际上再次应用了相同的合并,并且忘记了我在解决冲突方面的辛勤工作。再次 - 不好的行为!

是否有我想要的解决方案?合并后使用rebase -i重新排序或编辑特定提交而不必重复我的合并后操作?

谢谢!

3 个答案:

答案 0 :(得分:12)

以下是我在评论中提到的rerere-train.sh脚本的内容 - 基本上它重做了合并,使用了你的分辨率,只是让我们重新看到它。如果您愿意,可以手动为单个提交执行此操作:

git checkout <parent of merge commit>
git merge <merged commit>         # if this goes cleanly, we're done
git rerere                        # done automatically if rerere.enabled is true
git checkout <merge commit> -- .  # check out the files from the result of the merge
git rerere                        # done automatically if rerere.enabled is true
git reset --hard                  # wipe away the merge

# and you'd want to follow with git checkout <branch> to return to where you were

但您也可以将rerere.enabled设置为true,并执行这些步骤减去对git rerere的直接调用 - 并且您将来会设置,并且每当您解决时都会自动运行rerere冲突。 这就是我做的事情 - 这太棒了。

如果您想直接运行脚本,您可能希望使用rerere-train.sh ^<commit before the merge> <current branch>之类的参数运行它。 (^commit符号表示“不要将其移到历史记录中”,因此它不会为您的回购中的所有合并提交执行此操作。)

然而,如果你想做到这一点,你应该最终记录下所需的分辨率。这意味着你可以继续做你的rebase -i,当你遇到冲突时,rerere将重新使用REcorded REsolution。只是一个单挑:它仍然在索引中留下标记为冲突的文件,以便您可以检查它们,并确保它的作用是有意义的。完成后,使用git add检查它们,就像您自己解决冲突一样,并照常继续!

git-rerere manpage包含对正常使用rerere的非常好的,冗长的描述,它实际上并不涉及实际调用rerere - 它全部自动完成。并且它没有强调一个注释:它都是基于冲突困境,所以它可以重用一个解决方案,即使冲突最终在一个完全不同的地方,只要它仍然是相同的文本冲突。

答案 1 :(得分:1)

我制作了一个脚本来执行此操作here。有关已知限制,请参阅open issues

您需要先在{PATH}上安装rerere-train.sh。在Fedora上可以通过以下方式完成:

    install "$(rpm -ql git|grep '/rerere-train.sh$')" ~/bin

答案 2 :(得分:0)

我使用了来自@ Jefromi用户答案的​​rerere-train.sh。但是我有这个错误:

$ ../rerere-train.sh HEAD
C:\Program Files\Git\mingw64/libexec/git-core/git-sh-setup: line 6: .: git-sh-i18n: file not found

从这http://kernel.opensuse.org/cgit/kernel-source/commit/?h=linux-next&id=d52b9f00588bb18d7f7a0e043eea15e6c27ec40c我看到了这个:

  

Michal Marek

     

git-sh-setup帮助器显然从来没有被使用过   git之外的脚本。这在git 2.10中显而易见:

downloading an older version - 2.3.4便携式之后 - 我设法让rerere-train.sh工作。