Re: [PATCH 2/2] Teach the --no-ff option to 'rebase -i'.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Marc Branchaud <marcnarc@xxxxxxxxxxx> writes:

> This option tells git-rebase--interactive to cherry-pick all the commits in
> the rebased branch, instead of fast-forwarding over any unchanged commits.

Thanks.

> +Sometimes you're in a situation like this
> +
> + P---o---o---M---x---x---W---x
> +  \         /
> +   A---B---C
> +
> +where W is the reversion of merge M and you:
> +
> + - Need to rewrite one of the commits on the A-B-C branch; and
> +
> + - Want the rewritten A-B-C branch to still start at commit P (perhaps P
> +   is a branching-off point for yet another branch, and you want be able to
> +   merge A-B-C into both branches).
> +
> +The natural thing to do in this case is to checkout the A-B-C branch and use
> +"rebase -i A" to change commit B.  However, this does not rewrite commit A,
> +and you end up with this:
> +
> + P---o---o---M---x---x---W---x
> +  \         /
> +   A---B---C   <-- old branch
> +   \
> +    B'---C'    <-- rewritten branch
> +
> +To merge A-B'-C' into the mainline branch you would still have to first revert
> +commit W in order to pick up the changes in A, but then it's likely that the
> +changes in B' will conflict with the original B changes re-introduced by the
> +reversion of W.

I find it somewhat a contrived and unconvincing explanation.  A moderately
intelligent reader would wonder "Why did you choose to 'rebase -i A' in
the first place?  if you did 'rebase -i P' instead, you didn't have to
suffer from this issue, no?", and you are not answering that question.

Two things that you are assuming but not telling the user to make this
explanation appear unsatisfactory are:

 - The true reason you reverted M turns out to be that B was bad, and A
   was fine, so you want to fix B in A-B-C and merge it to master; and

 - Because "rebase -i" by default fast-forwards earlier "pick", even
   "rebase -i P" wouldn't have given you a rewritten A.

If you spell these out, then the explanation starts to make sense.

> +However, you can avoid these problems if you recreate the entire branch,
> +including commit A:
> +
> + P---o---o---M---x---x---W---x
> + |\         /
> + | A---B---C   <-- old branch
> + \
> +  A'---B'---C' <-- entirely recreated branch

This is just an advice on drawing, but you can avoid this ugly picture by
starting your discussion with:

      A---B---C
     /         \
    P---o---o---M---x---x---W---x

and adding the reproduction like this:

      A---B---C
     /         \
    P---o---o---M---x---x---W---x
     \
      A'--B'--C'

> +But if you don't actually need to change commit A, then you need some way to
> +recreate it as a new commit with the same changes in it.  The rebase commmand's
> +two modes (interactive and non-interactive) provide options to do this.  With
> +"rebase -i" use the --no-ff option:
> +
> +    $ git rebase -i --no-ff P
> +
> +With plain "rebase" use the -f option:
> +
> +    $ git rebase -f P

This is exactly why I don't mind giving a --no-ff synonym for --force to
non-interactive rebase.  That would make the choice between -i and no -i
made by the reader solely depend on the need to change anything in the
commits.  If you are fixing B in A-B-C, you would use "rebase -i".  If
instead you queued a fix-up as D, like so:

      A---B---C-------------------D
     /         \
    P---o---o---M---x---x---W---x

then you can rebase non-interactively the whole thing in preparation for
another merge:

      A---B---C---D
     /         \
    P---o---o---M---x---x---W---x...*
     \                             /
      A'--B'--C'------------------D'
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]