{"thread":{"id":"4631","subject":"git-format-patch builtin isn't using git-cherry?","startedAt":"2006-06-23T00:32:01Z","lastAt":"2006-06-23T15:44:48Z","messageCount":5,"participants":["Martin Langhoff","Johannes Schindelin","Timo Hirvonen"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"22324","messageId":"46a038f90606221732k6d93bcceic2761081d7a7c72b@mail.gmail.com","threadId":"4631","inReplyTo":null,"subject":"git-format-patch builtin isn't using git-cherry?","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2006-06-23T00:32:01Z","receivedAt":"2006-06-23T00:32:01Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"I used to rely on git-format-patch to be calling git-cherry in the bg,\nso that I'd know that the obviously merged patches were upstream\nalredy. It doesn't seem to do it any more.\n\nReading cmd_format_patch() in builtin-log.c, it seems to have lost\nthat magic that made it so useful... :( Can a kind soul that speaks C\nfluently help me out here?\n\n(The new format-patch gives me 180 patches to merge/rebase, where the\nold one tells me there's only 51. guess which one I prefer ;-) )\n\ncheers,\n\n\n\nm\n"},{"id":"22346","messageId":"Pine.LNX.4.63.0606231357420.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4631","inReplyTo":"46a038f90606221732k6d93bcceic2761081d7a7c72b@mail.gmail.com","subject":"Re: git-format-patch builtin isn't using git-cherry?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-06-23T12:05:12Z","receivedAt":"2006-06-23T12:05:12Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 23 Jun 2006, Martin Langhoff wrote:\n\n> Reading cmd_format_patch() in builtin-log.c, it seems to have lost that \n> magic that made it so useful... :( Can a kind soul that speaks C \n> fluently help me out here?\n\nMy fault. But note that it is much faster now, too! I think I can trick it \nback into doing something like the old script, but I'll do that only with \nan option (in order to not slow down the now-common case). And it will \ntake a while. So if anybody wants to give it a try...\n\nBasically, it will involve the following recipe:\n\n\t- add a DIFF_FORMAT_PATCH_ID\n\t- calculate _all_ the patch ids in upstream since branch point\n\t- in cmd_format_patch, in the get_revision() loop, skip those\n\t  commits which have the same patch id\n\nCiao,\nDscho\n"},{"id":"22347","messageId":"20060623152321.2c20e9f8.tihirvon@gmail.com","threadId":"4631","inReplyTo":"Pine.LNX.4.63.0606231357420.29667@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: git-format-patch builtin isn't using git-cherry?","fromName":"Timo Hirvonen","fromEmail":"tihirvon@gmail.com","sentAt":"2006-06-23T12:23:21Z","receivedAt":"2006-06-23T12:23:21Z","isPatch":false,"sender":{"key":"tihirvon@gmail.com","avatar":null},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n\n> Basically, it will involve the following recipe:\n> \n> \t- add a DIFF_FORMAT_PATCH_ID\n\nPlease don't add any DIFF_FORMAT_*.  I'm cleaning the diff output code\nand replacing diff_options.output_format with one-bit flags.\n\n-- \nhttp://onion.dynserv.net/~timo/\n"},{"id":"22349","messageId":"Pine.LNX.4.63.0606231431420.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4631","inReplyTo":"20060623152321.2c20e9f8.tihirvon@gmail.com","subject":"Re: git-format-patch builtin isn't using git-cherry?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-06-23T12:33:25Z","receivedAt":"2006-06-23T12:33:25Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 23 Jun 2006, Timo Hirvonen wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> \n> > Basically, it will involve the following recipe:\n> > \n> > \t- add a DIFF_FORMAT_PATCH_ID\n> \n> Please don't add any DIFF_FORMAT_*.  I'm cleaning the diff output code\n> and replacing diff_options.output_format with one-bit flags.\n\nOkay. For the purposes of git-format-patch, this is not needed anyway, but \nrather a function which takes two tree objects and returns the patch id. \nWhen you are finished it should be easy to add this as a display format.\n\nCiao,\nDscho\n"},{"id":"22361","messageId":"Pine.LNX.4.63.0606231743150.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4631","inReplyTo":"Pine.LNX.4.63.0606231431420.29667@wbgn013.biozentrum.uni-wuerzburg.de","subject":"[FYI/PATCH] diff: add diff_flush_patch_id()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-06-23T15:44:48Z","receivedAt":"2006-06-23T15:44:48Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nCall it like this:\n\nunsigned char id[20];\nif (diff_flush_patch_id(diff_options, id))\n\tprintf(\"And the patch id is: %s\\n\", sha1_to_hex(id));\n\nThis patch also adds a switch \"--with-patch-id\" to the diff family, to\nprint out the patch id before each patch.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n\n\t> > > \t- add a DIFF_FORMAT_PATCH_ID\n\t> > \n\t> > Please don't add any DIFF_FORMAT_*.  I'm cleaning the diff output code\n\t> > and replacing diff_options.output_format with one-bit flags.\n\t> \n\t> Okay. For the purposes of git-format-patch, this is not needed \n\t> anyway, but rather a function which takes two tree objects and \n\t> returns the patch id. When you are finished it should be easy to \n\t> add this as a display format.\n\n\tTimo, I am prepared to redo this patch when you finished\n\tthe cleanup.\n\n diff.c |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n diff.h |    3 +\n 2 files changed, 132 insertions(+), 0 deletions(-)\n\ndiff --git a/diff.c b/diff.c\nindex 5b34f73..1140d54 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1460,6 +1460,8 @@ int diff_opt_parse(struct diff_options *\n \t\toptions->output_format = DIFF_FORMAT_PATCH;\n \t\toptions->with_stat = 1;\n \t}\n+\telse if (!strcmp(arg, \"--with-patch-id\"))\n+\t\toptions->with_patch_id = 1;\n \telse if (!strcmp(arg, \"-z\"))\n \t\toptions->line_termination = 0;\n \telse if (!strncmp(arg, \"-l\", 2))\n@@ -2027,12 +2029,139 @@ static void diff_summary(struct diff_fil\n \t}\n }\n \n+struct patch_id_t {\n+\tstruct xdiff_emit_state xm;\n+\tSHA_CTX *ctx;\n+\tint patchlen;\n+};\n+\n+static int remove_space(char *line, int len)\n+{\n+\tint i;\n+        char *dst = line;\n+        unsigned char c;\n+\n+        for (i = 0; i < len; i++)\n+                if (!isspace((c = line[i])))\n+                        *dst++ = c;\n+\n+        return dst - line;\n+}\n+\n+static void patch_id_consume(void *priv, char *line, unsigned long len)\n+{\n+\tstruct patch_id_t *data = priv;\n+\tint new_len;\n+\n+\t/* Ignore line numbers when computing the SHA1 of the patch */\n+\tif (!strncmp(line, \"@@ -\", 4))\n+\t\treturn;\n+\n+\tnew_len = remove_space(line, len);\n+\n+\tSHA1_Update(data->ctx, line, new_len);\n+\tdata->patchlen += new_len;\n+}\n+\n+/* returns 0 upon success, and writes result into sha1 */\n+int diff_flush_patch_id(struct diff_options *options, unsigned char *sha1)\n+{\n+\tstruct diff_queue_struct *q = &diff_queued_diff;\n+\tint i;\n+\tSHA_CTX ctx;\n+\tstruct patch_id_t data;\n+\tchar buffer[PATH_MAX * 4 + 20];\n+\n+\tSHA1_Init(&ctx);\n+\tmemset(&data, 0, sizeof(struct patch_id_t));\n+\tdata.ctx = &ctx;\n+\tdata.xm.consume = patch_id_consume;\n+\t\n+\tfor (i = 0; i < q->nr; i++) {\n+\t\txpparam_t xpp;\n+\t\txdemitconf_t xecfg;\n+\t\txdemitcb_t ecb;\n+\t\tmmfile_t mf1, mf2;\n+\t\tstruct diff_filepair *p = q->queue[i];\n+\t\tint len1, len2;\n+\n+\t\tif (p->status == 0)\n+\t\t\treturn error(\"internal diff status error\");\n+\t\tif (p->status == DIFF_STATUS_UNKNOWN)\n+\t\t\tcontinue;\n+\t\tif (diff_unmodified_pair(p))\n+\t\t\tcontinue;\n+\t\tif ((DIFF_FILE_VALID(p->one) && S_ISDIR(p->one->mode)) ||\n+\t\t    (DIFF_FILE_VALID(p->two) && S_ISDIR(p->two->mode)))\n+\t\t\tcontinue;\n+\t\tif (DIFF_PAIR_UNMERGED(p))\n+\t\t\tcontinue;\n+\n+\t\tdiff_fill_sha1_info(p->one);\n+\t\tdiff_fill_sha1_info(p->two);\n+\t\tif (fill_mmfile(&mf1, p->one) < 0 ||\n+\t\t\t\tfill_mmfile(&mf2, p->two) < 0)\n+\t\t\treturn error(\"unable to read files to diff\");\n+\n+\t\t/* Maybe hash p->two? into the patch id? */\n+\t\tif (mmfile_is_binary(&mf2))\n+\t\t\tcontinue;\n+\n+\t\tlen1 = remove_space(p->one->path, strlen(p->one->path));\n+\t\tlen2 = remove_space(p->two->path, strlen(p->two->path));\n+\t\tif (p->one->mode == 0)\n+\t\t\tlen1 = snprintf(buffer, sizeof(buffer),\n+\t\t\t\t\t\"diff--gita/%.*sb/%.*s\"\n+\t\t\t\t\t\"newfilemode%06o\"\n+\t\t\t\t\t\"---/dev/null\"\n+\t\t\t\t\t\"+++b/%.*s\",\n+\t\t\t\t\tlen1, p->one->path,\n+\t\t\t\t\tlen2, p->two->path,\n+\t\t\t\t\tp->two->mode,\n+\t\t\t\t\tlen2, p->two->path);\n+\t\telse if (p->two->mode == 0)\n+\t\t\tlen1 = snprintf(buffer, sizeof(buffer),\n+\t\t\t\t\t\"diff--gita/%.*sb/%.*s\"\n+\t\t\t\t\t\"deletedfilemode%06o\"\n+\t\t\t\t\t\"---a/%.*s\"\n+\t\t\t\t\t\"+++/dev/null\",\n+\t\t\t\t\tlen1, p->one->path,\n+\t\t\t\t\tlen2, p->two->path,\n+\t\t\t\t\tp->one->mode,\n+\t\t\t\t\tlen1, p->one->path);\n+\t\telse\n+\t\t\tlen1 = snprintf(buffer, sizeof(buffer),\n+\t\t\t\t\t\"diff--gita/%.*sb/%.*s\"\n+\t\t\t\t\t\"---a/%.*s\"\n+\t\t\t\t\t\"+++b/%.*s\",\n+\t\t\t\t\tlen1, p->one->path,\n+\t\t\t\t\tlen2, p->two->path,\n+\t\t\t\t\tlen1, p->one->path,\n+\t\t\t\t\tlen2, p->two->path);\n+\t\tSHA1_Update(&ctx, buffer, len1);\n+\n+\t\txpp.flags = XDF_NEED_MINIMAL;\n+\t\txecfg.ctxlen = 3;\n+\t\txecfg.flags = 3;\n+\t\tecb.outf = xdiff_outf;\n+\t\tecb.priv = &data;\n+\t\txdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);\n+\t}\n+\n+\tSHA1_Final(sha1, &ctx);\n+\treturn 0;\n+}\n+\n void diff_flush(struct diff_options *options)\n {\n \tstruct diff_queue_struct *q = &diff_queued_diff;\n \tint i;\n \tint diff_output_format = options->output_format;\n \tstruct diffstat_t *diffstat = NULL;\n+\tunsigned char sha1[20];\n+\n+\tif (options->with_patch_id && !diff_flush_patch_id(options, sha1))\n+\t\tprintf(\"patch-id %s\\n\", sha1_to_hex(sha1));\n \n \tif (diff_output_format == DIFF_FORMAT_DIFFSTAT || options->with_stat) {\n \t\tdiffstat = xcalloc(sizeof (struct diffstat_t), 1);\ndiff --git a/diff.h b/diff.h\nindex 7d7b6cd..29aac52 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -27,6 +27,7 @@ struct diff_options {\n \tunsigned recursive:1,\n \t\t with_raw:1,\n \t\t with_stat:1,\n+\t\t with_patch_id:1,\n \t\t tree_in_recursive:1,\n \t\t binary:1,\n \t\t full_index:1,\n@@ -185,4 +186,6 @@ extern int run_diff_files(struct rev_inf\n \n extern int run_diff_index(struct rev_info *revs, int cached);\n \n+extern int diff_flush_patch_id(struct diff_options *, unsigned char *);\n+\n #endif /* DIFF_H */\n-- \n1.4.0.g319e-dirty\n"}]}