Merging a branch of a branch after first branch is squashed when merged to master

arcanist, git, squash

Solution

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

Problem

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?

Original source