{"thread":{"id":"4132","subject":"[PATCH] Add \"--summary\" option to git diff.","startedAt":"2006-05-14T12:13:49Z","lastAt":"2006-05-15T02:34:33Z","messageCount":5,"participants":["Sean","Junio C Hamano","Linus Torvalds"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"19905","messageId":"BAYC1-PASMTP0770FC4238970CB812C192AEA20@CEZ.ICE","threadId":"4132","inReplyTo":null,"subject":"[PATCH] Add \"--summary\" option to git diff.","fromName":"Sean","fromEmail":"seanlkml@sympatico.ca","sentAt":"2006-05-14T12:13:49Z","receivedAt":"2006-05-14T12:13:49Z","isPatch":true,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"Remove the need to pipe git diff through git apply to\nget the extended headers summary.\n\nSigned-off-by: Sean Estabrooks <seanlkml@sympatico.ca>\n\n---\n\ne5d981eef0203c399d8b1890be94add525eee969\n Documentation/diff-options.txt |    4 ++\n diff.c                         |   88 ++++++++++++++++++++++++++++++++++++++++\n diff.h                         |    3 +\n 3 files changed, 93 insertions(+), 2 deletions(-)\n\ne5d981eef0203c399d8b1890be94add525eee969\ndiff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\nindex c183dc9..f523ec2 100644\n--- a/Documentation/diff-options.txt\n+++ b/Documentation/diff-options.txt\n@@ -10,6 +10,10 @@\n --stat::\n \tGenerate a diffstat instead of a patch.\n \n+--summary::\n+\tOutput a condensed summary of extended header information\n+\tsuch as creations, renames and mode changes.\n+\n --patch-with-stat::\n \tGenerate patch and prepend its diffstat.\n \ndiff --git a/diff.c b/diff.c\nindex 7a7b839..00b1044 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1233,6 +1233,8 @@ int diff_opt_parse(struct diff_options *\n \t}\n \telse if (!strcmp(arg, \"--stat\"))\n \t\toptions->output_format = DIFF_FORMAT_DIFFSTAT;\n+\telse if (!strcmp(arg, \"--summary\"))\n+\t\toptions->summary = 1;\n \telse if (!strcmp(arg, \"--patch-with-stat\")) {\n \t\toptions->output_format = DIFF_FORMAT_PATCH;\n \t\toptions->with_stat = 1;\n@@ -1703,6 +1705,85 @@ static void flush_one_pair(struct diff_f\n \t}\n }\n \n+static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs)\n+{\n+\tif (fs->mode)\n+\t\tprintf(\" %s mode %06o %s\\n\", newdelete, fs->mode, fs->path);\n+\telse\n+\t\tprintf(\" %s %s\\n\", newdelete, fs->path);\n+}\n+\n+\n+static void show_mode_change(struct diff_filepair *p, int show_name)\n+{\n+\tif (p->one->mode && p->two->mode && p->one->mode != p->two->mode) {\n+\t\tif (show_name)\n+\t\t\tprintf(\" mode change %06o => %06o %s\\n\",\n+\t\t\t       p->one->mode, p->two->mode, p->two->path);\n+\t\telse\n+\t\t\tprintf(\" mode change %06o => %06o\\n\",\n+\t\t\t       p->one->mode, p->two->mode);\n+\t}\n+}\n+\n+static void show_rename_copy(const char *renamecopy, struct diff_filepair *p)\n+{\n+\tconst char *old, *new;\n+\n+\t/* Find common prefix */\n+\told = p->one->path;\n+\tnew = p->two->path;\n+\twhile (1) {\n+\t\tconst char *slash_old, *slash_new;\n+\t\tslash_old = strchr(old, '/');\n+\t\tslash_new = strchr(new, '/');\n+\t\tif (!slash_old ||\n+\t\t    !slash_new ||\n+\t\t    slash_old - old != slash_new - new ||\n+\t\t    memcmp(old, new, slash_new - new))\n+\t\t\tbreak;\n+\t\told = slash_old + 1;\n+\t\tnew = slash_new + 1;\n+\t}\n+\t/* p->one->path thru old is the common prefix, and old and new\n+\t * through the end of names are renames\n+\t */\n+\tif (old != p->one->path)\n+\t\tprintf(\" %s %.*s{%s => %s} (%d%%)\\n\", renamecopy,\n+\t\t       (int)(old - p->one->path), p->one->path,\n+\t\t       old, new, (int)(0.5 + p->score * 100.0/MAX_SCORE));\n+\telse\n+\t\tprintf(\" %s %s => %s (%d%%)\\n\", renamecopy,\n+\t\t       p->one->path, p->two->path,\n+\t\t       (int)(0.5 + p->score * 100.0/MAX_SCORE));\n+\tshow_mode_change(p, 0);\n+}\n+\n+static void diff_summary(struct diff_filepair *p)\n+{\n+\tswitch(p->status) {\n+\tcase DIFF_STATUS_DELETED:\n+\t\tshow_file_mode_name(\"delete\", p->one);\n+\t\tbreak;\n+\tcase DIFF_STATUS_ADDED:\n+\t\tshow_file_mode_name(\"create\", p->two);\n+\t\tbreak;\n+\tcase DIFF_STATUS_COPIED:\n+\t\tshow_rename_copy(\"copy\", p);\n+\t\tbreak;\n+\tcase DIFF_STATUS_RENAMED:\n+\t\tshow_rename_copy(\"rename\", p);\n+\t\tbreak;\n+\tdefault:\n+\t\tif (p->score) {\n+\t\t\tprintf(\" rewrite %s (%d%%)\\n\", p->two->path,\n+\t\t\t\t(int)(0.5 + p->score * 100.0/MAX_SCORE));\n+\t\t\tshow_mode_change(p, 0);\n+\t\t} else\tshow_mode_change(p, 1);\n+\t\tbreak;\n+\t}\n+}\n+\n void diff_flush(struct diff_options *options)\n {\n \tstruct diff_queue_struct *q = &diff_queued_diff;\n@@ -1736,7 +1817,6 @@ void diff_flush(struct diff_options *opt\n \tfor (i = 0; i < q->nr; i++) {\n \t\tstruct diff_filepair *p = q->queue[i];\n \t\tflush_one_pair(p, diff_output_format, options, diffstat);\n-\t\tdiff_free_filepair(p);\n \t}\n \n \tif (diffstat) {\n@@ -1744,6 +1824,12 @@ void diff_flush(struct diff_options *opt\n \t\tfree(diffstat);\n \t}\n \n+\tfor (i = 0; i < q->nr; i++) {\n+\t\tif (options->summary)\n+\t\t\tdiff_summary(q->queue[i]);\n+\t\tdiff_free_filepair(q->queue[i]);\n+\t}\n+\n \tfree(q->queue);\n \tq->queue = NULL;\n \tq->nr = q->alloc = 0;\ndiff --git a/diff.h b/diff.h\nindex d052608..70077c6 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -31,7 +31,8 @@ struct diff_options {\n \t\t binary:1,\n \t\t full_index:1,\n \t\t silent_on_remove:1,\n-\t\t find_copies_harder:1;\n+\t\t find_copies_harder:1,\n+\t\t summary:1;\n \tint break_opt;\n \tint detect_rename;\n \tint line_termination;\n-- \n1.3.2.gab2a\n"},{"id":"19943","messageId":"7v3bfcno2b.fsf@assigned-by-dhcp.cox.net","threadId":"4132","inReplyTo":"BAYC1-PASMTP0770FC4238970CB812C192AEA20@CEZ.ICE","subject":"Re: [PATCH] Add \"--summary\" option to git diff.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-15T00:12:28Z","receivedAt":"2006-05-15T00:12:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sean <seanlkml@sympatico.ca> writes:\n\n> Remove the need to pipe git diff through git apply to\n> get the extended headers summary.\n>\n> Signed-off-by: Sean Estabrooks <seanlkml@sympatico.ca>\n\nHmph...\n\nThe next branch with this and other patches applied seems to\nmisbehave.\n\nIt makes glibc unhappy with \n\nPAGER= ./git whatchanged -B -C --stat --summary --no-merges --diff-filter=RC\n\nand \"*** glibc detected *** malloc(): memory corruption: xxx ***\"\n\nbut not with this:\n\nPAGER= ./git whatchanged -B -C --no-merges --diff-filter=RC\n\nnor with this:\n\nPAGER= ./git whatchanged -B -C --summary --no-merges --diff-filter=RC\n\nworks just fine, so this is _not_ your fault, and I know who to\nharrass ;-).\n"},{"id":"19947","messageId":"BAYC1-PASMTP02640E2C9813E4DA1E778BAEA30@CEZ.ICE","threadId":"4132","inReplyTo":"7v3bfcno2b.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add \"--summary\" option to git diff.","fromName":"Sean","fromEmail":"seanlkml@sympatico.ca","sentAt":"2006-05-15T00:54:42Z","receivedAt":"2006-05-15T00:54:42Z","isPatch":true,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Sun, 14 May 2006 17:12:28 -0700\nJunio C Hamano <junkio@cox.net> wrote:\n\n> The next branch with this and other patches applied seems to\n> misbehave.\n> \n> It makes glibc unhappy with \n> \n> PAGER= ./git whatchanged -B -C --stat --summary --no-merges --diff-filter=RC\n\nWhat's a bit more worrying is that:\n\n$ PAGER= ./git whatchanged -B -C --stat --no-merges --diff-filter=RC\n\nCauses the same problem on the current (1.3.2) release branch without any\nother patches applied at all.\n\nSean\n"},{"id":"19949","messageId":"Pine.LNX.4.64.0605141848080.3866@g5.osdl.org","threadId":"4132","inReplyTo":"BAYC1-PASMTP02640E2C9813E4DA1E778BAEA30@CEZ.ICE","subject":"Re: [PATCH] Add \"--summary\" option to git diff.","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-15T01:51:26Z","receivedAt":"2006-05-15T01:51:26Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 14 May 2006, Sean wrote:\n> \n> What's a bit more worrying is that:\n> \n> $ PAGER= ./git whatchanged -B -C --stat --no-merges --diff-filter=RC\n> \n> Causes the same problem on the current (1.3.2) release branch without any\n> other patches applied at all.\n\nIf you have electric fence installed, just do\n\n\tPAGER= ef ./git whatchanged -B -C --stat --no-merges --diff-filter=RC\n\nto run it with the efence preload, which should cause a core-dump and/or \nbe more debuggable.\n\nSadly, last I tried, you can't run gdb under ef, because electric fence \n(incorrectly) thinks that zero-size allocations are bad.\n\n\t\tLinus\n\t\n"},{"id":"19956","messageId":"7v7j4oxbgm.fsf@assigned-by-dhcp.cox.net","threadId":"4132","inReplyTo":"Pine.LNX.4.64.0605141848080.3866@g5.osdl.org","subject":"Re: [PATCH] Add \"--summary\" option to git diff.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-15T02:34:33Z","receivedAt":"2006-05-15T02:34:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> On Sun, 14 May 2006, Sean wrote:\n>> \n>> What's a bit more worrying is that:\n>> \n>> $ PAGER= ./git whatchanged -B -C --stat --no-merges --diff-filter=RC\n>> \n>> Causes the same problem on the current (1.3.2) release branch without any\n>> other patches applied at all.\n\nAnd the culprit was _me_ X-<.  *BLUSH*\n\n\n-- >8 --\n\ndiff --git a/diff.c b/diff.c\nindex 7a7b839..2d72673 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -232,11 +232,16 @@ static char *pprint_rename(const char *a\n \t * name-a => name-b\n \t */\n \tif (pfx_length + sfx_length) {\n+\t\tint a_len = len_a - pfx_length - sfx_length;\n+\t\tint b_len = len_b - pfx_length - sfx_length;\n+\t\tif (a_len < 0) a_len = 0;\n+\t\tif (b_len < 0) b_len = 0;\n+\n \t\tname = xmalloc(len_a + len_b - pfx_length - sfx_length + 7);\n \t\tsprintf(name, \"%.*s{%.*s => %.*s}%s\",\n \t\t\tpfx_length, a,\n-\t\t\tlen_a - pfx_length - sfx_length, a + pfx_length,\n-\t\t\tlen_b - pfx_length - sfx_length, b + pfx_length,\n+\t\t\ta_len, a + pfx_length,\n+\t\t\tb_len, b + pfx_length,\n \t\t\ta + len_a - sfx_length);\n \t}\n \telse {\n"}]}