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 git 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?
I don't recommend rebasing at all but just for private branches. By private I mean branches that you're pretty sure only you have pulled.
A rebase changes the starting point of the branch to some newer commit, thus merging all the commits to that point. This could lead to merge conflicts to people that had in their repository the old branch base. I would recommend plain merge always and leave rebasing only for certain situations (feature branches, for example).
Regarding your question:
- git rebase rebases the branch you want.
- git pull --rebase performs a fetch + rebase in the branches you pull. Normally a pull would fetch + merge.
Best Answer
It is only an issue if you have only published (pushed) some of your commits, because they would be harder to merge to other repos which have already those commits. Since their SHA1 have changed, Git would try to replay them again on those repos.
If you have not (pushed any of those commits again), any rebase should be safe.
So the issue here is: are you sure that all the local commit you are rebasing are still actually... local?
And are you sure of that '
git pull --rebase
' after 'git pull --rebase
'?If you are working on a 'private branch' (a branch that you never pushed, but only merge or rebase on a public branch, one that you will push), then you are safe to rebase that private branch any time you want.
In the end, it all depends on the workflow of merge you have chosen to establish.