{"thread":{"id":"13287","subject":"[updated PATCH] Simplify and fix --first-parent implementation","startedAt":"2008-04-27T17:32:46Z","lastAt":"2008-04-27T17:32:46Z","messageCount":1,"participants":["Stephen R. van den Berg"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"75304","messageId":"20080427173246.10023.45426.stgit@aristoteles.cuci.nl","threadId":"13287","inReplyTo":null,"subject":"[updated PATCH] Simplify and fix --first-parent implementation","fromName":"Stephen R. van den Berg","fromEmail":"srb@cuci.nl","sentAt":"2008-04-27T17:32:46Z","receivedAt":"2008-04-27T17:32:46Z","isPatch":true,"sender":{"key":"srb@cuci.nl","avatar":"https://gravatar.com/avatar/f75389059e827634d38e9df2a9b6ecbd50028b5a454442efa1c7205b7ff29c6a?d=mp&s=160"},"body":"The purpose of --first-parent is to simplify the tree into a tree without\n merges.  This is accomplished by pretending there are no other parents\nthan the first parent when encountering a merge.  In order to implement\nthis correctly the behaviour should be such that the tree traversal does\nnot depend on any parent other than the first.\n\nThe old code marked the other parents as seen, which means that the tree\ntraversal (under certain circumstances) will behave differently depending\non which merges have been done, therefore violating the rule that only the\nfirst parent should be relevant.\n\nCase in point, given the following tree:\n\n       -----\n      /     \\\n D---E---F---G master\n\nThe current first-parent code considers E to be seen and stops the\ntraversal after showing G and F.\n\nSigned-off-by: Stephen R. van den Berg <srb@cuci.nl>\n---\n\n revision.c |   10 ++++------\n 1 files changed, 4 insertions(+), 6 deletions(-)\n\n\ndiff --git a/revision.c b/revision.c\nindex 4231ea2..bcfcd2a 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -415,7 +415,6 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str\n {\n \tstruct commit_list *parent = commit->parents;\n \tunsigned left_flag;\n-\tint add, rest;\n \n \tif (commit->object.flags & ADDED)\n \t\treturn 0;\n@@ -462,19 +461,18 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str\n \n \tleft_flag = (commit->object.flags & SYMMETRIC_LEFT);\n \n-\trest = !revs->first_parent_only;\n-\tfor (parent = commit->parents, add = 1; parent; add = rest) {\n+\tfor (parent = commit->parents; parent; parent = parent->next) {\n \t\tstruct commit *p = parent->item;\n \n-\t\tparent = parent->next;\n \t\tif (parse_commit(p) < 0)\n \t\t\treturn -1;\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-\t\tif (add)\n-\t\t\tinsert_by_date(p, list);\n+\t\tinsert_by_date(p, list);\n+\t\tif(revs->first_parent_only)\n+\t\t\tbreak;\n \t}\n \treturn 0;\n }\n"}]}