Git is pretty cool source code control. It is distributed, predictable, and does not feel like you have to tell it what to do.
Git tells you.
My colleague and I thought it would be a great idea for us to realign our source code structure. Our solution composes of various small projects from various small teams where we would like to put everything under one roof: our build to compile all of the different features, branches, and releases harmoniously.
The method, we thought, would be simple to keep our history somewhat clean when we do cut over.
git checkout -boff our main branch.
Issue a whole bunch of
git mvcommands to move the existing code into the desired location.
Whenever the main branch moves ahead, we simply use
git merge master --rebaseupon or “movement branch” and repeat steps one and two.
That is all very well… as long as you do not share this rebasing branch with anyone or on any other repository. As soon as you do this, this is what git will play out.
Upon further investigation, I learnt quite a bit about the purpose of Git rebase vs. merging.
One of those sources was on a public mailing list, where Linus Torvalds shared his purpose of creating these two features.
Put another way: think of the absolute chaos that would happen if I were to rebase instead of just merging. Every time I pull from you I’d invalidate your whole tree, and you’d have to re-generate. It gets unmaintainable very quickly.
And that’s actually ignoring a real issue: stability of commits. The nice thing about stable commit naming is that all bug-reports from other people that told where the bug happened are basically 100% trust-worthy and the code is 100% reproducible not just for you, but for everybody else.
In other words, you really shouldn’t rebase stuff that has been exposed anywhere outside of your own private tree. But within your own private tree, and within the commits that have never seen the light of day, rebasing is fine.
Jorrod Spillers also has an excellent blog post entitled “git merge vs git rebase: Avoiding Rebase Hell.” He dwelves in the internal workings of git, and really gives some great practical advice. If you are short of time, but need more reading material for your understanding read this!
But once the branch is being shared with anyone else it’s time to ditch the rebase and instead use merge to keep your experimental branches up to date with master.
So in conclusion:
- Merge by default. Even if you are in doubt.
- Rebase when your commits have not been shared and you know exactly how the rebase works.