{"thread":{"id":"5111","subject":"git-annotate bug report","startedAt":"2006-08-03T20:38:48Z","lastAt":"2006-08-08T08:49:42Z","messageCount":11,"participants":["Jeff King","Ryan Anderson","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"24668","messageId":"20060803203848.GA15121@coredump.intra.peff.net","threadId":"5111","inReplyTo":null,"subject":"git-annotate bug report","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2006-08-03T20:38:48Z","receivedAt":"2006-08-03T20:38:48Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"git-annotate on the tip of master seems to be broken for some files (but\nnot for others):\n\n$ git-describe\nv1.4.2-rc2-gfba0cbd\n$ make && ./git-annotate builtin-read-tree.c\nparent eff97e3faeb28f6521851c1b3be1a54a2138f12a is on line 852\nLine 852, does not match:\n||\n|                       cnt++;|\n021b6e454944a4fba878651ebf9bfe0a3f6c3077\n\n-Peff\n"},{"id":"24670","messageId":"20060803211024.GA29529@h4x0r5.com","threadId":"5111","inReplyTo":"20060803203848.GA15121@coredump.intra.peff.net","subject":"Re: git-annotate bug report","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2006-08-03T21:10:25Z","receivedAt":"2006-08-03T21:10:25Z","isPatch":false,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Thu, Aug 03, 2006 at 04:38:48PM -0400, Jeff King wrote:\n> git-annotate on the tip of master seems to be broken for some files (but\n> not for others):\n> \n> $ git-describe\n> v1.4.2-rc2-gfba0cbd\n> $ make && ./git-annotate builtin-read-tree.c\n> parent eff97e3faeb28f6521851c1b3be1a54a2138f12a is on line 852\n> Line 852, does not match:\n> ||\n> |                       cnt++;|\n> 021b6e454944a4fba878651ebf9bfe0a3f6c3077\n\n\nSweet, that might be exactly the test case I need to figure out where it\nloses track of some lines during merges.\n\nI'll see about looking at this over the weekend.\n\n-- \n\nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"24916","messageId":"20060807115000.GC15477@h4x0r5.com","threadId":"5111","inReplyTo":"20060803203848.GA15121@coredump.intra.peff.net","subject":"Re: git-annotate bug report","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2006-08-07T11:50:01Z","receivedAt":"2006-08-07T11:50:01Z","isPatch":false,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Thu, Aug 03, 2006 at 04:38:48PM -0400, Jeff King wrote:\n> git-annotate on the tip of master seems to be broken for some files (but\n> not for others):\n\nWell, I think I've found a few bugs here tonight, basically all are\nrelated to handling merges correctly.\n\nFirst, a trivial one:\n\ngit diff-tree -M --name-status -z outputs the sha1 without honoring the\n-z.  Patch following this email.\n\nSecond, one I don't know how to fix, at the moment:\n\ngit annotate uses the automatic tree simplification that git rev-list\ndoes.  So, when it sees a commit with 1 parent, it assumes that it\nreally only has one parent.  git diff-tree -c doesn't know about this\nsame tree simplification, and, in the case of a merge commit, will still\noutput the -c format patch.\n\nThat particular case is trivial, simply remove the -c from commits where\nI *know* there is only parent, and ask for the exact diff I need, from\nthe parent to the current rev.\n\nThere is, unfortunately, another situation, that of an octopus merge.\nIn the case of read-tree.c (after the rename is followed), the commit\n7bd1527d2d8c80a6e9a0f8583082a5aee5428c68 is problematic.  In it we have\na 4-way merge, yet only 3 paths affected read-tree.c.  The diff-parsing\nin annotate constructs a regular expression to find the diff header and\nread out the line number to work on, and also to construct some regular\nexpressions from which to tell which lines affect which parents.\n\nFor example, it looks for a line like:\n+ ++Line added in 3 parents\nwith dynamically generated regular expressions.  These, of course, need\nto know how many parents there are.  The fact that diff-tree uses a\ndifferent number of parents makes the parsing fail, and then, the fact\nthat there isn't a great way to figure out which of the real parents\ncorresponds to the pseudo parents, makes this whole thing very\nmessy to fix.\n\nSo, the solution I've settled on is to use git merge-base to perform\nsome analysis and create a pseudo-parent list that is the same size as\nthe actual parent list, but consisting mostly of the fake parents\ngit-rev-list gives me.\n\nIf anyone else is confused by this email, it's probably because I\nstopped and fixed a bug in the middle of writing it.\n\nPatches as followups to this.\n\n\n-- \n\nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"24918","messageId":"1154952684908-git-send-email-ryan@michonline.com","threadId":"5111","inReplyTo":"20060807115000.GC15477@h4x0r5.com","subject":"[PATCH 1/2] log-tree: show_log() should respect the setting of diffopt->line_termination","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2006-08-07T12:11:23Z","receivedAt":"2006-08-07T12:11:23Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"Signed-off-by: Ryan Anderson <ryan@michonline.com>\n---\n log-tree.c |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/log-tree.c b/log-tree.c\nindex b67b8dd..05ede0c 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -59,7 +59,7 @@ void show_log(struct rev_info *opt, cons\n \t\tfputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout);\n \t\tif (opt->parents)\n \t\t\tshow_parents(commit, abbrev_commit);\n-\t\tputchar('\\n');\n+\t\tputchar(opt->diffopt.line_termination);\n \t\treturn;\n \t}\n \n-- \n1.4.2.rc3.g6487-dirty\n"},{"id":"24919","messageId":"11549526841904-git-send-email-ryan@michonline.com","threadId":"5111","inReplyTo":"1154952684908-git-send-email-ryan@michonline.com","subject":"[PATCH 2/2] annotate: Fix bug when parsing merges with differing real and logical parents.","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2006-08-07T12:11:24Z","receivedAt":"2006-08-07T12:11:24Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"Signed-off-by: Ryan Anderson <ryan@michonline.com>\n---\n git-annotate.perl |  128 +++++++++++++++++++++++++++++++++++++++++++++++++++--\n 1 files changed, 122 insertions(+), 6 deletions(-)\n\ndiff --git a/git-annotate.perl b/git-annotate.perl\nindex 505b5cc..215ed26 100755\n--- a/git-annotate.perl\n+++ b/git-annotate.perl\n@@ -147,7 +147,7 @@ sub init_claim {\n \n \n sub handle_rev {\n-\tmy $i = 0;\n+\tmy $revseen = 0;\n \tmy %seen;\n \twhile (my $rev = shift @revqueue) {\n \t\tnext if $seen{$rev}++;\n@@ -247,22 +247,129 @@ sub git_find_parent {\n \treturn $parent;\n }\n \n+sub git_find_all_parents {\n+\tmy ($rev) = @_;\n+\n+\tmy $revparent = open_pipe(\"git-rev-list\",\"--remove-empty\", \"--parents\",\"--max-count=1\",\"$rev\")\n+\t\tor die \"Failed to open git-rev-list to find a single parent: $!\";\n+\n+\tmy $parentline = <$revparent>;\n+\tchomp $parentline;\n+\tmy ($origrev, @parents) = split m/\\s+/, $parentline;\n+\n+\tclose($revparent);\n+\n+\treturn @parents;\n+}\n+\n+sub git_merge_base {\n+\tmy ($rev1, $rev2) = @_;\n+\n+\tmy $mb = open_pipe(\"git-merge-base\", $rev1, $rev2)\n+\t        or die \"Failed to open git-merge-base: $!\";\n+\n+\tmy $base = <$mb>;\n+\tchomp $base;\n+\n+\tclose($mb);\n+\n+\treturn $base;\n+}\n+\n+# Construct a set of pseudo parents that are in the same order,\n+# and the same quantity as the real parents,\n+# but whose SHA1s are as similar to the logical parents\n+# as possible.\n+sub get_pseudo_parents {\n+\tmy ($all, $fake) = @_;\n+\n+\tmy @all = @$all;\n+\tmy @fake = @$fake;\n+\n+\tmy @pseudo;\n+\n+\tmy %fake = map {$_ => 1} @fake;\n+\tmy %seenfake;\n+\n+\tmy $fakeidx = 0;\n+\tforeach my $p (@all) {\n+\t\tif (exists $fake{$p}) {\n+\t\t\tif ($fake[$fakeidx] ne $p) {\n+\t\t\t\tdie sprintf(\"parent mismatch: %s != %s\\nall:%s\\nfake:%s\\n\",\n+\t\t\t\t\t    $fake[$fakeidx], $p,\n+\t\t\t\t\t    join(\", \", @all),\n+\t\t\t\t\t    join(\", \", @fake),\n+\t\t\t\t\t   );\n+\t\t\t}\n+\n+\t\t\tpush @pseudo, $p;\n+\t\t\t$fakeidx++;\n+\t\t\t$seenfake{$p}++;\n+\n+\t\t} else {\n+\t\t\tmy $base = git_merge_base($fake[$fakeidx], $p);\n+\t\t\tif ($base ne $fake[$fakeidx]) {\n+\t\t\t\tdie sprintf(\"Result of merge-base doesn't match fake: %s,%s != %s\\n\",\n+\t\t\t\t       $fake[$fakeidx], $p, $base);\n+\t\t\t}\n+\n+\t\t\t# The details of how we parse the diffs\n+\t\t\t# mean that we cannot have a duplicate\n+\t\t\t# revision in the list, so if we've already\n+\t\t\t# seen the revision we would normally add, just use\n+\t\t\t# the actual revision.\n+\t\t\tif ($seenfake{$base}) {\n+\t\t\t\tpush @pseudo, $p;\n+\t\t\t} else {\n+\t\t\t\tpush @pseudo, $base;\n+\t\t\t\t$seenfake{$base}++;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn @pseudo;\n+}\n+\n \n # Get a diff between the current revision and a parent.\n # Record the commit information that results.\n sub git_diff_parse {\n \tmy ($parents, $rev, %revinfo) = @_;\n \n+\tmy @pseudo_parents;\n+\tmy @command = (\"git-diff-tree\");\n+\tmy $revision_spec;\n+\n+\tif (scalar @$parents == 1) {\n+\n+\t\t$revision_spec = join(\"..\", $parents->[0], $rev);\n+\t\t@pseudo_parents = @$parents;\n+\t} else {\n+\t\tmy @all_parents = git_find_all_parents($rev);\n+\n+\t\tif (@all_parents !=  @$parents) {\n+\t\t\t@pseudo_parents = get_pseudo_parents(\\@all_parents, $parents);\n+\t\t} else {\n+\t\t\t@pseudo_parents = @$parents;\n+\t\t}\n+\n+\t\t$revision_spec = $rev;\n+\t\tpush @command, \"-c\";\n+\t}\n+\n \tmy @filenames = ( $revs{$rev}{'filename'} );\n+\n \tforeach my $parent (@$parents) {\n \t\tpush @filenames, $revs{$parent}{'filename'};\n \t}\n \n-\tmy $diff = open_pipe(\"git-diff-tree\",\"-M\",\"-p\",\"-c\",$rev,\"--\",\n-\t\t\t\t@filenames )\n+\tpush @command, \"-p\", \"-M\", $revision_spec, \"--\", @filenames;\n+\n+\n+\tmy $diff = open_pipe( @command )\n \t\tor die \"Failed to call git-diff for annotation: $!\";\n \n-\t_git_diff_parse($diff, $parents, $rev, %revinfo);\n+\t_git_diff_parse($diff, \\@pseudo_parents, $rev, %revinfo);\n \n \tclose($diff);\n }\n@@ -283,6 +390,7 @@ sub _git_diff_parse {\n \t$diff_header_regexp .= \"@\" x @$parents;\n \t$diff_header_regexp .= ' -\\d+,\\d+' x @$parents;\n \t$diff_header_regexp .= ' \\+(\\d+),\\d+';\n+\t$diff_header_regexp .= \" \" . (\"@\" x @$parents);\n \n \tmy %claim_regexps;\n \tmy $allparentplus = '^' . '\\\\+' x @$parents . '(.*)$';\n@@ -311,6 +419,7 @@ sub _git_diff_parse {\n \tDIFF:\n \twhile(<$diff>) {\n \t\tchomp;\n+\t\t#printf(\"%d:%s:\\n\", $gotheader, $_);\n \t\tif (m/$diff_header_regexp/) {\n \t\t\t$remstart = $1 - 1;\n \t\t\t# (0-based arrays)\n@@ -391,10 +500,17 @@ sub _git_diff_parse {\n \t\t\t\t\t\tprintf(\"parent %s is on line %d\\n\", $parent, $pi{$parent});\n \t\t\t\t\t}\n \n+\t\t\t\t\tmy @context;\n+\t\t\t\t\tfor (my $i = -2; $i < 2; $i++) {\n+\t\t\t\t\t\tpush @context, get_line($slines, $ri + $i);\n+\t\t\t\t\t}\n+\t\t\t\t\tmy $context = join(\"\\n\", @context);\n+\n+\t\t\t\t\tmy $justline = substr($_, scalar @$parents);\n \t\t\t\t\tdie sprintf(\"Line %d, does not match:\\n|%s|\\n|%s|\\n%s\\n\",\n \t\t\t\t\t\t    $ri,\n-\t\t\t\t\t\tsubstr($_,scalar @$parents),\n-\t\t\t\t\t\tget_line($slines,$ri), $rev);\n+\t\t\t\t\t\t    $justline,\n+\t\t\t\t\t\t    $context);\n \t\t\t\t}\n \t\t\t\tforeach my $parent (@$parents) {\n \t\t\t\t\t$plines{$parent}[$pi{$parent}++] = $slines->[$ri];\n-- \n1.4.2.rc3.g6487-dirty\n"},{"id":"24938","messageId":"7virl42w6s.fsf@assigned-by-dhcp.cox.net","threadId":"5111","inReplyTo":"11549526841904-git-send-email-ryan@michonline.com","subject":"Re: [PATCH 2/2] annotate: Fix bug when parsing merges with differing real and logical parents.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-07T19:16:27Z","receivedAt":"2006-08-07T19:16:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This does stop it from dying on Jeff King's bug report\n(<20060803203848.GA15121@coredump.intra.peff.net>) to annotate\nbuiltin-read-tree.c.  However,...\n\nComparing output between \"annotate\" and \"blame -c\" on the same\nfile shows a rather interesting differences.\n\n(1) \"annotate\" blames the first line \"/*\" to d147e501 made on\n    2006-05-23, while \"blame\" annotates it with 8bc9a0c7 made on\n    2005-04-07.  As far as I remember this line has never been\n    touched by anybody during the life of the file, so the\n    latter sounds more plausible.\n\n(2) The 13th line to #include \"cache-tree.h\" is blamed on\n    3f69d405 by \"annotate\", while annotation by \"blame\" reads\n    that it came from bad68ec9.\n\n    3f69d405 is a merge to incorporate the line into \"master\"\n    branch.  \"git show -M 3f69d405 -- builtin-read-tree.c read-tree.c\"\n    starts with:\n\n        diff --cc builtin-read-tree.c\n        index ec40d01,99e7c75..716f792\n        --- a/builtin-read-tree.c\n        +++ b/builtin-read-tree.c\n        @@@ -9,9 -9,9 +9,10 @@@\n\n          #include \"object.h\"\n          #include \"tree.h\"\n        + #include \"cache-tree.h\"\n\t  #include <sys/time.h>\n\n    Which means the line is new from the point of view of the\n    \"master\" branch, but existed in the branch that this commit\n    merges from (namely, jc/cache-tree) already.\n\n    \"git show -M bad68ec9 -- read-tree.c\" shows that it is the\n    one that added the #include line to the history.\n\n(3) The 14th line to #include <sys/time.h> is blamed on d147e501\n    by \"annotate\" but \"blame\" says it came from 744633cb.  It is\n    obvious the latter is correct, if you look at \"git show\" on\n    these commits.  The eye-candy was what made <sys/time.h>\n    necessary (it needed to do the progress-signal stuff).\n\nIn fact, \"annotate\" attributes too many lines to d147e501 (839\nlines).\n\nGiven that \"git show -M d147e501 -- read-tree.c builtin-read-tree.c\"\nshows only 2 insertions and 1 deletion, it does not sound\nright.  The commit adds #include \"builtin.h\" and changes the\nfunction name \"main\" to \"cmd_read_tree\".\n\nOn the other hand, \"blame\" attributes only 1 line to this\ncommit; the line to #include \"builtin.h\".  The other change this\ncommit introduces (main -> cmd_read_tree) is not counted because\nthe third parameter to the function changes after this commit by\na91af794 (which, by the way, both \"annotate\" and \"blame\" get\nright), and the line this commit introduces did not survive.\n"},{"id":"24942","messageId":"7vy7u01glb.fsf@assigned-by-dhcp.cox.net","threadId":"5111","inReplyTo":"1154952684908-git-send-email-ryan@michonline.com","subject":"Re: [PATCH 1/2] log-tree: show_log() should respect the setting of diffopt->line_termination","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-07T19:38:40Z","receivedAt":"2006-08-07T19:38:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks.  This indeed was a regression from 1.0 codebase.\n"},{"id":"24944","messageId":"20060807194539.GD15477@h4x0r5.com","threadId":"5111","inReplyTo":"7virl42w6s.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 2/2] annotate: Fix bug when parsing merges with differing real and logical parents.","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2006-08-07T19:45:40Z","receivedAt":"2006-08-07T19:45:40Z","isPatch":true,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Mon, Aug 07, 2006 at 12:16:27PM -0700, Junio C Hamano wrote:\n> This does stop it from dying on Jeff King's bug report\n> (<20060803203848.GA15121@coredump.intra.peff.net>) to annotate\n> builtin-read-tree.c.  However,...\n> \n> Comparing output between \"annotate\" and \"blame -c\" on the same\n> file shows a rather interesting differences.\n\nYes, annotate is still mis-attributing things to merges that it should\nnot.  I was kind of hoping this fix would have a side-effect of fixing\nit, but I had no logical reason to think it would.   I'm going to try\nagain at fixing it later this week, maybe the weekend, but I'm starting\nto think that maybe blame has won. :)\n\n> \n> (1) \"annotate\" blames the first line \"/*\" to d147e501 made on\n>     2006-05-23, while \"blame\" annotates it with 8bc9a0c7 made on\n>     2005-04-07.  As far as I remember this line has never been\n>     touched by anybody during the life of the file, so the\n>     latter sounds more plausible.\n> \n> (2) The 13th line to #include \"cache-tree.h\" is blamed on\n>     3f69d405 by \"annotate\", while annotation by \"blame\" reads\n>     that it came from bad68ec9.\n> \n>     3f69d405 is a merge to incorporate the line into \"master\"\n>     branch.  \"git show -M 3f69d405 -- builtin-read-tree.c read-tree.c\"\n>     starts with:\n> \n>         diff --cc builtin-read-tree.c\n>         index ec40d01,99e7c75..716f792\n>         --- a/builtin-read-tree.c\n>         +++ b/builtin-read-tree.c\n>         @@@ -9,9 -9,9 +9,10 @@@\n> \n>           #include \"object.h\"\n>           #include \"tree.h\"\n>         + #include \"cache-tree.h\"\n> \t  #include <sys/time.h>\n> \n>     Which means the line is new from the point of view of the\n>     \"master\" branch, but existed in the branch that this commit\n>     merges from (namely, jc/cache-tree) already.\n> \n>     \"git show -M bad68ec9 -- read-tree.c\" shows that it is the\n>     one that added the #include line to the history.\n> \n> (3) The 14th line to #include <sys/time.h> is blamed on d147e501\n>     by \"annotate\" but \"blame\" says it came from 744633cb.  It is\n>     obvious the latter is correct, if you look at \"git show\" on\n>     these commits.  The eye-candy was what made <sys/time.h>\n>     necessary (it needed to do the progress-signal stuff).\n> \n> In fact, \"annotate\" attributes too many lines to d147e501 (839\n> lines).\n> \n> Given that \"git show -M d147e501 -- read-tree.c builtin-read-tree.c\"\n> shows only 2 insertions and 1 deletion, it does not sound\n> right.  The commit adds #include \"builtin.h\" and changes the\n> function name \"main\" to \"cmd_read_tree\".\n> \n> On the other hand, \"blame\" attributes only 1 line to this\n> commit; the line to #include \"builtin.h\".  The other change this\n> commit introduces (main -> cmd_read_tree) is not counted because\n> the third parameter to the function changes after this commit by\n> a91af794 (which, by the way, both \"annotate\" and \"blame\" get\n> right), and the line this commit introduces did not survive.\n> \n> \n> \n\n-- \n\nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"24946","messageId":"7vpsfc1fkt.fsf_-_@assigned-by-dhcp.cox.net","threadId":"5111","inReplyTo":"7virl42w6s.fsf@assigned-by-dhcp.cox.net","subject":"Annotate another problem report","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-07T20:00:34Z","receivedAt":"2006-08-07T20:00:34Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"git annotate Makefile v1.4.0\" outputs this:\n\n...\n58e60dd2\t(Nick Hengeveld\t2005-11-02 11:19:24 -0800\t13)# git.......\n58e60dd2\t(Nick Hengeveld\t2005-11-02 11:19:24 -0800\t14)# tra.......\n\t(          \t1970-01-01 00:00:00 \t15)#\n6d9bbc50\t(Patrick Mauritz\t2005-09-19 16:11:19 +0200\t16)# ..\n6d9bbc50\t(Patrick Mauritz\t2005-09-19 16:11:19 +0200\t17)# ..\n...\n\nThere are a handful lines it couldn't tell where they came from:\n\n\t(          \t1970-01-01 00:00:00 \t15)#\n\t(          \t1970-01-01 00:00:00 \t179)\n\t(          \t1970-01-01 00:00:00 \t182)\n\t(          \t1970-01-01 00:00:00 \t274)endif\n\t(          \t1970-01-01 00:00:00 \t323)\n\t(          \t1970-01-01 00:00:00 \t384)else\n\t(          \t1970-01-01 00:00:00 \t385)\tLIB_4_ICONV =\n"},{"id":"24948","messageId":"20060807201920.GE15477@h4x0r5.com","threadId":"5111","inReplyTo":"7vpsfc1fkt.fsf_-_@assigned-by-dhcp.cox.net","subject":"Re: Annotate another problem report","fromName":"Ryan Anderson","fromEmail":"ryan@michonline.com","sentAt":"2006-08-07T20:19:21Z","receivedAt":"2006-08-07T20:19:21Z","isPatch":false,"sender":{"key":"ryan@michonline.com","avatar":null},"body":"On Mon, Aug 07, 2006 at 01:00:34PM -0700, Junio C Hamano wrote:\n> \"git annotate Makefile v1.4.0\" outputs this:\n\nKnown.  I think this is related to the merge-parsing bug.\n\nUnfortunately, the only test cases I've found for this involve things\nwith both a lot of revisions and a lot of lines, so it's a bit hard to\nmanually see what's going wrong.\n\n> ...\n> 58e60dd2\t(Nick Hengeveld\t2005-11-02 11:19:24 -0800\t13)# git.......\n> 58e60dd2\t(Nick Hengeveld\t2005-11-02 11:19:24 -0800\t14)# tra.......\n> \t(          \t1970-01-01 00:00:00 \t15)#\n> 6d9bbc50\t(Patrick Mauritz\t2005-09-19 16:11:19 +0200\t16)# ..\n> 6d9bbc50\t(Patrick Mauritz\t2005-09-19 16:11:19 +0200\t17)# ..\n> ...\n> \n> There are a handful lines it couldn't tell where they came from:\n> \n> \t(          \t1970-01-01 00:00:00 \t15)#\n> \t(          \t1970-01-01 00:00:00 \t179)\n> \t(          \t1970-01-01 00:00:00 \t182)\n> \t(          \t1970-01-01 00:00:00 \t274)endif\n> \t(          \t1970-01-01 00:00:00 \t323)\n> \t(          \t1970-01-01 00:00:00 \t384)else\n> \t(          \t1970-01-01 00:00:00 \t385)\tLIB_4_ICONV =\n> \n> \n\n-- \n\nRyan Anderson\n  sometimes Pug Majere\n"},{"id":"24969","messageId":"7vvep3wr15.fsf@assigned-by-dhcp.cox.net","threadId":"5111","inReplyTo":"20060807115000.GC15477@h4x0r5.com","subject":"Re: git-annotate bug report","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-08T08:49:42Z","receivedAt":"2006-08-08T08:49:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ryan Anderson <ryan@michonline.com> writes:\n\n> Second, one I don't know how to fix, at the moment:\n>\n> git annotate uses the automatic tree simplification that git rev-list\n> does.  So, when it sees a commit with 1 parent, it assumes that it\n> really only has one parent.  git diff-tree -c doesn't know about this\n> same tree simplification, and, in the case of a merge commit, will still\n> output the -c format patch.\n\nWhen a merge M between A and B is simplified to have only A as a\nparent, that means the file in question are identical in M and\nA.  So you can just pass all the remaining blame on to A without\nletting M taking any blame for itself.  So you do not need to do\nany diff at all for a simplified merge.\n\n> There is, unfortunately, another situation, that of an octopus merge.\n> In the case of read-tree.c (after the rename is followed), the commit\n> 7bd1527d2d8c80a6e9a0f8583082a5aee5428c68 is problematic.  In it we have\n> a 4-way merge, yet only 3 paths affected read-tree.c.  The diff-parsing\n> in annotate constructs a regular expression to find the diff header and\n> read out the line number to work on, and also to construct some regular\n> expressions from which to tell which lines affect which parents.\n\nIf a merge is not simplified, and if you end up reading from\n--cc or -c -p, then:\n\n> For example, it looks for a line like:\n> + ++Line added in 3 parents\n> with dynamically generated regular expressions.\n\nthe merge needs to claim responsibility only for lines that have\nall pluses (i.e. evil merge), which you are already doing, I\nthink.  Any line without a minus that has at least one space can\nbe blamed on the parent that corresponds to the space (and if\nthere are more than one space, pick the first one).\n\nYour particular \"octopus\" case, I think, is the same story.\n\n$ git diff-tree --pretty=short -p -c 7bd1527 -- read-tree.c builtin-read-tree.c\n\nwould give you a combined diff, none of which has $allparentplus\n(so nothing should be attributed to this merge), and the header\nwould tell you which parent to pass the blame on from that\npoint.\n"}]}