GitHub" Squash并合并后的Rebase分支"主人

时间:2017-01-25 18:48:44

标签: git github git-merge git-squash

我们假设我已在branch1上开发了一项功能,并使用Gi​​tHub Pull Request将其发送给代码审核。在对其进行审核时,我会对branch2进行一些后续工作。

 branch2                   -> D --> E --> F
                          /    
 branch1  -> A --> B --> C
         /
 master M

我的评论员喜欢我的作品!无需更改。我使用GitHub的Squash and merge功能合并了branch1的提取请求。

git pull上运行master并删除branch1后,我就离开了这种情况:

 branch2  -> A --> B --> C -> D --> E --> F
         /
 master M --> S

要为branch2发送一个外观整洁的PR,我想让我的提交树看起来像这样:

 branch2        -> D' --> E' --> F'
               /
 master M --> S

S处的代码(#34生成的提交; Squash和合并#34; branch1生成的提交)与C相同,因为它只是压扁版A --> B --> C

实现此目标的一种方法是在branch2上运行这样的序列:

git reset --hard S
git cherry-pick D E F

但是以这种方式列出所有提交变得乏味,而且这真的感觉就像一个rebase。当然,git rebase master无法工作,因为提交ABC需要消失。

从一个祖先提交的压缩版本中修改分支的最佳方法是什么?

1 个答案:

答案 0 :(得分:10)

git rebase--onto一起使用。这仍然有点棘手,所以为了方便起见,你会想要做一件与众不同的事情。

顺便说一下,我认为用 right 侧的分支名称绘制这些图表会更好,指向一个特定的提交。这是因为在Git中,提交在多个分支上,而分支名称​​ do 只是指向一个特定的提交。它也值得翻转内部箭头(因为Git真的以这种方式存储它们)或者只是使用连接线以免意味着错误的方向。

因此:

          D--E--F   <-- branch2
         /    
  A--B--C       <-- branch1
 /
M          <-- master

提交AC确实在branch1 branch2,同时提交D到{{1}在F上只有 。 (提交branch2及更早版本在所有三个分支上。)

M做的是选择所有 1 提交当前分支到达,但无法从 git rebase upstream 参数,然后复制它们(使用upstream或等效项),以便它们在 git cherry-pick 提交后立即生效。

壁球后 - &#34;合并&#34; (不是真正的合并),如果你运行upstream然后快进你的git fetch,你就会得到同样的东西,但我会留下master并将标签放在离开并在此处添加branch1

origin/master

(或者,如果您没有快进 D--E--F <-- branch2 / A--B--C <-- branch1 / M--S <-- master, origin/master ,只需master分即可提交origin/master

您现在想告诉Git使用cherry-pick复制S,然后移动标签D-E-F以指向上次复制的提交。您 希望复制branch2,因为它们已合并到A-B-C中。您希望副本在S后追踪S现在指向的位置 - 无论您是否已更新origin/master。因此:

master

git checkout branch2 git rebase --onto origin/master branch1 现在是upstream而不是branch1,但master会告诉Git将副本放在哪里:{{1} }仅用于界定不要复制的内容。所以现在Git复制--onto并更改branch1指向那里:

D-E-F

现在您可以删除名称branch2。 (现在你可以快进 D--E--F [abandoned] / A--B--C <-- branch1 / M--S <-- master?, origin/master \ D'-E'-F' <-- branch2 如果你还没有 - 当你这样做时并不重要,事实上你不需要你自己branch1来所有。)

1 更准确地说,rebase选择的提交是(a)不合并提交和(b)与排除集中的某些提交没有相同的master,使用对称区别。也就是说,而不是master,Git实际上在git patch-id upstream..HEAD上运行git rev-list,用upstream...HEAD或类似的方式来挑选提交。实现方式略有不同,具体取决于特定类型的rebase。