git rebase vs git merge

I am working now with git for about 1 year. The question when to use a git rebase and when to use a git merge always lead to confusion for me. To clarify this I want to show you what a git rebase really is, what advantages we can leverage from it and how to use it safely.

Lets start with the most basic question, what is a git rebase? When we consolidate the man page of it, we get the description:

git-rebase – Forward-port local commits to the updated upstream head

 

So what does that mean? Lets look at it in a real example. Consider we have a repository with a master branch. In that master branch we made 2 commits.

We are creating now a new feature branch from that master and make a new commit on it.

While we are developing in our feature branch, someone else made updates on the master branch.

When we now want to merge the latest commits of the master into our feature branch we can make a git rebase.

So what happened by now? The git command line tool tells us: First, rewinding head to replay your work on top of it… So git first throws away all our local changes of the branch feature-xy. It now applies all commits from the master so that the master branch and our feature-xy branch look the same. Than it takes our local commits on the feature-xy branch and applies them on the top.

Maybe we can understand the definition of the man page now better. In our case it updates first our local branch to the master branch .. to the updated upstream head and than it applies our local commits on top of it Forward-port local commits ..

Caution: When you look close at the commit „developed feature-xy“ you will recognize that the commit hash has changed. This is because it now has a different parent commit and the parent commit influences the commit hashes.

Important: This brings us to the conclusion that we dont want to use git rebase when we already have pushed our changes to the remote. Otherwise git would not recognize that the changes in the commits are the same, as it tracks the differences just by the commit hashes, and would try to merge it what would lead to merge conflicts.

Remember: To update your local branch use git rebase, for everything else use git merge.

Okay, but where is now the benefit to use git rebase instead of git merge for local branches? The benefit is to avoid merge-commits and therefor keep a clean history. Lets have a look at an example where we can see the problems of a git merge. Here is the state of our local copy on the master branch.

We are making now some new changes on the master branch.

While we made our local changes someone else has pushed a new commit to the remote master. Thus, when we want to push our changes it is rejected as we have to merge the changes on the remote repository first.

To see better what happens, I will now do manually what a git pull normally combines. First I will fetch the latest version of the repository from the remote and than do a git merge with the latest master version of the remote.

So now we have merged our local master version with the latest version from the remote repository. When we now look at the history, we see a merge commit and even a split in the graph of our history, though we have worked on the master branch all the time.

If we would have updated our local master version with git rebase, the history would be linear and we would have saved us that merged commit. I hope the advantages of git rebase are now clear. We can maintain a clean history without cluttering it through unnecessary merge conflicts and branches in the graph.

Note on git pull: A git pull always first fetches the latest version of the remote repository and then makes a git merge on it. If we want git pull to make a rebase instead of that merge with can append the –rebase flag.

I would recommend to set up git to do that by default.

If you skip the –global option this option is just setup for your current local branch.

Remember

To update your local branch, use git rebase, for everything else, use git merge.

Links / Sources

http://git-scm.com/book/en/Git-Branching
http://git-scm.com/book/en/Git-Branching-Rebasing
Book: Daily Git – Author: Martin Dilger

Follow-Up

In this article I have not mentioned how to use git rebase –interactive to cleanup your local history and edit / squash / ammend commits. This will be the content for another article so stay tuned :)

Für neue Blogupdates anmelden:


5 Gedanken zu “git rebase vs git merge

  1. The configuration command needs to be git config --global branch.autosetuprebase always instead of git config branch.autosetuprebase always --global.

    Otherwise, good summary.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.