Git merge vs. rebase

The short:

The long:

If you enjoy this post, check out my git tips you didn’t know about!

Avoid merge commits that result from git pull

When you want to push your changes to a branch, but someone else already pushed before you, you have to pull in their changes first. Normally, git does a merge commit in that situation.

Such merge commits can be numerous, especially between a team of people who push their changes often. Those merges convey no useful information to others, and litter the project’s history.

You should always pull with git pull --rebase. Git can be configured to make it the default behavior:

git config --global --bool pull.rebase true

Interactively rebase local commits before pushing

Run this every time before pushing a set of commits:

git rebase -i @{u}

The “u” stands for “upstream” (added in git v1.7.0), and it resolves to the latest commit on this branch on the remote. Putting it simply, this command rewrites only the local commits which you’re about the push. Starting in git v1.7.6, @{upstream} is the default for when there is no argument.

This gives you a chance to perform basic housekeeping before sharing your changes, such as squashing related commits together and rewording commit messages if they’re too long or not descriptive enough.

Suppose you have a set of 4 commits (newest first):

[D] oops! fixed typo in feature A
[C] bugfix for change B
[B] another change
[A] yay new feature!

You definitely want to squash A+D and B+C together, while still keeping A and B separate. The philosophy behind this is: don’t make bugs or typos a part of your project’s history if you haven’t shared them yet.

Integrate changes from master into a feature branch with merge

If you’re working on a long-lived feature branch, it pays off to sometimes merge in the master branch (assuming “master” is the main development branch) to verify that they are compatible and to get the latest bug fixes.

You could also rebase the current branch on top of master, but the rebase has shortcomings:

Record a merge commit when a feature lands into master

After working on a feature/topic branch, merge it in master like so:

git merge --no-ff feature

The --no-ff flag ensures there will always be a merge commit, even when technically not necessary. Merge commits are useful because they convey the following information:

Sometimes a topic branch will consist only of a single commit, especially for bug fixes. When merging it in, I often decide not to record the merge commit for a single commit because that merge information is less useful to the team:

You can pull in a single commit to master like so:

git cherry-pick feature