{"thread":{"id":"5494","subject":"[PATCH 1/2] revision.c: allow injecting revision parameters after setup_revisions().","startedAt":"2006-09-06T04:47:03Z","lastAt":"2006-09-06T04:47:03Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"26386","messageId":"7vd5a9a9fc.fsf@assigned-by-dhcp.cox.net","threadId":"5494","inReplyTo":null,"subject":"[PATCH 1/2] revision.c: allow injecting revision parameters after setup_revisions().","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-09-06T04:47:03Z","receivedAt":"2006-09-06T04:47:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"setup_revisions() wants to get all the parameters at once and\nthen postprocesses the resulting revs structure after it is done\nwith them.  This code structure is a bit cumbersome to deal with\nefficiently when we want to inject revision parameters from the\nside (e.g. read from standard input).\n\nFortunately, the nature of this postprocessing is not affected by\nrevision parameters; they are affected only by flags.  So it is\nOk to do add_object() after the it returns.\n\nThis splits out the code that deals with the revision parameter\nout of the main loop of setup_revisions(), so that we can later\ncall it from elsewhere after it returns.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n revision.c |  159 ++++++++++++++++++++++++++++++++----------------------------\n revision.h |    2 +\n 2 files changed, 87 insertions(+), 74 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex b588f74..db01682 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -592,6 +592,85 @@ static void prepare_show_merge(struct re\n \trevs->prune_data = prune;\n }\n \n+int handle_revision_arg(const char *arg, struct rev_info *revs,\n+\t\t\tint flags,\n+\t\t\tint cant_be_filename)\n+{\n+\tchar *dotdot;\n+\tstruct object *object;\n+\tunsigned char sha1[20];\n+\tint local_flags;\n+\n+\tdotdot = strstr(arg, \"..\");\n+\tif (dotdot) {\n+\t\tunsigned char from_sha1[20];\n+\t\tconst char *next = dotdot + 2;\n+\t\tconst char *this = arg;\n+\t\tint symmetric = *next == '.';\n+\t\tunsigned int flags_exclude = flags ^ UNINTERESTING;\n+\n+\t\t*dotdot = 0;\n+\t\tnext += symmetric;\n+\n+\t\tif (!*next)\n+\t\t\tnext = \"HEAD\";\n+\t\tif (dotdot == arg)\n+\t\t\tthis = \"HEAD\";\n+\t\tif (!get_sha1(this, from_sha1) &&\n+\t\t    !get_sha1(next, sha1)) {\n+\t\t\tstruct commit *a, *b;\n+\t\t\tstruct commit_list *exclude;\n+\n+\t\t\ta = lookup_commit_reference(from_sha1);\n+\t\t\tb = lookup_commit_reference(sha1);\n+\t\t\tif (!a || !b) {\n+\t\t\t\tdie(symmetric ?\n+\t\t\t\t    \"Invalid symmetric difference expression %s...%s\" :\n+\t\t\t\t    \"Invalid revision range %s..%s\",\n+\t\t\t\t    arg, next);\n+\t\t\t}\n+\n+\t\t\tif (!cant_be_filename) {\n+\t\t\t\t*dotdot = '.';\n+\t\t\t\tverify_non_filename(revs->prefix, arg);\n+\t\t\t}\n+\n+\t\t\tif (symmetric) {\n+\t\t\t\texclude = get_merge_bases(a, b, 1);\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} else\n+\t\t\t\ta->object.flags |= flags_exclude;\n+\t\t\tb->object.flags |= flags;\n+\t\t\tadd_pending_object(revs, &a->object, this);\n+\t\t\tadd_pending_object(revs, &b->object, next);\n+\t\t\treturn 0;\n+\t\t}\n+\t\t*dotdot = '.';\n+\t}\n+\tdotdot = strstr(arg, \"^@\");\n+\tif (dotdot && !dotdot[2]) {\n+\t\t*dotdot = 0;\n+\t\tif (add_parents_only(revs, arg, flags))\n+\t\t\treturn 0;\n+\t\t*dotdot = '^';\n+\t}\n+\tlocal_flags = 0;\n+\tif (*arg == '^') {\n+\t\tlocal_flags = UNINTERESTING;\n+\t\targ++;\n+\t}\n+\tif (get_sha1(arg, sha1))\n+\t\treturn -1;\n+\tif (!cant_be_filename)\n+\t\tverify_non_filename(revs->prefix, arg);\n+\tobject = get_reference(revs, arg, sha1, flags ^ local_flags);\n+\tadd_pending_object(revs, object, arg);\n+\treturn 0;\n+}\n+\n /*\n  * Parse revision information, filling in the \"rev_info\" structure,\n  * and removing the used arguments from the argument list.\n@@ -620,12 +699,7 @@ int setup_revisions(int argc, const char\n \n \tflags = show_merge = 0;\n \tfor (i = 1; i < argc; i++) {\n-\t\tstruct object *object;\n \t\tconst char *arg = argv[i];\n-\t\tunsigned char sha1[20];\n-\t\tchar *dotdot;\n-\t\tint local_flags;\n-\n \t\tif (*arg == '-') {\n \t\t\tint opts;\n \t\t\tif (!strncmp(arg, \"--max-count=\", 12)) {\n@@ -830,71 +904,10 @@ int setup_revisions(int argc, const char\n \t\t\tleft++;\n \t\t\tcontinue;\n \t\t}\n-\t\tdotdot = strstr(arg, \"..\");\n-\t\tif (dotdot) {\n-\t\t\tunsigned char from_sha1[20];\n-\t\t\tconst char *next = dotdot + 2;\n-\t\t\tconst char *this = arg;\n-\t\t\tint symmetric = *next == '.';\n-\t\t\tunsigned int flags_exclude = flags ^ UNINTERESTING;\n-\n-\t\t\t*dotdot = 0;\n-\t\t\tnext += symmetric;\n-\n-\t\t\tif (!*next)\n-\t\t\t\tnext = \"HEAD\";\n-\t\t\tif (dotdot == arg)\n-\t\t\t\tthis = \"HEAD\";\n-\t\t\tif (!get_sha1(this, from_sha1) &&\n-\t\t\t    !get_sha1(next, sha1)) {\n-\t\t\t\tstruct commit *a, *b;\n-\t\t\t\tstruct commit_list *exclude;\n-\n-\t\t\t\ta = lookup_commit_reference(from_sha1);\n-\t\t\t\tb = lookup_commit_reference(sha1);\n-\t\t\t\tif (!a || !b) {\n-\t\t\t\t\tdie(symmetric ?\n-\t\t\t\t\t    \"Invalid symmetric difference expression %s...%s\" :\n-\t\t\t\t\t    \"Invalid revision range %s..%s\",\n-\t\t\t\t\t    arg, next);\n-\t\t\t\t}\n-\n-\t\t\t\tif (!seen_dashdash) {\n-\t\t\t\t\t*dotdot = '.';\n-\t\t\t\t\tverify_non_filename(revs->prefix, arg);\n-\t\t\t\t}\n-\n-\t\t\t\tif (symmetric) {\n-\t\t\t\t\texclude = get_merge_bases(a, b, 1);\n-\t\t\t\t\tadd_pending_commit_list(revs, exclude,\n-\t\t\t\t\t                        flags_exclude);\n-\t\t\t\t\tfree_commit_list(exclude);\n-\t\t\t\t\ta->object.flags |= flags;\n-\t\t\t\t} else\n-\t\t\t\t\ta->object.flags |= flags_exclude;\n-\t\t\t\tb->object.flags |= flags;\n-\t\t\t\tadd_pending_object(revs, &a->object, this);\n-\t\t\t\tadd_pending_object(revs, &b->object, next);\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\t*dotdot = '.';\n-\t\t}\n-\t\tdotdot = strstr(arg, \"^@\");\n-\t\tif (dotdot && !dotdot[2]) {\n-\t\t\t*dotdot = 0;\n-\t\t\tif (add_parents_only(revs, arg, flags))\n-\t\t\t\tcontinue;\n-\t\t\t*dotdot = '^';\n-\t\t}\n-\t\tlocal_flags = 0;\n-\t\tif (*arg == '^') {\n-\t\t\tlocal_flags = UNINTERESTING;\n-\t\t\targ++;\n-\t\t}\n-\t\tif (get_sha1(arg, sha1)) {\n-\t\t\tint j;\n \n-\t\t\tif (seen_dashdash || local_flags)\n+\t\tif (handle_revision_arg(arg, revs, flags, seen_dashdash)) {\n+\t\t\tint j;\n+\t\t\tif (seen_dashdash || *arg == '^')\n \t\t\t\tdie(\"bad revision '%s'\", arg);\n \n \t\t\t/* If we didn't have a \"--\":\n@@ -906,14 +919,12 @@ int setup_revisions(int argc, const char\n \t\t\tfor (j = i; j < argc; j++)\n \t\t\t\tverify_filename(revs->prefix, argv[j]);\n \n-\t\t\trevs->prune_data = get_pathspec(revs->prefix, argv + i);\n+\t\t\trevs->prune_data = get_pathspec(revs->prefix,\n+\t\t\t\t\t\t\targv + i);\n \t\t\tbreak;\n \t\t}\n-\t\tif (!seen_dashdash)\n-\t\t\tverify_non_filename(revs->prefix, arg);\n-\t\tobject = get_reference(revs, arg, sha1, flags ^ local_flags);\n-\t\tadd_pending_object(revs, object, arg);\n \t}\n+\n \tif (show_merge)\n \t\tprepare_show_merge(revs);\n \tif (def && !revs->pending.nr) {\ndiff --git a/revision.h b/revision.h\nindex d289781..c1f71af 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -90,6 +90,8 @@ extern int rev_compare_tree(struct rev_i\n \n extern void init_revisions(struct rev_info *revs, const char *prefix);\n extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);\n+extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);\n+\n extern void prepare_revision_walk(struct rev_info *revs);\n extern struct commit *get_revision(struct rev_info *revs);\n \n-- \n1.4.2.g980c3\n"}]}