From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: "Johannes Schindelin" <johannes.schindelin@gmx.de>,
git@vger.kernel.org, "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: Re: [PATCH 05/15] handle_revision_arg: add handle_dotdot() helper
Date: Wed, 24 May 2017 11:30:07 +0900 [thread overview]
Message-ID: <xmqqinkrhtqo.fsf@gitster.mtv.corp.google.com> (raw)
In-Reply-To: <20170519125200.mtpchnyg26re5u4h@sigill.intra.peff.net> (Jeff King's message of "Fri, 19 May 2017 08:52:00 -0400")
Jeff King <peff@peff.net> writes:
> The handle_revision_arg function is rather long, and a big
> chunk of it is handling the range operators. Let's pull that
> out to a separate helper. While we're doing so, we can clean
> up a few of the rough edges that made the flow hard to
> follow:
>
> - instead of manually restoring *dotdot (that we overwrote
> with a NUL), do the real work in a sub-helper, which
> makes it clear that the munge/restore lines are a
> matched pair
>
> - eliminate a goto which wasn't actually used for control
> flow, but only to avoid duplicating a few lines
> (instead, those lines are pushed into another helper
> function)
>
> - use early returns instead of deep nesting
>
> - consistently name all variables for the left-hand side
> of the range as "a" (rather than "this" or "from") and
> the right-hand side as "b" (rather than "next", or using
> the unadorned "sha1" or "flags" from the main function).
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> revision.c | 177 +++++++++++++++++++++++++++++++++++--------------------------
> 1 file changed, 102 insertions(+), 75 deletions(-)
Nicely done. Together with [PATCH 04/15] the resulting code wrt ".."
is much easier to follow.
> diff --git a/revision.c b/revision.c
> index dec06ff8b..eb45501fd 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -1429,10 +1429,109 @@ static void prepare_show_merge(struct rev_info *revs)
> revs->limited = 1;
> }
>
> +static int dotdot_missing(const char *arg, char *dotdot,
> + struct rev_info *revs, int symmetric)
> +{
> + if (revs->ignore_missing)
> + return 0;
> + /* de-munge so we report the full argument */
> + *dotdot = '.';
> + die(symmetric
> + ? "Invalid symmetric difference expression %s"
> + : "Invalid revision range %s", arg);
> +}
> +
> +static int handle_dotdot_1(const char *arg, char *dotdot,
> + struct rev_info *revs, int flags,
> + int cant_be_filename)
> +{
> + const char *a_name, *b_name;
> + struct object_id a_oid, b_oid;
> + struct object *a_obj, *b_obj;
> + unsigned int a_flags, b_flags;
> + int symmetric = 0;
> + unsigned int flags_exclude = flags ^ (UNINTERESTING | BOTTOM);
> +
> + a_name = arg;
> + if (!*a_name)
> + a_name = "HEAD";
> +
> + b_name = dotdot + 2;
> + if (*b_name == '.') {
> + symmetric = 1;
> + b_name++;
> + }
> + if (!*b_name)
> + b_name = "HEAD";
> +
> + if (get_sha1_committish(a_name, a_oid.hash) ||
> + get_sha1_committish(b_name, b_oid.hash))
> + return -1;
> +
> + if (!cant_be_filename) {
> + *dotdot = '.';
> + verify_non_filename(revs->prefix, arg);
> + *dotdot = '\0';
> + }
> +
> + a_obj = parse_object(a_oid.hash);
> + b_obj = parse_object(b_oid.hash);
> + if (!a_obj || !b_obj)
> + return dotdot_missing(arg, dotdot, revs, symmetric);
> +
> + if (!symmetric) {
> + /* just A..B */
> + b_flags = flags;
> + a_flags = flags_exclude;
> + } else {
> + /* A...B -- find merge bases between the two */
> + struct commit *a, *b;
> + struct commit_list *exclude;
> +
> + a = lookup_commit_reference(a_obj->oid.hash);
> + b = lookup_commit_reference(b_obj->oid.hash);
> + if (!a || !b)
> + return dotdot_missing(arg, dotdot, revs, symmetric);
> +
> + exclude = get_merge_bases(a, b);
> + add_rev_cmdline_list(revs, exclude, REV_CMD_MERGE_BASE,
> + flags_exclude);
> + add_pending_commit_list(revs, exclude, flags_exclude);
> + free_commit_list(exclude);
> +
> + b_flags = flags;
> + a_flags = flags | SYMMETRIC_LEFT;
> + }
> +
> + a_obj->flags |= a_flags;
> + b_obj->flags |= b_flags;
> + add_rev_cmdline(revs, a_obj, a_name, REV_CMD_LEFT, a_flags);
> + add_rev_cmdline(revs, b_obj, b_name, REV_CMD_RIGHT, b_flags);
> + add_pending_object(revs, a_obj, a_name);
> + add_pending_object(revs, b_obj, b_name);
> + return 0;
> +}
> +
> +static int handle_dotdot(const char *arg,
> + struct rev_info *revs, int flags,
> + int cant_be_filename)
> +{
> + char *dotdot = strstr(arg, "..");
> + int ret;
> +
> + if (!dotdot)
> + return -1;
> +
> + *dotdot = '\0';
> + ret = handle_dotdot_1(arg, dotdot, revs, flags, cant_be_filename);
> + *dotdot = '.';
> +
> + return ret;
> +}
> +
> int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt)
> {
> struct object_context oc;
> - char *dotdot;
> char *mark;
> struct object *object;
> unsigned char sha1[20];
> @@ -1451,80 +1550,8 @@ int handle_revision_arg(const char *arg_, struct rev_info *revs, int flags, unsi
> return -1;
> }
>
> - dotdot = strstr(arg, "..");
> - if (dotdot) {
> - unsigned char from_sha1[20];
> - const char *next = dotdot + 2;
> - const char *this = arg;
> - int symmetric = *next == '.';
> - unsigned int flags_exclude = flags ^ (UNINTERESTING | BOTTOM);
> - unsigned int a_flags;
> -
> - *dotdot = 0;
> - next += symmetric;
> -
> - if (!*next)
> - next = "HEAD";
> - if (dotdot == arg)
> - this = "HEAD";
> - if (!get_sha1_committish(this, from_sha1) &&
> - !get_sha1_committish(next, sha1)) {
> - struct object *a_obj, *b_obj;
> -
> - if (!cant_be_filename) {
> - *dotdot = '.';
> - verify_non_filename(revs->prefix, arg);
> - *dotdot = '\0';
> - }
> -
> - a_obj = parse_object(from_sha1);
> - b_obj = parse_object(sha1);
> - if (!a_obj || !b_obj) {
> - missing:
> - *dotdot = '.';
> - if (revs->ignore_missing)
> - return 0;
> - die(symmetric
> - ? "Invalid symmetric difference expression %s"
> - : "Invalid revision range %s", arg);
> - }
> -
> - if (!symmetric) {
> - /* just A..B */
> - a_flags = flags_exclude;
> - } else {
> - /* A...B -- find merge bases between the two */
> - struct commit *a, *b;
> - struct commit_list *exclude;
> -
> - a = lookup_commit_reference(a_obj->oid.hash);
> - b = lookup_commit_reference(b_obj->oid.hash);
> - if (!a || !b)
> - goto missing;
> - exclude = get_merge_bases(a, b);
> - add_rev_cmdline_list(revs, exclude,
> - REV_CMD_MERGE_BASE,
> - flags_exclude);
> - add_pending_commit_list(revs, exclude,
> - flags_exclude);
> - free_commit_list(exclude);
> -
> - a_flags = flags | SYMMETRIC_LEFT;
> - }
> -
> - a_obj->flags |= a_flags;
> - b_obj->flags |= flags;
> - add_rev_cmdline(revs, a_obj, this,
> - REV_CMD_LEFT, a_flags);
> - add_rev_cmdline(revs, b_obj, next,
> - REV_CMD_RIGHT, flags);
> - add_pending_object(revs, a_obj, this);
> - add_pending_object(revs, b_obj, next);
> - *dotdot = '.';
> - return 0;
> - }
> - *dotdot = '.';
> - }
> + if (!handle_dotdot(arg, revs, flags, revarg_opt))
> + return 0;
>
> mark = strstr(arg, "^@");
> if (mark && !mark[2]) {
next prev parent reply other threads:[~2017-05-24 2:30 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-15 15:23 [PATCH 0/2] Demonstrate and partially work around a gitattributes problem Johannes Schindelin
2017-05-15 15:23 ` [PATCH 1/2] gitattributes: demonstrate that Git tries to read a bogus file Johannes Schindelin
2017-05-15 15:24 ` [PATCH 2/2] mingw: Suppress warning that <commit>:.gitattributes does not exist Johannes Schindelin
2017-05-16 7:54 ` [PATCH 0/2] Demonstrate and partially work around a gitattributes problem Jeff King
2017-05-16 8:10 ` Jeff King
2017-05-17 1:38 ` Junio C Hamano
2017-05-17 2:05 ` Jeff King
2017-05-18 19:23 ` Johannes Schindelin
2017-05-19 0:00 ` Jeff King
2017-05-19 12:46 ` [PATCH 0/15] retain blob info for git diff HEAD:foo HEAD:bar Jeff King
2017-05-19 12:48 ` [PATCH 01/15] handle_revision_arg: reset "dotdot" consistently Jeff King
2017-05-20 14:56 ` Philip Oakley
2017-05-23 19:51 ` Jeff King
2017-05-23 23:47 ` Philip Oakley
2017-05-19 12:48 ` [PATCH 02/15] handle_revision_arg: simplify commit reference lookups Jeff King
2017-05-19 12:50 ` [PATCH 03/15] handle_revision_arg: stop using "dotdot" as a generic pointer Jeff King
2017-05-24 2:45 ` Junio C Hamano
2017-05-24 9:55 ` Jeff King
2017-05-19 12:51 ` [PATCH 04/15] handle_revision_arg: hoist ".." check out of range parsing Jeff King
2017-05-19 12:52 ` [PATCH 05/15] handle_revision_arg: add handle_dotdot() helper Jeff King
2017-05-24 2:30 ` Junio C Hamano [this message]
2017-05-19 12:52 ` [PATCH 06/15] sha1_name: consistently refer to object_context as "oc" Jeff King
2017-05-19 12:52 ` [PATCH 07/15] get_sha1_with_context: always initialize oc->symlink_path Jeff King
2017-05-19 12:54 ` [PATCH 08/15] get_sha1_with_context: dynamically allocate oc->path Jeff King
2017-05-19 12:54 ` [PATCH 09/15] t4063: add tests of direct blob diffs Jeff King
2017-05-19 12:55 ` [PATCH 10/15] handle_revision_arg: record modes for "a..b" endpoints Jeff King
2017-05-19 12:55 ` [PATCH 11/15] handle_revision_arg: record paths for pending objects Jeff King
2017-05-19 12:57 ` [PATCH 12/15] diff: pass whole pending entry in blobinfo Jeff King
2017-05-19 12:58 ` [PATCH 13/15] diff: use the word "path" instead of "name" for blobs Jeff King
2017-05-19 12:59 ` [PATCH 14/15] diff: use pending "path" if it is available Jeff King
2017-05-19 12:59 ` [PATCH 15/15] diff: use blob path for blob/file diffs Jeff King
2017-05-24 2:44 ` [PATCH 0/15] retain blob info for git diff HEAD:foo HEAD:bar Junio C Hamano
2017-05-24 9:57 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqinkrhtqo.fsf@gitster.mtv.corp.google.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=johannes.schindelin@gmx.de \
--cc=pclouds@gmail.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).