Simpler Rebasing (avoiding unintentional merge commits)
git rebasePlanet DrupalgitExecutive summary: Set up to automatically use a git pull --rebase
Please just do this if you do nothing else:
git config --global branch.autosetuprebase always
About rebasing and pulling
I've written a couple of articles on rebasing and why to do it, but it does seem that the approaches can be too complex for some workflows. So I'd like to propose a simpler rebase approach and reiterate why rebasing is important in a number of situations.
Here's a simple way to avoid evil merge commits but not do the fancier topic branch approaches:
- Go ahead and work on the branch you commit on (say 7.x-1.x)
- Make sure that when you pull you do it with
git pull --rebase
- Push when you need to.
That's it.
Reasons to rebase to keep your history clean
There are two major reasons not to go with the default "git pull" merge technique.
- Unintentional merge commits are evil: As described in the Git disasters article, doing the default git pull with a merge can result in merge commits that hide information, present cryptic merge commits like "Merge branch '7.x' of /home/rfay/workspace/d7git into 7.x" which explain nothing at all, and may contain toxic changes that you didn't intend. There is nothing wrong with merges or merge commits if you intend to present a merge. But having garbage merges every time you do a pull is really a mess, as described in the article above.
- Intentional merge commits are OK if you really want that branch history there: If a significant, long-term piece of work has gone on and should be shown as a branch in the future history of the project, then go ahead and merge it before you commit, using git merge --no-ff to show a specific intentional merge. However, if the work you're committing is really a single piece of work (the equivalent of a Drupal.org patch), then why should it show up in the long-term history of the project as a branch and a merge?
I'll write again about merging and rebasing workflows, but for now we're just going to deal with #1: The case where you share a branch with others and you want to pull in their work without generating unintentional merge commits.
How to use git pull --rebase
The first and most important thing if you're a committer working on a branch shared with other committers is to never use the default git pull
. Use the rebase version, git pull --rebase
. That takes your commits that are not on the remote version of your branch and reworks/rebases them so that they're ahead of (on top of) the new commits you pull in with your pull.
Automatically using git pull --rebase
It's very easy to set up so that you don't ever accidentally use the merge-based pull. To configure a single branch this way:
git config branch.7.x.rebase true
To set it up so every branch you ever create on any repository is set to pull with rebase:
git config --global branch.autosetuprebase always
That should do the trick. Using this technique, no matter whether you use techniques to keep your history linear or not, whether you use topic branches or not, whether you squash or not, you won't end up with git disasters.
Bottom line: No matter what you do, please use git pull --rebase. To do that automatically forever without thinking,
git config --global branch.autosetuprebase always