合并到母版时,在压缩第一个分支后合并分支的分支


79

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

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上有一个南瓜策略,这意味着必须将合并到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合并到master中时,git被重新编写/压缩的历史混淆了,并且基本上将每个更改标记depedendent_branch为冲突。这是一个PITA,基本上需要进行重新执行或取消冲突dependent_branch。有解决办法吗?有时,我会手动创建一个补丁并将其应用到master的新分支上,但是如果与此产生任何实际冲突,则修复起来会更糟。

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.

有任何想法吗?我知道发生这种情况是由于壁球期间的重写历史记录,但这是我不能更改的要求。最好的解决方案/解决方法是什么?我能做些魔术吗?还是有更快的方法来完成与手动创建差异有关的所有步骤?


顺便说一句,这git add .是完全邪恶的,最终在您犯下您本来不想做的事情时最终会咬住您。您应该使用git add -p或至少使用git add -u .
meagar

1
完成代码审查更改后,应将dependent_branch重新建立到功能分支上。然后,当准备好进入母版时,将功能分支重新设置到母版上,并压缩提交,然后将功能分支合并到母版中。
2014年

Answers:


104

关于发生这种情况的一些信息:

在将功能分支合并到其中之后,我将O成为“原始主人”和FB“新主人”:

feature_branch看起来像:

O - A - B - C 

dependent_feature 最重要的是:

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

您将原始要素分支合并到master并将其压缩,从而得到:

O - FB

现在,当您尝试重新建立从属分支的基础时,git将试图找出这些分支之间的共同祖先。虽然它最初本来C,如果你没有压扁提交了下来,而不是混帐认定O为共同的祖先。其结果是,Git是试图重播AB以及C它们已经包含FB了,你会得到一堆的冲突。

因此,您不能真正依靠典型的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

我希望看到使用--onto时master的git树有何不同。也许还有其他方式可以进一步了解--onto的不同之处。
Abhishek Anand

3
--onto只是让您可以选择要重播到分支上的提交。默认情况下,git尝试“找出”应重播哪些提交。当使用--onto时,您明确指示git重播一定范围的提交。在我的示例中,如果不使用--onto,则最终会出现O-FB-A-B-C-D-E-F和许多合并冲突的情况,因为FB和A-B-C包含相同的更改。通过使用--onto并指定最后3个提交,您将得到O-FB-D-E-F,就像原始请求者所要的那样。
joshtkling '16

2

在这种特殊情况下,看来你“知道”原来工作的分支的压缩工作已被放入主文件。

因此,您可以在每次发生冲突时保持更改,从而快乐地合并。有一个选项:

git merge -Xours master

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


1
不幸的是,事实并非如此。如果对feature_branch和dependent_branch进行代码审查之间有时间,则有可能feature_branch可能会合并并推送,并且其他人可能会在登陆dependent_branch之前添加一些冲突内容。
迈克

0

我衷心不同意“将所有功能开发混为一谈”的政策,但这是他们的要求。

我会按原样保留分支,并在一个特殊的分支中创建一个仅用于发布的混搭提交。即使管理人员不相信开发过程,也能够逐步跟踪开发过程是很有价值的。通过“真实”分支中的标签标记南瓜的位置,还可以添加南瓜之间的标签,并带有指向真实提交的消息。


我实际上喜欢这种挤压,但这是因为它实际上是由arccanist完成的,并且功能分支的所有开发/提交/代码审查都存储在phabricator中...但是我可以肯定地说。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.