Re: Heads up: rebase -i -p will be made sane again

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

 



Hi,

On Tue, 27 Jan 2009, Stephen Haberman wrote:
> 
> Dscho wroteÖ
> 
> > As for the design bug I want to fix: imagine this history:
> > 
> >   ------A
> >  /     /
> > /     /
> > ---- B
> > \     \
> >  \     \
> >   C-----D-----E = HEAD
> > 
> > A, C and D touch the same file, and A and D agree on the contents.
> > 
> > Now, rebase -p A does the following at the moment:
> > 
> >   ------A-----E' = HEAD
> >  /     /
> > /     /
> > ---- B
> > 
> > In other words, C is truly forgotten, and it is pretended that D never 
> > happened, either.  That is exactly what test case 2 in t3410 tests for 
> > [*1*].
> > 
> > This is insane.
> 
> Agreed.

Actually, I misread t3410 a great deal.  The situation is as follows:

    ... UPSTREAM
           \
... A - B - C -D

A is a patch the upstream does not have, B is a patch UPSTREAM has,
and "git diff C^!" (i.e. the diff of C to its first parent) is _also_ 
identical to a diff of a merge that is in UPSTREAM.

Basically, t3410 tests that after "git rebase -i -p UPSTREAM" and leaving 
the rebase script as-is, essentially, A and D are cherry-picked on top of 
UPSTREAM.

> Does this mean you're just getting rid of the code that calls "rev list 
> --cherry-pick"?

Only now do I understand.

I misread the code for --cherry-pick.  For merges, it adds the diff to the 
first parent!

I do not know if it really is desirable to have --cherry-pick handle 
merges at all; I tend to think it is not.

Unfortunately, a short blame session just points to 9c6efa36 done by a 
sloppy programmer: yours truly.

So I adapted my code to find the "dropped" merges in 
git-rebase--interactive, too, for now, but I guess the proper fix is 
something like this:

-- snipsnap --
[PATCH] --cherry-pick: do not skip merges, ever

Currently, --cherry-pick has no problem getting a patch id for merge 
commits: it calculated as the patch id of the patch between the first 
parent and the merge commit.

Of course, this is bogus, as it completely misses the fact that the
merge commit has other parents, too, and therefore a single patch id
would be wrong.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx>
---
 patch-ids.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/patch-ids.c b/patch-ids.c
index 3be5d31..808a7f0 100644
--- a/patch-ids.c
+++ b/patch-ids.c
@@ -6,9 +6,12 @@
 static int commit_patch_id(struct commit *commit, struct diff_options *options,
 		    unsigned char *sha1)
 {
-	if (commit->parents)
+	if (commit->parents) {
+		if (commit->parents->next)
+			return 0; /* merges do not have a patch id */
 		diff_tree_sha1(commit->parents->item->object.sha1,
 		               commit->object.sha1, "", options);
+	}
 	else
 		diff_root_tree_sha1(commit->object.sha1, "", options);
 	diffcore_std(options);

[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]

  Powered by Linux