My favourite method of merging feature branches has to be "rebase and merge" (that's a "semi-linear merge" if you're using DevOps) - it allows us to avoid losing data while keeping the tree clean and tidy.
But what is a rebase and how do they work?
⚠️ This article was written in and last updated in so may contain some out of date information.
I've taken an example git repository so we can walk through how we'd do this with rebase and merge.
We can actually see the merge of the feature/another-talk
branch is already complete since it's cleanly merged into main
with no intermediate commits to main - there was no need to rebase and merge, so it's just the other two branches we need to worry about.
Now, I've created a new branch from the latest main
and faded out our existing feature/git-talk
branch.
If you've ever done a cherry-pick before to move a commit from one branch to another, a rebase is like an extreme version of that! When told to rebase, git will cherry-pick each commit in a branch in turn and add it to a new branch at the point requested (in this case, a later version of the same main
branch).
Here I've "cherry-picked" the "Write talk" commit and put it onto our new branch.
Then we repeat that for all the other commits needed (including "fix typos" in that other branch), adding them in order and fixing any merge conflicts that may come about for each one.
And that's actually the rebase out the way! We've "cherry picked" each commit and resolved any merges, but in a more automated way than actually doing loads of cherry-picks.
Now it's time to merge feature/git-talk
into main
.
That old branch doesn't need to be there anymore - it doesn't actually exist locally, so we can hide that.
And then all we have to do is rebase and merge our final branch, feature/another-talk
.
To give us this!
Each feature makes a neat "D" shape with the main
or develop
branch, with no crossovers. As you can see, when compared to a traditional merge process shown below this method removes the muddle of crisscrossing merges, while maintaining the whole branch structure and all the detail in every commit.