合并到母版时,在压缩第一个分支后合并分支的分支 [英] Merging a branch of a branch after first branch is squashed when merged to master

查看:82
本文介绍了合并到母版时,在压缩第一个分支后合并分支的分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

解决方案

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

在功能分支合并到以下位置后,我将O设为原始主",将FB设为新主":

feature_branch像这样:

O - A - B - C 

dependent_feature除此之外,还有一些额外的提交:

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

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

O - FB

现在,当您尝试重新建立从属分支的基础时,git将尝试找出这些分支之间的共同祖先.虽然最初本来是C,但是如果您没有压缩提交内容,则git会找到O作为共同祖先.结果,git尝试重播FB中已已包含ABC,您将遇到很多冲突./p>

由于这个原因,您不能真正依靠典型的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

Here's a workflow that I commonly deal with at work.

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

At this point the feature branch is up for review from my colleagues, but I want to keep developing on other features that are dependent on feature_branch. So while feature_branch is in review...

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

Now I make some changes in response to the code review on feature_branch

git checkout feature_branch
# Do review fixes
git add .
git commit
git checkout dependent_branch
git merge feature_branch

Now this is where we get have problems. We have a squash policy on master, which means that feature branches that are merged into master have to be squashed into a single commit.

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

Everything is cool, except with dependent_branch. When I try to rebase dependent branch onto master or try and merge master into it, git is confused by the re-written/squashed history and basically marks every single change in depedendent_branch as a conflict. It's a PITA to go through and basically re-do or de-conflicticize all of the changes in dependent_branch. Is there some solution to this? Sometimes, I'll manually create a patch and apply it off a fresh branch of master, but if there's any real conflicts with that, its even worse to fix.

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.

Any ideas? I know this happens because of the re-written history during the squash, but that's a requirement that I can't change. What's the best solution / workaround? Is there some magic I can do? Or is there a faster way to do all the steps involved with manually creating the diff?

解决方案

A little bit about why this happens:

I'll let O be "original master" and FB be "new master", after a feature branch has been merged in:

Say feature_branch looks like:

O - A - B - C 

dependent_feature has a few extra commits on top of that:

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

You merge your original feature branch into master and squash it down, giving you:

O - FB

Now, when you try to rebase the dependent branch, git is going to try to figure out the common ancestor between those branches. While it originally would have been C, if you had not squashed the commits down, git instead finds O as the common ancestor. As a result, git is trying to replay A, B, and C which are already contained in FB, and you're going to get a bunch of conflicts.

For this reason, you can't really rely on a typical rebase command, and you have to be more explicit about it by supplying the --onto parameter:

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

Modify the HEAD~3 parameter as necessary for your branches, and you shouldn't have to deal with any redundant conflict resolution.

Some alternate syntax, if you don't like specifying ranges and you haven't deleted your original feature branch yet:

git rebase --onto master feature_branch dependent_feature

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

这篇关于合并到母版时,在压缩第一个分支后合并分支的分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆