{"thread":{"id":"4661","subject":"[PATCH 2/2] format-patch: introduce \"--ignore-if-in-upstream\"","startedAt":"2006-06-25T01:52:01Z","lastAt":"2006-06-25T01:52:01Z","messageCount":1,"participants":["Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"22501","messageId":"Pine.LNX.4.63.0606250351180.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4661","inReplyTo":null,"subject":"[PATCH 2/2] format-patch: introduce \"--ignore-if-in-upstream\"","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-06-25T01:52:01Z","receivedAt":"2006-06-25T01:52:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nWith this flag, format-patch will try very hard not to output patches which\nare already in the upstream branch.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n---\n builtin-log.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 80 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin-log.c b/builtin-log.c\nindex 5a8a50b..e78a9a4 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -160,6 +160,71 @@ static void reopen_stdout(struct commit \n \tfreopen(filename, \"w\", stdout);\n }\n \n+static void reset_all_objects_flags()\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < obj_allocs; i++)\n+\t\tif (objs[i])\n+\t\t\tobjs[i]->flags = 0;\n+}\n+\n+static int get_patch_id(struct commit *commit, struct diff_options *options,\n+\t\tunsigned char *sha1)\n+{\n+\tdiff_tree_sha1(commit->parents->item->object.sha1, commit->object.sha1,\n+\t\t\t\"\", options);\n+\tdiffcore_std(options);\n+\treturn diff_flush_patch_id(options, sha1);\n+}\n+\n+static void get_patch_ids(struct rev_info *rev, struct diff_options *options)\n+{\n+\tstruct rev_info check_rev;\n+\tstruct commit *commit;\n+\tstruct object *o1, *o2;\n+\tunsigned flags1, flags2;\n+\tunsigned char sha1[20];\n+\n+\tif (rev->pending.nr != 2)\n+\t\tdie(\"Need exactly one range.\");\n+\n+\to1 = rev->pending.objects[0].item;\n+\tflags1 = o1->flags;\n+\to2 = rev->pending.objects[1].item;\n+\tflags2 = o2->flags;\n+\n+\tif ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))\n+\t\tdie(\"Not a range.\");\n+\n+\tdiff_setup(options);\n+\toptions->recursive = 1;\n+\tif (diff_setup_done(options) < 0)\n+\t\tdie(\"diff_setup_done failed\");\n+\n+\t/* given a range a..b get all patch ids for b..a */\n+\tinit_revisions(&check_rev);\n+\to1->flags ^= UNINTERESTING;\n+\to2->flags ^= UNINTERESTING;\n+\tadd_pending_object(&check_rev, o1, \"o1\");\n+\tadd_pending_object(&check_rev, o2, \"o2\");\n+\tprepare_revision_walk(&check_rev);\n+\n+\twhile ((commit = get_revision(&check_rev)) != NULL) {\n+\t\t/* ignore merges */\n+\t\tif (commit->parents && commit->parents->next)\n+\t\t\tcontinue;\n+\n+\t\tif (!get_patch_id(commit, options, sha1))\n+\t\t\tcreated_object(sha1, xcalloc(1, sizeof(struct object)));\n+\t}\n+\n+\t/* reset for next revision walk */\n+\treset_all_objects_flags();\n+\to1->flags = flags1;\n+\to2->flags = flags2;\n+}\n+\n int cmd_format_patch(int argc, const char **argv, char **envp)\n {\n \tstruct commit *commit;\n@@ -170,6 +235,8 @@ int cmd_format_patch(int argc, const cha\n \tint numbered = 0;\n \tint start_number = -1;\n \tint keep_subject = 0;\n+\tint ignore_if_in_upstream = 0;\n+\tstruct diff_options patch_id_opts;\n \tchar *add_signoff = NULL;\n \n \tinit_revisions(&rev);\n@@ -235,6 +302,8 @@ int cmd_format_patch(int argc, const cha\n \t\t\trev.mime_boundary = git_version_string;\n \t\telse if (!strncmp(argv[i], \"--attach=\", 9))\n \t\t\trev.mime_boundary = argv[i] + 9;\n+\t\telse if (!strcmp(argv[i], \"--ignore-if-in-upstream\"))\n+\t\t\tignore_if_in_upstream = 1;\n \t\telse\n \t\t\targv[j++] = argv[i];\n \t}\n@@ -262,14 +331,25 @@ int cmd_format_patch(int argc, const cha\n \t\tadd_head(&rev);\n \t}\n \n+\tif (ignore_if_in_upstream)\n+\t\tget_patch_ids(&rev, &patch_id_opts);\n+\n \tif (!use_stdout)\n \t\trealstdout = fdopen(dup(1), \"w\");\n \n \tprepare_revision_walk(&rev);\n \twhile ((commit = get_revision(&rev)) != NULL) {\n+\t\tunsigned char sha1[20];\n+\n \t\t/* ignore merges */\n \t\tif (commit->parents && commit->parents->next)\n \t\t\tcontinue;\n+\n+\t\tif (ignore_if_in_upstream &&\n+\t\t\t\t!get_patch_id(commit, &patch_id_opts, sha1) &&\n+\t\t\t\tlookup_object(sha1))\n+\t\t\tcontinue;\n+\n \t\tnr++;\n \t\tlist = realloc(list, nr * sizeof(list[0]));\n \t\tlist[nr - 1] = commit;\n-- \n1.4.0.g7a200-dirty\n"}]}