【问题标题】:Git rebase, skip merge-commitsGit rebase,跳过合并提交
【发布时间】:2014-09-17 08:52:35
【问题描述】:

开始

    hack---F1----M1----F2  (feature)
   /            /
  C1-----C2----C3  (master)

我想结束

    hack---F1----M1----F2  (feature)
   /            /
  C1-----C2----C3---F1'---F2'  (master)

到目前为止,我拥有的最好的是

git checkout feature  
git checkout -b temp  
git rebase -i --onto master hack temp
   * Big drawback: manually remove the merged-in C2 and C3 from list of commits *
git checkout master  
git merge temp  
git branch -d temp  

我希望有人能回答,即使这是一个可疑的工作流程。

【问题讨论】:

  • git checkout master,然后git cherry-pick F1git cherry-pick F2 是你想做的,在这里。
  • 是的,在这种情况下,有两个提交樱桃挑选会很好,但有几个我更喜欢另一种方式。也许Cherry-pick range 带有某种排除选项?
  • 我正试图弄清楚你在一般情况下真正想要做什么......你能把你想做的事情表述为 cherrypick @987654328 之间的所有非合并提交@(不包括)和feature(包括)在master之上的尖端?

标签: git rebase


【解决方案1】:

简单案例

如果你的回购状态是

  hack---F1----M1----F2 [feature]
 /            /
C1-----C2----C3 [master]

你想到达

  hack---F1----M1----F2 [feature]
 /            /
C1-----C2----C3----F1'----F2' [HEAD=master]

你应该使用git cherry-pick,而不是git rebase -i(这里不需要处理交互式变基):

git checkout master
git cherry-pick <commit-ID-of-F1> <commit-ID-of-F2>

一般情况

如果我错了,请纠正我,但我明白你所说的 general case 是什么意思

cherry-pick,在master 之上,hack(不包括)和feature(包括)的尖端之间的所有非合并提交。

在下文中,我假设这确实是您的意思。

正如您在评论中正确指出的那样,随着手动挑选樱桃的提交数量的增加,上述方法的扩展性并不好:

  hack---F1---F2--- .... --- F68--M1---F67---...---F99 [feature]
 /                               /
C1-------------C2---------------C3 [master]

但是,您可以让git rev-list 自动生成感兴趣的修订列表,使用

git rev-list --reverse --no-merges --first-parent <commit-ID-of-hack>..feature

编辑:您还需要--first-parent 标志以避免收集诸如C1C2--reverse 标志之类的提交,以便以所需的顺序精心挑选提交。

您可以将该命令的输出传递给git cherry-pick

git checkout master
git cherry-pick `git rev-list --reverse --no-merges --first-parent <commit-ID-of-hack>..feature`

这会产生

  hack---F1---F2--- .... --- F68--M1---F67---...---F99 [feature]
 /                               /
C1-------------C2---------------C3---F1'---F2'---...---F99' [HEAD=master]

【讨论】:

  • 谢谢!这正是一般情况。但是我遇到了问题。位于 F2 的 rev-list-command 列出了 F2、C2、C1 和 F1 的 ID。即便如此,我还是用cherry-pick尝试了它。不幸的是,它在 F2 发生冲突后停止了。万一我忽略了问题中的一些细节,我提出了the test-repo on github
  • @Grastveit 你是对的;我的修订范围有问题。让我想想……
  • @Grastveit 查看我的编辑:如果您使用 --first-parent 标志,它应该可以工作。
  • 太好了,成功了。我还添加了 --reverse 以使 rev-list 恢复到时间顺序。将 hack 标记为“hack”后,在 master 上运行的命令变为:git cherry-pick `git rev-list --no-merges --first-parent --reverse hack..feature`
  • @Grastveit 你是对的。我会将该标志添加到我的答案中。
【解决方案2】:

查看您的原始工作流程,您似乎想忽略合并,唯一的问题是使用 -i 进行交互式变基,从而保留合并。

git checkout -b temp  
git rebase --onto master hack temp
   * Big drawback is gone!
git checkout master  
git merge temp  
git branch -d temp

应该完全按照您的意愿工作。不过,这可能并不能完全解决您的“一般情况”。

【讨论】:

    猜你喜欢
    • 2018-07-15
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 2017-11-04
    • 2011-12-19
    • 1970-01-01
    相关资源
    最近更新 更多