Re: is rebase the same as merging every commit?
This example you provided Matthieu is exactly my confusion with rebase..
If I want to bring a 'broken feature-a' branch into my topic branch to build on it, one commit of which is this:
> + int * x = malloc(sizeof(char));
if I merge, my tree looks like:
: /<--G<--H<--Qj jeske/topic1 : / / : /<--P<------Q feature-a : / : -----A<---B<---C master
or if I rebase, it looks like:
: /<--G'<--H' jeske/topic1 : / : /<--P<---Q feature-a : / : -----A<---B<---C master
-----
..and then through 'fixing' the patch, it ends up rebased and accepted onto the mainline origin/master, as a single patch, which (among other things) changed this line to:
> + int * x = malloc(sizeof(int));
...if I merged above, it will look like,
: /<--G<--H<--Qj jeske/topic1 : / / : /<--P<------Q feature-a : / : -----A<---B<---C<---Q' master
...if I rebased above, it will look like:
: /<--G'<--H' jeske/topic1 : / : /<--P<---Q feature-a : / : -----A<---B<---C<---Q' master
However, in both cases, because Q' is not connected to Q, I don't see how git will do anything sane to help me accept Q' correctly.
If I rebased my merge-q-branch against the master, I would expect to get this (which will cause a conflict I have to resolve):
: /<--G<--H<--Qj jeske/topic1 : / : <--C<---Q' master
If I rebased my rebase-q-branch against master, I would expect to get this (which will cause a conflict I have to resolve):
: /<--G'<--H' jeske/topic1 : / : /<--P<---Q feature-a : / : --C<---Q' master
However, if that Q' rebase contained a link back to (P,Q), it would know that the Q' rebase was replacing (P,Q), and would know to back them out of my tree when I rebased back onto the head, producing this in BOTH cases above (whether I rebased or merged from the feature-a branch):
: /<--G'<--H' jeske/topic1 : / : --C<---Q' master
This operation above of "working will pulling uncompleted patches into my tree" seems like a fairly common thing for developers. I've never provided any patches to linux-kernel, but when I did try hacking on it years ago, I was doing exactly this. (pulling unaccepted patches into my kernel, then building on those patches). When I read about the DAG and its universal naming, I always assumed that the above workflow was what it was DESIGNED to make automatic. I'm confused, how does this work in git?
-- Matthieu Moy wrote:
Show 21 quoted lines
> Well, look at the [PATCH] messages on this list, and how they evolve.
> Patch series give a clean way to go from a point to another. That's
> what you want to see in upstream history.
>
> Then, patch series usually get reviewed, and the patches themselves
> are modified. There's a kind of meta-history: the changes you make to
> your own changes.
>
> Suppose I send a patch containing
>
> + int * x = malloc(sizeof(char));
>
> and someone notices how wrong it is. I send another patch with
>
> + int * x = malloc(sizeof(int));
>
> The first version was basicaly a mistake, and if it hasn't been
> released, no one want to bother with it longer that the time to resend
> the patch. No one want to be hit by the bug while using bisect later
> on the upstream repository. And no one wants to see both patches when
> reviewing or "git blame"-ing.