Question

The git documentation mentions in several places not to rebase if the code has been pushed to a public repository. However, I have seen this rebase strategy suggested in multiple places while Googling my Git problems.

The situation stated is to use git pull with the --rebase option when working with other devs in order to reduce the amount of merge commits which "pollute the logs". This can even be made automatic by setting the branch.master.rebase option to true.

Why is this strategy considered safe, seeing how the fine documentation specifically warns against rebasing when working with other devs?

Was it helpful?

Solution

I believe you're misinterpreting the warning.

Say there's a local commit A that hasn't been pushed, and a commit B that hasn't been pulled. By running git pull --rebase, you're gonna destroy commit A, pull commit B, and re-create commit A on top of B.

Since commit A is local, this is fine and safe, and it's what the rebase strategy suggests. But, the documentation tells you not to do this if commit A had already been pushed (to a different branch, for example). In that case, you'd be destroying a publicly available commit, and re-writing public history.

OTHER TIPS

When you do a git pull --rebase you don't push anything anywhere. So it's safe.

With a normal git pull, the following happens:

A-B-C(master)
   \
    D(origin/master)

becomes

A-B-C-E(master)
   \ /
    D(origin/master)

Which is "polluted" with a merge commit.

If you use git pull --rebase instead:

A-B-C(master)
   \
    D(origin/master)

becomes

A-B-D(origin/master)
     \
      E(master)

No merge, more linear history. Still no push, no danger. You've only rewritten the history of your local master branch.

The very reason that master and origin/master have diverged, is that you have not pushed your master yet. That's why there is no contradiction with all the warnings about using rebase.

Why People Don't Like to Rebase Public Commits

People usually don't want to rebase commits that are shared with other people because it makes it harder for them to sync their old commits with the rewritten commits that result from the rebase.

Note that this does not mean that it's impossible for team members to sync their work with publicly pushed code that has been rebased. It's just harder to coordinate, especially for large teams. If you have to sync your work that's based off of old public commits with the same rebased commits, then you can use the git rebase --onto flag to do it. The official Linux Kernel git documentation for rebase even states so.

So basically, if you don't trust other people to be able to or know how to sync their work with rebased public commits, or you don't want to create extra work for other developers, don't push rebased commits that have already been publicly pushed.

Why It's OK to Rebase Local Unshared Commits

Notice, however, that I said already publicly pushed. If no one else has a copy of the commits that you're going to rebase, then there's nothing to worry about. That's why it's okay to use git pull --rebase on your own local commits...as long as you've never shared those local commits with anyone else yet.

When you do a pull --rebase, you rebase your commits on top of whats on the remote.

What you indeed shouldn't do is rebase your own commits (interactive), for commits which you've already pushed to the master.

If you do an interactive rebase, e.g. you squash your own commits, for commits already pushed to the master, you are actually "destroying" the history of your git repository. Most git servers will not allow you to push those commits to the remote anyway.

So be aware that the one they are warning you for is something totally different than doing a pull --rebase

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top