threads / patch / 6921

patchgit-diff: fix combined diff

Subject: [PATCH] git-diff: fix combined diff

## tl;dr

5 messages between Feb 23, 2007 and Feb 23, 2007. Diffs are folded; open one to read it.

replies: 4people: 3as markdown or json

Johannes Schindelin· Feb 23, 2007, 04:20 UTC · lore

With "const unsigned (*parent)[20]", "parent + 1" is not the same as "&parent[1]"...

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
	I triggered this bug by "git diff a...b", where a and b
	have 4 merge bases. I am really too tired to add a test
	case, though...
 builtin-diff.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
Show changes to builtin-diff.c +2 −1
diff --git a/builtin-diff.c b/builtin-diff.c
index 9334589..846cafb 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -158,7 +158,8 @@ static int builtin_diff_combined(struct rev_info *revs,
 	parent = xmalloc(ents * sizeof(*parent));
 	/* Again, the revs are all reverse */
 	for (i = 0; i < ents; i++)
-		hashcpy((unsigned char*)parent + i, ent[ents - 1 - i].item->sha1);
+		hashcpy((unsigned char*)&parent[i],
+				ent[ents - 1 - i].item->sha1);
 	diff_tree_combined(parent[0], parent + 1, ents - 1,
 			   revs->dense_combined_merges, revs);
 	return 0;
-- 
1.5.0.1.2218.g2de79
Junio C Hamano· Feb 23, 2007, 06:09 UTC · re: Junio C Hamano · lore

Re: [PATCH] git-diff: fix combined diff

Junio C Hamano <junkio@cox.net> writes:
Show 5 quoted lines
> With this,
>
> 	$ git diff maint master next pu
>
> starts working as planned ;-).

By the way, your commit log message does not seem to say why it is a fix correctly. Here is what I replaced it with.

-- >8 -- cut here -- >8 --
From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Date: Fri, 23 Feb 2007 05:20:32 +0100
Subject: [PATCH] git-diff: fix combined diff

The code forgets that typecast binds tighter than addition, in other words:

    (cast *)array + i  === ((cast *)array) + i
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 builtin-diff.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
Show changes to builtin-diff.c +2 −1
diff --git a/builtin-diff.c b/builtin-diff.c
index a659020..c387ebb 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -192,7 +192,8 @@ static int builtin_diff_combined(struct rev_info *revs,
 	parent = xmalloc(ents * sizeof(*parent));
 	/* Again, the revs are all reverse */
 	for (i = 0; i < ents; i++)
-		hashcpy((unsigned char*)parent + i, ent[ents - 1 - i].item->sha1);
+		hashcpy((unsigned char *)(parent + i),
+			ent[ents - 1 - i].item->sha1);
 	diff_tree_combined(parent[0], parent + 1, ents - 1,
 			   revs->dense_combined_merges, revs);
 	return 0;
-- 
1.5.0.1.619.g04c5c
Jeff King· Feb 23, 2007, 05:34 UTC · re: Johannes Schindelin · lore

Re: [PATCH] git-diff: fix combined diff

On Fri, Feb 23, 2007 at 05:20:32AM +0100, Johannes Schindelin wrote:
> With "const unsigned (*parent)[20]", "parent + 1" is not the
> same as "&parent[1]"...

Actually, they _are_ the same (the C standard definition of A[B] is *(A+B)). The problem is the operator precedence of the cast:

> -		hashcpy((unsigned char*)parent + i, ent[ents - 1 - i].item->sha1);

which translates to "cast parent to an unsigned char pointer, and then add i * sizeof(unsigned char) to it".

Your fix works because [] binds more tightly, fixing the precedence
problem. You could also do this:
  hashcpy((unsigned char*)(parent + i), ...
-Peff
Johannes Schindelin· Feb 23, 2007, 11:19 UTC · re: Jeff King · lore

Re: [PATCH] git-diff: fix combined diff

Hi,
On Fri, 23 Feb 2007, Jeff King wrote:
Show 6 quoted lines
> On Fri, Feb 23, 2007 at 05:20:32AM +0100, Johannes Schindelin wrote:
> 
> > With "const unsigned (*parent)[20]", "parent + 1" is not the
> > same as "&parent[1]"...
> 
> Actually, they _are_ the same (the C standard definition of A[B] is *(A+B)).
Modulo binding precedence.

Thanks for clearing this up, Dscho

← back to recent threads