{"thread":{"id":"23492","subject":"[PATCH] patch-id: Add support for mbox format","startedAt":"2010-04-16T16:22:28Z","lastAt":"2010-04-20T16:54:26Z","messageCount":11,"participants":["Paolo Bonzini","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"139672","messageId":"1271434948-14134-1-git-send-email-bonzini@gnu.org","threadId":"23492","inReplyTo":null,"subject":"[PATCH] patch-id: Add support for mbox format","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2010-04-16T16:22:28Z","receivedAt":"2010-04-16T16:22:28Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"I have an alias that takes two arguments and compares their patch IDs.\nI would like to use to make sure I've tested exactly what I submit\n(patch by patch), like\n\n   git patch-cmp origin/master.. file-being-sent\n\nHowever, I cannot do that because git patch-id is fooled by the\n\"-- \" trailer that git format-patch puts.\n\nThis patch adds a bit of lookahead to git patch-id in order to detect\nthe trailer and split the patch when it comes.  In addition, commit\nids in the \"From \" lines are considered and printed in the output.\n\nSigned-off-by: Paolo Bonzini <bonzini@gnu.org>\n---\n\tI couldn't resist testing it right away:\n\n\t$ git format-patch -1\n\t0001-patch-id-Add-support-for-mbox-format.patch\n\n\t### With the git I have installed:\n\t$ git patch-cmp HEAD^! 0001-patch-id-Add-support-for-mbox-format.patch\n\tHEAD^! and 0001-patch-id-Add-support-for-mbox-format.patch differ\n\n\t### With this patch:\n\t$ PATH=.:$PATH !!\n\tHEAD^! and 0001-patch-id-Add-support-for-mbox-format.patch are the same\n\n builtin/patch-id.c  |   23 ++++++++++++++++++++++-\n t/t4204-patch-id.sh |   32 ++++++++++++++++++++++++++++++++\n 2 files changed, 54 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin/patch-id.c b/builtin/patch-id.c\nindex af0911e..895c526 100644\n--- a/builtin/patch-id.c\n+++ b/builtin/patch-id.c\n@@ -34,17 +34,22 @@ static void generate_id_list(void)\n \tstatic char line[1000];\n \tgit_SHA_CTX ctx;\n \tint patchlen = 0;\n+\tint have_line = 0;\n \n \tgit_SHA1_Init(&ctx);\n-\twhile (fgets(line, sizeof(line), stdin) != NULL) {\n+\twhile (!feof (stdin) &&\n+\t       (have_line || fgets(line, sizeof(line), stdin) != NULL)) {\n \t\tunsigned char n[20];\n \t\tchar *p = line;\n \t\tint len;\n \n+\t\thave_line = 0;\n \t\tif (!memcmp(line, \"diff-tree \", 10))\n \t\t\tp += 10;\n \t\telse if (!memcmp(line, \"commit \", 7))\n \t\t\tp += 7;\n+\t\telse if (!memcmp(line, \"From \", 5))\n+\t\t\tp += 5;\n \n \t\tif (!get_sha1_hex(p, n)) {\n \t\t\tflush_current_id(patchlen, sha1, &ctx);\n@@ -67,6 +72,22 @@ static void generate_id_list(void)\n \n \t\t/* Compute the sha without whitespace */\n \t\tlen = remove_space(line);\n+\n+\t\t/* Split at -- followed by version number.  */\n+\t\tif (len == 2 && line[0] == '-' && line[1] == '-') {\n+\t\t\tif (fgets(line, sizeof(line), stdin) != NULL &&\n+\t\t\t    isdigit (*line)) {\n+\t\t\t\tflush_current_id(patchlen, sha1, &ctx);\n+\t\t\t\tpatchlen = 0;\n+\t\t\t} else {\n+\t\t\t\t/* Just a normal unified diff line.  */\n+\t\t\t\tpatchlen += 2;\n+\t\t\t\tgit_SHA1_Update(&ctx, \"--\", 2);\n+\t\t\t\thave_line = 1;\n+\t\t\t}\n+\t\t\tcontinue;\n+\t\t}\n+\n \t\tpatchlen += len;\n \t\tgit_SHA1_Update(&ctx, line, len);\n \t}\ndiff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh\nindex 04f7bae..2110eac 100755\n--- a/t/t4204-patch-id.sh\n+++ b/t/t4204-patch-id.sh\n@@ -18,6 +18,11 @@ test_expect_success 'patch-id output is well-formed' '\n \tgrep \"^[a-f0-9]\\{40\\} $(git rev-parse HEAD)$\" output\n '\n \n+get_text_patch_id () {\n+\ttr % '\\n' | git patch-id |\n+\t\tsed \"s# .*##\" > patch-id_\"$1\"\n+}\n+\n get_patch_id () {\n \tgit log -p -1 \"$1\" | git patch-id |\n \t\tsed \"s# .*##\" > patch-id_\"$1\"\n@@ -35,4 +40,31 @@ test_expect_success 'patch-id detects inequality' '\n \t! test_cmp patch-id_master patch-id_notsame\n '\n \n+test_expect_success 'patch-id does not discard meaningful -- line' '\n+\techo \"diff a b%--%-ab%-cd\" | get_text_patch_id first &&\n+\techo \"diff a b%-ab%-cd\" | get_text_patch_id second &&\n+\t! test_cmp patch-id_first patch-id_second\n+'\n+\n+test_expect_success 'patch-id does not discard meaningful final -- line' '\n+\techo \"diff a b%-ab%-cd%--\" | get_text_patch_id first &&\n+\techo \"diff a b%-ab%-cd\" | get_text_patch_id second &&\n+\t! test_cmp patch-id_first patch-id_second\n+'\n+\n+test_expect_success 'whitespace is irrelevant in footer' '\n+\techo \"diff a b%--%-ab%-cd%-- %1.2\" | get_text_patch_id first &&\n+\techo \"diff a b%--%-ab%-cd%--%1.2\" | get_text_patch_id second &&\n+\ttest_cmp patch-id_first patch-id_second\n+'\n+\n+test_expect_success 'patch-id supports git-format-patch output' '\n+\tget_patch_id master &&\n+\tgit checkout same &&\n+\tgit format-patch -1 --stdout | get_text_patch_id same &&\n+\ttest_cmp patch-id_master patch-id_same &&\n+\tset `git format-patch -1 --stdout | git patch-id` &&\n+\ttest \"$2\" = `git rev-parse HEAD`\n+'\n+\n test_done\n-- \n1.6.6.1\n"},{"id":"139694","messageId":"7vk4s7cks4.fsf@alter.siamese.dyndns.org","threadId":"23492","inReplyTo":"1271434948-14134-1-git-send-email-bonzini@gnu.org","subject":"Re: [PATCH] patch-id: Add support for mbox format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-16T18:30:35Z","receivedAt":"2010-04-16T18:30:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Paolo Bonzini <bonzini@gnu.org> writes:\n\n> I have an alias that takes two arguments and compares their patch IDs.\n> I would like to use to make sure I've tested exactly what I submit\n> (patch by patch), like\n>\n>    git patch-cmp origin/master.. file-being-sent\n>\n> However, I cannot do that because git patch-id is fooled by the\n> \"-- \" trailer that git format-patch puts.\n>\n> This patch adds a bit of lookahead to git patch-id in order to detect\n> the trailer and split the patch when it comes.  In addition, commit\n> ids in the \"From \" lines are considered and printed in the output.\n\nHow well does this interact with mime encoded output?\n\nI somehow have a feeling that this is solving a wrong problem.\n"},{"id":"139697","messageId":"4BC8CEC7.40003@gnu.org","threadId":"23492","inReplyTo":"7vk4s7cks4.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] patch-id: Add support for mbox format","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2010-04-16T20:55:35Z","receivedAt":"2010-04-16T20:55:35Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"On 04/16/2010 08:30 PM, Junio C Hamano wrote:\n>> >  I have an alias that takes two arguments and compares their patch IDs.\n>> >  I would like to use to make sure I've tested exactly what I submit\n>> >  (patch by patch), like\n>> >\n>> >      git patch-cmp origin/master.. file-being-sent\n>> >\n>> >  However, I cannot do that because git patch-id is fooled by the\n>> >  \"-- \" trailer that git format-patch puts.\n>> >\n>> >  This patch adds a bit of lookahead to git patch-id in order to detect\n>> >  the trailer and split the patch when it comes.  In addition, commit\n>> >  ids in the \"From \" lines are considered and printed in the output.\n>\n> How well does this interact with mime encoded output?\n\nIt doesn't work.  I have a version of the patch that works with it now \n(by parsing hunk headers and looking for a \"--\" line outside the hunk, \nbut I doubt that would satisfy your feeling.\n\n> I somehow have a feeling that this is solving a wrong problem.\n\nIn what sense?\n\nIn the end the patch id is what matters for the usecase above.  I could \nobtain it in other ways for the \"origin/master..\" part, but the mbox \nfile from \"git format-patch --stdout\" must be given unmodified to \ngit-patch-cmp, otherwise it wouldn't be what I send on the next step.\n\nPaolo\n"},{"id":"139698","messageId":"7vochjay8a.fsf@alter.siamese.dyndns.org","threadId":"23492","inReplyTo":"4BC8CEC7.40003@gnu.org","subject":"Re: [PATCH] patch-id: Add support for mbox format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-16T21:23:01Z","receivedAt":"2010-04-16T21:23:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Paolo Bonzini <bonzini@gnu.org> writes:\n\n> On 04/16/2010 08:30 PM, Junio C Hamano wrote:\n>>> >  I have an alias that takes two arguments and compares their patch IDs.\n>>> >  I would like to use to make sure I've tested exactly what I submit\n>>> >  (patch by patch), like\n>>> >\n>>> >      git patch-cmp origin/master.. file-being-sent\n>>> > ...\n>>\n>> I somehow have a feeling that this is solving a wrong problem.\n>\n> In what sense?\n\nWhy does file-being-sent have anything from origin/master to begin with?\nPerhaps the --ignore-if-in-upstream mechanism needs to be updated so that\nyou won't have duplicates that patch-id could easily find in the first\nplace?\n"},{"id":"139699","messageId":"4BC8DC0F.5010007@gnu.org","threadId":"23492","inReplyTo":"7vochjay8a.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] patch-id: Add support for mbox format","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2010-04-16T21:52:15Z","receivedAt":"2010-04-16T21:52:15Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"On 04/16/2010 11:23 PM, Junio C Hamano wrote:\n>>>>   I have an alias that takes two arguments and compares their patch IDs.\n>>>>   I would like to use to make sure I've tested exactly what I submit\n>>>>   (patch by patch), like\n>>>>\n>>>>       git patch-cmp origin/master.. file-being-sent\n>>>> ...\n>>>\n>>> I somehow have a feeling that this is solving a wrong problem.\n>>\n>> In what sense?\n>\n> Why does file-being-sent have anything from origin/master to begin with?\n> Perhaps the --ignore-if-in-upstream mechanism needs to be updated so that\n> you won't have duplicates that patch-id could easily find in the first\n> place?\n\nI think we're speaking about different things, --ignore-if-in-upstream \ndoesn't have anything to do with this.  The git patch-cmp alias is just \nchecking that\n\n   git show origin/master.. | git patch-id | tac | awk '{print $1}'\n\nand\n\n   git patch-id < file-being-sent | awk '{print $1}'\n\nproduce the exact same output.\n\nI use this when I had to edit the file-being-sent, e.g. to add cover \nletters or an introduction to a patch series.  Since some time passes \nbetween format-patch and send-email, I want to test that the file I'm \nsending is exactly what I have in the repository, and that I'm not \nsubmitting the wrong series.\n\nAlternatively, I could apply file-being-sent to a detached HEAD and \ncompare the trees, like\n\n   topic=`git rev-parse HEAD`\n   git checkout origin/master\n   git am file-being-sent || echo bad\n   mine=HEAD\n   for i in `git rev-list origin/master..$topic`; do\n     git diff-tree $i $mine || echo bad\n     mine=${mine}^\n   done\n\nHowever, comparing the patch-id is faster and perfect for this job. \nWhat were your intended uses for the git-patch-id utility?\n\nPaolo\n"},{"id":"139712","messageId":"7vfx2ubxz1.fsf@alter.siamese.dyndns.org","threadId":"23492","inReplyTo":"4BC8DC0F.5010007@gnu.org","subject":"Re: [PATCH] patch-id: Add support for mbox format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-17T02:43:14Z","receivedAt":"2010-04-17T02:43:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Paolo Bonzini <bonzini@gnu.org> writes:\n\n> I use this when I had to edit the file-being-sent, e.g. to add cover\n> letters or an introduction to a patch series.  Since some time passes\n> between format-patch and send-email, I want to test that the file I'm\n> sending is exactly what I have in the repository, and that I'm not\n> submitting the wrong series.\n\nOk, that is what I missed when I mentioned ignore-if-in-upstream, iow, I\nthought \"patch-cmp\" were merely to check for failed detection of\nduplicates by format-patch.  If you are editing the mbox file and let the\npatches sit there while origin/master may be progressing, then that is an\nentirely different story.\n"},{"id":"139882","messageId":"1271666774-11619-1-git-send-email-bonzini@gnu.org","threadId":"23492","inReplyTo":"7vfx2ubxz1.fsf@alter.siamese.dyndns.org","subject":"[PATCH 1/2] patch-id: extract parsing one diff out of generate_id_list","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2010-04-19T08:46:13Z","receivedAt":"2010-04-19T08:46:13Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"This simplifies a bit the next patch, since it will have more than one\ncondition to exit the loop.\n\nSigned-off-by: Paolo Bonzini <bonzini@gnu.org>\n---\n        On 04/17/2010 04:43 AM, Junio C Hamano wrote:\n        > Paolo Bonzini<bonzini@gnu.org>  writes:\n        > \n        >> I use this when I had to edit the file-being-sent, e.g. to add cover\n        >> letters or an introduction to a patch series.  Since some time passes\n        >> between format-patch and send-email, I want to test that the file I'm\n        >> sending is exactly what I have in the repository, and that I'm not\n        >> submitting the wrong series.\n        > \n        > Ok, that is what I missed when I mentioned ignore-if-in-upstream, iow,\n        > I thought \"patch-cmp\" were merely to check for failed detection of\n        > duplicates by format-patch.  If you are editing the mbox file and let\n        > the patches sit there while origin/master may be progressing, then\n        > that is an entirely different story.\n\n        Yes, that is exactly the point.  I sometimes have to edit the mbox file\n        so I cannot use \"git send-email origin/master..\", and I want a double\n        check that I'm not doing something stupid.\n\n builtin/patch-id.c |   35 +++++++++++++++++++++--------------\n 1 files changed, 21 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/patch-id.c b/builtin/patch-id.c\nindex af0911e..78d24dc 100644\n--- a/builtin/patch-id.c\n+++ b/builtin/patch-id.c\n@@ -28,16 +28,11 @@ static int remove_space(char *line)\n \treturn dst - line;\n }\n \n-static void generate_id_list(void)\n+int get_one_patchid (unsigned char *next_sha1, git_SHA_CTX *ctx)\n {\n-\tstatic unsigned char sha1[20];\n \tstatic char line[1000];\n-\tgit_SHA_CTX ctx;\n \tint patchlen = 0;\n-\n-\tgit_SHA1_Init(&ctx);\n \twhile (fgets(line, sizeof(line), stdin) != NULL) {\n-\t\tunsigned char n[20];\n \t\tchar *p = line;\n \t\tint len;\n \n@@ -46,12 +41,8 @@ static void generate_id_list(void)\n \t\telse if (!memcmp(line, \"commit \", 7))\n \t\t\tp += 7;\n \n-\t\tif (!get_sha1_hex(p, n)) {\n-\t\t\tflush_current_id(patchlen, sha1, &ctx);\n-\t\t\thashcpy(sha1, n);\n-\t\t\tpatchlen = 0;\n-\t\t\tcontinue;\n-\t\t}\n+\t\tif (!get_sha1_hex(p, next_sha1))\n+\t\t\tbreak;\n \n \t\t/* Ignore commit comments */\n \t\tif (!patchlen && memcmp(line, \"diff \", 5))\n@@ -68,9 +59,25 @@ static void generate_id_list(void)\n \t\t/* Compute the sha without whitespace */\n \t\tlen = remove_space(line);\n \t\tpatchlen += len;\n-\t\tgit_SHA1_Update(&ctx, line, len);\n+\t\tgit_SHA1_Update(ctx, line, len);\n+\t}\n+\treturn patchlen;\n+}\n+\n+\n+static void generate_id_list(void)\n+{\n+\tunsigned char sha1[20], n[20];\n+\tgit_SHA_CTX ctx;\n+\tint patchlen;\n+\n+\tgit_SHA1_Init(&ctx);\n+\twhile (!feof (stdin)) {\n+\t\tmemset (n, 0, 20);\n+\t\tpatchlen = get_one_patchid (n, &ctx);\n+\t\tflush_current_id(patchlen, sha1, &ctx);\n+\t\thashcpy (sha1, n);\n \t}\n-\tflush_current_id(patchlen, sha1, &ctx);\n }\n \n static const char patch_id_usage[] = \"git patch-id < patch\";\n-- \n1.6.6.1\n"},{"id":"139883","messageId":"1271666774-11619-2-git-send-email-bonzini@gnu.org","threadId":"23492","inReplyTo":"1271666774-11619-1-git-send-email-bonzini@gnu.org","subject":"[PATCH 2/2] patch-id: Add support for mbox format","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2010-04-19T08:46:14Z","receivedAt":"2010-04-19T08:46:14Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"I have an alias that takes two arguments and compares their patch IDs.\nI would like to use to make sure I've tested exactly what I submit\n(patch by patch), like\n\n   git patch-cmp origin/master.. file-being-sent\n\nHowever, I cannot do that because git patch-id is fooled by the \"-- \"\ntrailer that git format-patch puts, or likely by the MIME boundary.\n\nThis patch adds hunk parsing logic to git patch-id in order to detect an\nout of place \"-\" line and split the patch when it comes.  In addition,\ncommit ids in the \"From \" lines are considered and printed in the output.\n\nSigned-off-by: Paolo Bonzini <bonzini@gnu.org>\n---\n builtin/patch-id.c  |   70 +++++++++++++++++++++++++++++++++++++++++++++-----\n t/t4204-patch-id.sh |   28 ++++++++++++++++++++\n 2 files changed, 91 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/patch-id.c b/builtin/patch-id.c\nindex 78d24dc..c3ecf8f 100644\n--- a/builtin/patch-id.c\n+++ b/builtin/patch-id.c\n@@ -28,10 +28,40 @@ static int remove_space(char *line)\n \treturn dst - line;\n }\n \n+static int scan_hunk_header(const char *p, int *p_before, int *p_after)\n+{\n+\tstatic const char digits[] = \"0123456789\";\n+\tconst char *q, *r;\n+\tint n;\n+\n+\tq = p + 4;\n+\tn = strspn(q, digits);\n+\tif (q[n] == ',') {\n+\t\tq += n + 1;\n+\t\tn = strspn(q, digits);\n+\t}\n+\tif (n == 0 || q[n] != ' ' || q[n+1] != '+')\n+\t\treturn 0;\n+\n+\tr = q + n + 2;\n+\tn = strspn(r, digits);\n+\tif (r[n] == ',') {\n+\t\tr += n + 1;\n+\t\tn = strspn(r, digits);\n+\t}\n+\tif (n == 0)\n+\t\treturn 0;\n+\n+\t*p_before = atoi(q);\n+\t*p_after = atoi(r);\n+\treturn 1;\n+}\n+\n int get_one_patchid (unsigned char *next_sha1, git_SHA_CTX *ctx)\n {\n \tstatic char line[1000];\n \tint patchlen = 0;\n+\tint before = -1, after = -1;\n \twhile (fgets(line, sizeof(line), stdin) != NULL) {\n \t\tchar *p = line;\n \t\tint len;\n@@ -40,6 +70,8 @@ int get_one_patchid (unsigned char *next_sha1, git_SHA_CTX *ctx)\n \t\t\tp += 10;\n \t\telse if (!memcmp(line, \"commit \", 7))\n \t\t\tp += 7;\n+\t\telse if (!memcmp(line, \"From \", 5))\n+\t\t\tp += 5;\n \n \t\tif (!get_sha1_hex(p, next_sha1))\n \t\t\tbreak;\n@@ -48,13 +80,37 @@ int get_one_patchid (unsigned char *next_sha1, git_SHA_CTX *ctx)\n \t\tif (!patchlen && memcmp(line, \"diff \", 5))\n \t\t\tcontinue;\n \n-\t\t/* Ignore git-diff index header */\n-\t\tif (!memcmp(line, \"index \", 6))\n-\t\t\tcontinue;\n-\n-\t\t/* Ignore line numbers when computing the SHA1 of the patch */\n-\t\tif (!memcmp(line, \"@@ -\", 4))\n-\t\t\tcontinue;\n+\t\t/* Parsing diff header?  */\n+\t\tif (before == -1) {\n+\t\t\tif (!memcmp(line, \"index \", 6))\n+\t\t\t\tcontinue;\n+\t\t\telse if (!memcmp(line, \"--- \", 4))\n+\t\t\t\tbefore = after = 1;\n+\t\t\telse if (!isalpha(line[0]))\n+\t\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* Looking for a valid hunk header?  */\n+\t\tif (before == 0 && after == 0) {\n+\t\t\tif (!memcmp (line, \"@@ -\", 4)) {\n+\t\t\t\t/* Parse next hunk, but ignore line numbers.  */\n+\t\t\t\tscan_hunk_header (line, &before, &after);\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\t/* Split at the end of the patch.  */\n+\t\t\tif (memcmp (line, \"diff \", 5))\n+\t\t\t\tbreak;\n+\n+\t\t\t/* Else we're parsing another header.  */\n+\t\t\tbefore = after = -1;\n+\t\t}\n+\n+\t\t/* If we get here, we're inside a hunk.  */\n+\t\tif (line[0] == '-' || line[0] == ' ')\n+\t\t\tbefore--;\n+\t\tif (line[0] == '+' || line[0] == ' ')\n+\t\t\tafter--;\n \n \t\t/* Compute the sha without whitespace */\n \t\tlen = remove_space(line);\ndiff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh\nindex 04f7bae..68e2652 100755\n--- a/t/t4204-patch-id.sh\n+++ b/t/t4204-patch-id.sh\n@@ -18,6 +18,11 @@ test_expect_success 'patch-id output is well-formed' '\n \tgrep \"^[a-f0-9]\\{40\\} $(git rev-parse HEAD)$\" output\n '\n \n+calc_patch_id () {\n+\tgit patch-id |\n+\t\tsed \"s# .*##\" > patch-id_\"$1\"\n+}\n+\n get_patch_id () {\n \tgit log -p -1 \"$1\" | git patch-id |\n \t\tsed \"s# .*##\" > patch-id_\"$1\"\n@@ -35,4 +40,27 @@ test_expect_success 'patch-id detects inequality' '\n \t! test_cmp patch-id_master patch-id_notsame\n '\n \n+test_expect_success 'patch-id supports git-format-patch output' '\n+\tget_patch_id master &&\n+\tgit checkout same &&\n+\tgit format-patch -1 --stdout | calc_patch_id same &&\n+\ttest_cmp patch-id_master patch-id_same &&\n+\tset `git format-patch -1 --stdout | git patch-id` &&\n+\ttest \"$2\" = `git rev-parse HEAD`\n+'\n+\n+test_expect_success 'whitespace is irrelevant in footer' '\n+\tget_patch_id master &&\n+\tgit checkout same &&\n+\tgit format-patch -1 --stdout | sed \"s/ \\$//\" | calc_patch_id same &&\n+\ttest_cmp patch-id_master patch-id_same\n+'\n+\n+test_expect_success 'patch-id supports git-format-patch MIME output' '\n+\tget_patch_id master &&\n+\tgit checkout same &&\n+\tgit format-patch -1 --attach --stdout | calc_patch_id same &&\n+\ttest_cmp patch-id_master patch-id_same\n+'\n+\n test_done\n-- \n1.6.6.1\n"},{"id":"139932","messageId":"7vy6gjp0zy.fsf@alter.siamese.dyndns.org","threadId":"23492","inReplyTo":"1271666774-11619-2-git-send-email-bonzini@gnu.org","subject":"Re: [PATCH 2/2] patch-id: Add support for mbox format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-19T21:48:33Z","receivedAt":"2010-04-19T21:48:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Paolo Bonzini <bonzini@gnu.org> writes:\n\n> This patch adds hunk parsing logic to git patch-id in order to detect an\n> out of place \"-\" line and split the patch when it comes.  In addition,\n> commit ids in the \"From \" lines are considered and printed in the output.\n\nI don't know how this patch will affect the difficulty of enhancing it to\nhandle MIME attachments later, but let's say we won't worry about it for\nnow, because we do not even know if we want to do so at this moment.\n\nI fixed up some style issues locally before applying, but please be\ncareful next time.\n\n - One SP after a keyword used in syntactic constructs (e.g. \"if (cond)\",\n   not \"while(cond)\"); your patches were fine wrt this;\n\n - No SP after a function (e.g. \"memcpy(args...)\", not \"memcpy (args...)\").\n\nAlso please be careful when calling get_sha1_hex(); an unsuccessful call\nto this function is allowed to clobber the buffer.  In addition to the\nstyle fixes, I squashed something like this (not exactly this).\n\nThanks.\n\n builtin/patch-id.c |   11 ++++++++---\n 1 files changed, 8 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/patch-id.c b/builtin/patch-id.c\nindex 40af5c7..4785411 100644\n--- a/builtin/patch-id.c\n+++ b/builtin/patch-id.c\n@@ -61,7 +61,8 @@ int get_one_patchid(unsigned char *next_sha1, git_SHA_CTX *ctx)\n {\n \tstatic char line[1000];\n \tint patchlen = 0;\n-\tint before = -1, after = -1;\n+\tint before = -1, after = -1, found_next = 0;\n+\n \twhile (fgets(line, sizeof(line), stdin) != NULL) {\n \t\tchar *p = line;\n \t\tint len;\n@@ -73,8 +74,10 @@ int get_one_patchid(unsigned char *next_sha1, git_SHA_CTX *ctx)\n \t\telse if (!memcmp(line, \"From \", 5))\n \t\t\tp += 5;\n \n-\t\tif (!get_sha1_hex(p, next_sha1))\n+\t\tif (!get_sha1_hex(p, next_sha1)) {\n+\t\t\tfound_next = 1;\n \t\t\tbreak;\n+\t\t}\n \n \t\t/* Ignore commit comments */\n \t\tif (!patchlen && memcmp(line, \"diff \", 5))\n@@ -117,6 +120,8 @@ int get_one_patchid(unsigned char *next_sha1, git_SHA_CTX *ctx)\n \t\tpatchlen += len;\n \t\tgit_SHA1_Update(ctx, line, len);\n \t}\n+\tif (!found_next)\n+\t\thashclr(next_sha1);\n \treturn patchlen;\n }\n \n@@ -128,8 +133,8 @@ static void generate_id_list(void)\n \tint patchlen;\n \n \tgit_SHA1_Init(&ctx);\n+\thashclr(sha1);\n \twhile (!feof(stdin)) {\n-\t\tmemset(n, 0, 20);\n \t\tpatchlen = get_one_patchid(n, &ctx);\n \t\tflush_current_id(patchlen, sha1, &ctx);\n \t\thashcpy(sha1, n);\n"},{"id":"139957","messageId":"4BCD6A36.90208@gnu.org","threadId":"23492","inReplyTo":"7vy6gjp0zy.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 2/2] patch-id: Add support for mbox format","fromName":"Paolo Bonzini","fromEmail":"bonzini@gnu.org","sentAt":"2010-04-20T08:47:50Z","receivedAt":"2010-04-20T08:47:50Z","isPatch":true,"sender":{"key":"bonzini@gnu.org","avatar":"https://avatars.githubusercontent.com/u/42082?v=4"},"body":"On 04/19/2010 11:48 PM, Junio C Hamano wrote:\n> I don't know how this patch will affect the difficulty of enhancing it to\n> handle MIME attachments later, but let's say we won't worry about it for\n> now, because we do not even know if we want to do so at this moment.\n\nThis v2 also handles MIME, see the tests.\n\nThanks for fixing up the patch.\n\nPaolo\n"},{"id":"139988","messageId":"7v4oj6hxod.fsf@alter.siamese.dyndns.org","threadId":"23492","inReplyTo":"4BCD6A36.90208@gnu.org","subject":"Re: [PATCH 2/2] patch-id: Add support for mbox format","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-20T16:54:26Z","receivedAt":"2010-04-20T16:54:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Paolo Bonzini <bonzini@gnu.org> writes:\n\n> This v2 also handles MIME, see the tests.\n\nI was more worried about quoted-printable (or base64) when I said MIME ;-)\n"}]}