It’s strangely hard to find documentation on the git workflow to follow to keep a clean commit history when you want to merge external contributions.

First enable rebasing by default

As it’s written on, many users find that they happen to do “git pull —rebase” most of the time. Would be nice if “git pull” simply did that by default. You can set that up for the master branch of all your repositories by:

git config —global branch.master.rebase true

An upstream project

For our example, we’ve an upstream project with only one commit called C1 mkdir upstream cd upstream git init touch hello.c git add hello.c git commit -m “C1"

Your fork

As contributor, you can fork as usual and commits your changes on a specific branch (newfeature).

git clone upstream fork cd fork git checkout -b newfeature edit hello.c git commit -a -m “C2"
When you’re ready to ask for a pull request, sync with upstream project with a final “git pull” to help the maintainer to merge your patches (it’s not mandatory).

Back to upstream

In the meantime, it’s possible some new commits have landed in upstream. As maintainer, you receive an email: “Could you merge my branch, please?”, so you add the repository to your remote list to fetch the content:

git remote add fork ../fork/ git fetch fork

and create a branch to rebase the contributor work in a separated branch:

git checkout -b fork fork/newfeature git rebase master (and resolve if necessary)

You can now apply the fast-forward merge on your master branch:

git checkout master
git merge fork
You’re done with a nice commit history w/o ghost commits.

On the contributor side

Just delete your branch because after a rebase in upstream, your branch is certainly broken so it’s time to cleanup: git branch -D newfeature

Thanks to Staz and Dodji on #gnomefr chan.

Originally published at on June 24, 2010.

I like clean and open code (Django, JS, Rust, libmodbus).

I like clean and open code (Django, JS, Rust, libmodbus).