Re: How to switch kernel customizations from 2.6.15.6 to 2.6.16?
From: Linus Torvalds <torvalds@osdl.org>
Date: 2016-06-15 22:42:22
On Tue, 28 Mar 2006, Junio C Hamano wrote:
Having said that, you have been able to say format-patch A..B C..D E..F for quite some time (since November 21, 2005).
Yes, and the documentation still talks only about the old insane format..
Rebase is even more strange, especially with --onto. When you do
$ rebase --onto his origin mine
in this picture,
*---x---x---o---o---o---o
\ ^origin ^mine
.---.---.---.
^his
you are discarding two 'x' commits, and lost-found is the only
thing that would help you to recover them.
.. and this is largely because the whole interface is broken.
The breakage shows up as inflexibility and having a hard time explaining
what the thing does. It shows up as confusion about the usage, and about
the meaning of a simple command line.
For example, in the most trivial format, doing a
git rebase <branchname>
the _logical_ thing (from just reading the command) to believe the above
does is to think that it rebases the named branch. I pretty much guarantee
that that is what any native English speaker would think it does, if they
thought about it.
The fact that it actually does the _reverse_, and rebases not the named
branch, but the branch you are on right now.
The fact that when things go south, the old branch has gotten lost (unless
you remember about ORIG_HEAD) is all related to the same thing. It's just
a very non-intuitive interface.
That was fine when people weren't supposed to use it, and it was doing
something very very special, but that has clearly changed over time. Now
people are encouraged to use it, it's pretty well-known, and even new git
users seem to want to do it.
I think "git rebase" is a lost cause. It's just fundamentally a very very
badly designed command, because it does everything the wrong way around.
I personally believe that the _sane_ way of doing rebasing is to
- get rid of "git rebase" entirely
- teach "git cherry-pick" to take a _range_ of commits instead.
Lookie here, let's look at your example a bit more (which in turn comes
from the original question that started this thread):
*---x---x---o---o---o---o
\ ^origin ^mine
.---.---.---.
^his
We have three branch points, and we want to move the commits on "mine"
from "origin" onto "his". How would you do this so that it's _not_
confusing, and so that you can explain to a newbie user what he is doing,
_especially_ if things go wrong in the middle?
Right now, the sequence is:
git checkout mine # if required
git rebase --onto his origin
and if things go south during the rebase, it's immediately total chaos,
and you really _really_ need to understand what you are doing.
The above just doesn't make any sense. It's hard to explain why you would
do something like that.
In contrast, here's an alternate workflow that is much easier to explain,
and doesn't involve "rebase" at all:
git checkout his
git cherry-pick origin..mine
Notice what this does? Show these two sequences to anybody who has some
basic familiarity with git terminology, but has perhaps never actually
used it, and ask them what the two sequences do. I pretty much guarantee
that the second sequence will make sense and get people to generally pick
the right answer, while the first sequence will make people maybe _guess_
the right answer, but it's not intuitive.
In particular, what do you think happens when a patch in the series
doesn't apply under the two circumstances? Which workflow has the
"intuitive" way of recovering, and which does not?
Right. The second one has a very intuitive way to recover. In fact, it's
so intuitive that the answer may be "ok, I'll skip that one commit
entirely because I don't know how to resolve it, and instead cherry-pick
the rest, and ask the original author to cherry-pick it for me later". And
doing so is as easy as
git reset --hard # undo the mess from the failed one,
# the same way we always do for all
# other failed things
git cherry-pick next..mine # do the rest
See? That's a very logical thing to do. It's different from "git rebase",
but it's different in a _good_ way.
In contrast, the "rebase" conflict resolution is pretty damn esoteric, and
using a simple "gitk --all" when things go wrong won't help you pick
things up at all.
Now, "git cherry-pick" doesn't actually support the above format, and I'm
not saying that the "git rebase" name itself is evil. I think we could fix
"git rebase" to work better, but the semantics - the way they are
_designed_ right now - are just horrible.
Linus