{"thread":{"id":"6006","subject":"[PATCH] rev-list --left-right","startedAt":"2006-10-23T04:47:48Z","lastAt":"2006-10-23T04:47:48Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"29699","messageId":"7v7iyrzlhn.fsf@assigned-by-dhcp.cox.net","threadId":"6006","inReplyTo":null,"subject":"[PATCH] rev-list --left-right","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-10-23T04:47:48Z","receivedAt":"2006-10-23T04:47:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The output from \"symmetric diff\", i.e. A...B, does not\ndistinguish between commits that are reachable from A and the\nones that are reachable from B.  In this picture, such a\nsymmetric diff includes commits marked with a and b.\n\n         x---b---b  branch B\n        / \\ /\n       /   .\n      /   / \\\n     o---x---a---a  branch A\n\nHowever, you cannot tell which ones are 'a' and which ones are\n'b' from the output.  Sometimes this is frustrating.  This adds\nan output option, --left-right, to rev-list.\n\n        rev-list --left-right A...B\n\nwould show ones reachable from A prefixed with '<' and the ones\nreachable from B prefixed with '>'.\n\nWhen combined with --boundary, boundary commits (the ones marked\nwith 'x' in the above picture) are shown with prefix '-', so you\nwould see list that looks like this:\n\n    git rev-list --left-right --boundary --pretty=oneline A...B\n\n    >bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 3rd on b\n    >bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 2nd on b\n    <aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 3rd on a\n    <aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2nd on a\n    -xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 1st on b\n    -xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 1st on a\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n * This lets you write something like git-cherry with a single\n   invocation of rev-list instead of two.  We would need a diff\n   format that gives patch-id in addition to this patch to make\n   git-cherry more efficient though.\n\n builtin-rev-list.c |   11 +++++++++++\n commit.c           |   10 +++++-----\n revision.c         |    5 ++++-\n revision.h         |    1 +\n 4 files changed, 21 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin-rev-list.c b/builtin-rev-list.c\nindex fb7fc92..4364035 100644\n--- a/builtin-rev-list.c\n+++ b/builtin-rev-list.c\n@@ -45,6 +45,7 @@ static int bisect_list;\n static int show_timestamp;\n static int hdr_termination;\n static const char *header_prefix;\n+static int show_left_right;\n \n static void show_commit(struct commit *commit)\n {\n@@ -54,6 +55,12 @@ static void show_commit(struct commit *c\n \t\tfputs(header_prefix, stdout);\n \tif (commit->object.flags & BOUNDARY)\n \t\tputchar('-');\n+\telse if (show_left_right) {\n+\t\tif (commit->object.flags & SYMMETRIC_LEFT)\n+\t\t\tputchar('<');\n+\t\telse\n+\t\t\tputchar('>');\n+\t}\n \tif (revs.abbrev_commit && revs.abbrev)\n \t\tfputs(find_unique_abbrev(commit->object.sha1, revs.abbrev),\n \t\t      stdout);\n@@ -240,6 +247,10 @@ int cmd_rev_list(int argc, const char **\n \t\t\tbisect_list = 1;\n \t\t\tcontinue;\n \t\t}\n+\t\tif (!strcmp(arg, \"--left-right\")) {\n+\t\t\tshow_left_right = 1;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strcmp(arg, \"--stdin\")) {\n \t\t\tif (read_from_stdin++)\n \t\t\t\tdie(\"--stdin given twice?\");\ndiff --git a/commit.c b/commit.c\nindex a6d543e..289ef65 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -868,11 +868,11 @@ void sort_in_topological_order_fn(struct\n \n /* merge-rebase stuff */\n \n-/* bits #0..7 in revision.h */\n-#define PARENT1\t\t(1u<< 8)\n-#define PARENT2\t\t(1u<< 9)\n-#define STALE\t\t(1u<<10)\n-#define RESULT\t\t(1u<<11)\n+/* bits #0..15 in revision.h */\n+#define PARENT1\t\t(1u<<16)\n+#define PARENT2\t\t(1u<<17)\n+#define STALE\t\t(1u<<18)\n+#define RESULT\t\t(1u<<19)\n \n static struct commit *interesting(struct commit_list *list)\n {\ndiff --git a/revision.c b/revision.c\nindex f1e0caa..26ddf09 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -344,6 +344,7 @@ static void try_to_simplify_commit(struc\n static void add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)\n {\n \tstruct commit_list *parent = commit->parents;\n+\tunsigned left_flag;\n \n \tif (commit->object.flags & ADDED)\n \t\treturn;\n@@ -388,6 +389,7 @@ static void add_parents_to_list(struct r\n \tif (revs->no_walk)\n \t\treturn;\n \n+\tleft_flag = (commit->object.flags & SYMMETRIC_LEFT);\n \tparent = commit->parents;\n \twhile (parent) {\n \t\tstruct commit *p = parent->item;\n@@ -395,6 +397,7 @@ static void add_parents_to_list(struct r\n \t\tparent = parent->next;\n \n \t\tparse_commit(p);\n+\t\tp->object.flags |= left_flag;\n \t\tif (p->object.flags & SEEN)\n \t\t\tcontinue;\n \t\tp->object.flags |= SEEN;\n@@ -643,7 +646,7 @@ int handle_revision_arg(const char *arg,\n \t\t\t\tadd_pending_commit_list(revs, exclude,\n \t\t\t\t\t\t\tflags_exclude);\n \t\t\t\tfree_commit_list(exclude);\n-\t\t\t\ta->object.flags |= flags;\n+\t\t\t\ta->object.flags |= flags | SYMMETRIC_LEFT;\n \t\t\t} else\n \t\t\t\ta->object.flags |= flags_exclude;\n \t\t\tb->object.flags |= flags;\ndiff --git a/revision.h b/revision.h\nindex 3adab95..f92a4d4 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -9,6 +9,7 @@ #define TMP_MARK\t(1u<<4) /* for isolated\n #define BOUNDARY\t(1u<<5)\n #define BOUNDARY_SHOW\t(1u<<6)\n #define ADDED\t\t(1u<<7)\t/* Parents already parsed and added? */\n+#define SYMMETRIC_LEFT\t(1u<<8)\n \n struct rev_info;\n struct log_info;\n-- \n1.4.3.1.g7ad4\n"}]}