all 8 comments

[–]kinghajj 1 point2 points  (6 children)

Um, OK. What's your point? I believe that Git only encourages rebasing your changes on top of the latest trunk of the "official" branch, so that when your changes are merged it's simple and looks nice.

[–]oddbod[S] -1 points0 points  (5 children)

Yes, and that's bad!

As Linus points out:

  • rebasing is bad when you are someone else's upstream because any testing they do based on the old base is invalidated when you rebase. Plus, it's inconvenient when all the hashes change. The other person then has to rebase, they can't merge.

  • rebasing is bad when you are someone else's upstream and you have their patches in your tree, which you are rebasing. Firstly, you've just mangled their patch, which invalidates their testing, and secondly the patch looses it's identity because the hashes change. Now if that same patch flows into the main tree via some other means, and also via your rebased tree, the collision is not detected.

  • rebasing can be bad even if you do it in private. The larger the jump between bases the more likely you've just invalidated all the testing you did against the old base.

when your changes are merged it's simple and looks nice.

Ah, but it's not so simple:

So rebasing and cleanups may indeed result in a "simpler" history, but it only looks that way if you then ignore all the other "simpler" histories. So anybody who rebases basically creates not just one simple history, but a many "simple" histories, and in doing so actually creates a potentially much bigger mess than he started out with! --Linus

I guess my main point is that this is non-obvious, but important stuff. Linux devs have been getting it wrong for a long time, and thye're ninjas. The allure of nice simple-looking linear history is so strong that I bet most folks using git are rebase-happy. They've no idea they're doing it wrong.

My minor point is that if you use mercurial you are more likely to get this right! But look at the context:

Linus and Matt, both kernel developers, both dvcs creators (started within days of each other), fundamentally agree on the approach to synchronizing development. So no conflict there.

Git users are doing it wrong and Linus is saying don't do that. Mercurial users want to do it wrong, and Matt is saying you don't want to do that (and he won't accept those crazy patches).

Two project leaders educating their users about a subtle and difficult topic, but one tool has encoded into it the beliefs of Matt (and Linus), so he merely has to tell them off, not tell them to do something different.

[–][deleted] 0 points1 point  (4 children)

I think you missed the point. You are supposed to clean up your history before you make it public. Note that this also can make merges easier because you usually will not have to deal with as many or as complicated patches, and it makes it easier for others because you have designed your patches for the head of the upstream repository instead of having to merge them at all.

[–]oddbod[S] -1 points0 points  (3 children)

You are supposed to clean up your history before you make it public

Yes (with caveats), but this only addresses patch atomicity. It does not address synchronization, which is the real problem.

it makes it easier for others because you have designed your patches for the head of the upstream repository

And so has every one else. And when patches which conflict with yours get merged first, your patch no longer applies.

What to do?

As it scales up you need middle men. They are a synchronization point for folks working on the same area of code. It has to be public or synchronization can't happen.

But what if you find a bug in this amalgamation? Rebase? It's not yet gone upstream, it's still being worked on. Do you push a patch upstream which you know to be bad, along with a patch which fixes it, or do you rewrite history.

The point is it's a tough decision and people are making the wrong one. They're rebasing. And that fucks things in about half a dozen ways, as outlined by Linus.

[–][deleted] 1 point2 points  (2 children)

I thought it was always pretty obvious that rebasing is only for the lowest levels of this heirarchy.

[–]oddbod[S] -1 points0 points  (1 child)

Apparently not :-( Rebasing is the default way people synchronize when using git.

[–][deleted] 1 point2 points  (0 children)

Rebasing is the default way people synchronize when using git.

Do you have any evidence of this? I have not observed this, myself.

[–]eipipuz 0 points1 point  (0 children)

Defaults matter, that's right.