When should I use git pull --rebase?
I would like to provide a different perspective on what "git pull --rebase" actually means, because it seems to get lost sometimes.
If you've ever used Subversion (or CVS), you may be used to the behavior of "svn update". If you have changes to commit and the commit fails because changes have been made upstream, you "svn update". Subversion proceeds by merging upstream changes with yours, potentially resulting in conflicts.
What Subversion just did, was essentially "pull --rebase". The act of re-formulating your local changes to be relative to the newer version is the "rebasing" part of it. If you had done "svn diff" prior to the failed commit attempt, and compare the resulting diff with the output of "svn diff" afterwards, the difference between the two diffs is what the rebasing operation did.
The major difference between Git and Subversion in this case is that in Subversion, "your" changes only exist as non-committed changes in your working copy, while in Git you have actual commits locally. In other words, in Git you have forked the history; your history and the upstream history has diverged, but you have a common ancestor.
In my opinion, in the normal case of having your local branch simply reflecting the upstream branch and doing continuous development on it, the right thing to do is always "--rebase", because that is what you are semantically actually doing. You and others are hacking away at the intended linear history of a branch. The fact that someone else happened to push slightly prior to your attempted push is irrelevant, and it seems counter-productive for each such accident of timing to result in merges in the history.
If you actually feel the need for something to be a branch for whatever reason, that is a different concern in my opinion. But unless you have a specific and active desire to represent your changes in the form of a merge, the default behavior should, in my opinion, be "git pull --rebase".
Please consider other people that need to observe and understand the history of your project. Do you want the history littered with hundreds of merges all over the place, or do you want only the select few merges that represent real merges of intentional divergent development efforts?
You should use git pull --rebase
when
- your changes do not deserve a separate branch
Indeed -- why not then? It's more clear, and doesn't impose a logical grouping on your commits.
Ok, I suppose it needs some clarification. In Git, as you probably know, you're encouraged to branch and merge. Your local branch, into which you pull changes, and remote branch are, actually, different branches, and git pull
is about merging them. It's reasonable, since you push not very often and usually accumulate a number of changes before they constitute a completed feature.
However, sometimes--by whatever reason--you think that it would actually be better if these two--remote and local--were one branch. Like in SVN. It is here where git pull --rebase
comes into play. You no longer merge--you actually commit on top of the remote branch. That's what it actually is about.
Whether it's dangerous or not is the question of whether you are treating local and remote branch as one inseparable thing. Sometimes it's reasonable (when your changes are small, or if you're at the beginning of a robust development, when important changes are brought in by small commits). Sometimes it's not (when you'd normally create another branch, but you were too lazy to do that). But that's a different question.