合并到第一个分支后合并分支的分支在合并到主分支时被压扁

时间:2014-03-23 15:44:51

标签: git squash arcanist

这是我在工作中经常处理的工作流程。

git checkout -b feature_branch
# Do some development
git add .
git commit
git push origin feature_branch

此时功能分支已经开始供我的同事审核,但我希望继续开发依赖于feature_branch的其他功能。因此,feature_branch正在审核中......

git checkout feature_branch
git checkout -b dependent_branch
# Do some more development
git add .
git commit

现在我做了一些更改以响应feature_branch

上的代码审查
git checkout feature_branch
# Do review fixes
git add .
git commit
git checkout dependent_branch
git merge feature_branch

现在这是我们遇到问题的地方。我们在master上有一个squash策略,这意味着合并到master中的功能分支必须被压缩成一个提交。

git checkout feature_branch
git log # Look for hash at beginning of branch
git rebase -i  first_hash_of_branch # Squash feature_branch into a single commit
git merge master

一切都很酷,除了dependent_branch。当我尝试将依赖分支重新绑定到master或尝试将master合并到其中时,git会被重写/压缩历史混淆,并且基本上将depedendent_branch中的每个更改标记为冲突。它是一个PITA,可以基本上重新执行或解除dependent_branch中所有更改的冲突。这有什么解决方案吗?有时候,我会手动创建一个补丁并将其应用到一个新的主分支上,但是如果与它有任何真正的冲突,那就更难以修复了。

git checkout dependent_branch
git diff > ~/Desktop/dependent_branch.diff
git checkout master
git checkout -b new_dependent_branch
patch -p1 < ~/Desktop/dependent_branch.diff
# Pray for a clean apply.

有什么想法吗?我知道这是因为壁球期间重写的历史,但这是我无法改变的要求。什么是最好的解决方案/解决方法?我能做些什么吗?或者有更快的方法来完成手动创建差异所涉及的所有步骤吗?

3 个答案:

答案 0 :(得分:72)

关于为什么会发生这种情况的一点点:

在合并功能分支后,我会让O成为“原始主人”而FB成为“新主人”:

feature_branch看起来像:

O - A - B - C 

dependent_feature还有一些额外的提交:

O - A - B - C - D - E - F

您将原始功能分支合并为主分区并将其压缩,然后为您提供:

O - FB

现在,当你尝试重新定义依赖分支时,git将尝试找出这些分支之间的共同祖先。虽然最初会是C,但如果你没有压缩提交,git会发现O是共同的祖先。因此,git正在尝试重放A已经包含BCFB,而您将继续得到一堆冲突。

出于这个原因,你不能真正依赖一个典型的rebase命令,你必须通过提供--onto参数来更加明确它:

git rebase --onto master HEAD~3  # instruct git to replay only the last
                                 # 3 commits, D E and F, onto master.

根据分支机构的需要修改HEAD~3参数,您不必处理任何多余的冲突解决方案。

一些替代语法,如果您不喜欢指定范围并且尚未删除原始要素分支:

git rebase --onto master feature_branch dependent_feature

                                 # replay all commits, starting at feature_branch
                                 # exclusive, through dependent_feature inclusive 
                                 # onto master

答案 1 :(得分:1)

在这种特殊情况下,你似乎已经知道了#34;那个唯一你最初工作的分支的压扁工作已被掌握。

因此,每当发生冲突时,您都可以通过保留更改来愉快地进行合并。有一个选项:

git merge -Xours master

有关详细信息,请参阅https://git-scm.com/docs/git-rebase

答案 2 :(得分:0)

我衷心地不同意将每个功能开发混合到一个提交中#34;政策,但这是他们的号召......

我按原样保留分支,并在特殊分支中创建仅用于发布的混合提交。即使管理层不相信,能够一步一步地遵循发展也是有价值的。在&#34;真实&#34;中用标记标记南瓜的位置。分支,你也可以添加壁球标签和指向真实提交的消息。