git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Michael J Gruber <git@drmicha.warpmail.net>
To: Junio C Hamano <gitster@pobox.com>, git@vger.kernel.org
Subject: Re: [PATCH 2/2] name-rev: favor describing with tags and use committer date to tiebreak
Date: Fri, 17 Mar 2017 12:25:01 +0100	[thread overview]
Message-ID: <ce5252a5-b94a-a389-6b3e-0e4d7b243210@drmicha.warpmail.net> (raw)
In-Reply-To: <20170315225045.15788-3-gitster@pobox.com>

> hops, without taking the "taggerdate" into account.  As we are
> taking over the "taggerdate" field to store the committer date for
> tips with commits:
> 
>  (1) keep the original logic when comparing names based on two refs
>      both of which are from refs/tags/;
> 
>  (2) favoring a name based on a ref in refs/tags/ hierarchy over
>      a ref outside the hierarchy;
> 
>  (3) between two names based on a ref both outside refs/tags/, give
>      precedence to a name with shorter hops and use "taggerdate"
>      only to tie-break.
> 
> A change to t4202 is a natural consequence.  The test creates a
> commit on a branch "side" and points at it with an unannotated tag
> "refs/tags/side-2".  The original code couldn't decide which one to
> favor at all, and gave a name based on a branch (simply because
> refs/heads/side sorts earlier than refs/tags/side-2).  Because the
> updated logic is taught to favor refs in refs/tags/ hierarchy, the
> the test is updated to expect to see tags/side-2 instead.
> 
> Signed-off-by: Junio C Hamano <gitster@pobox.com>

I think that strategy is fine and works as I expected in all tested
cases. Thanks!

> ---
> 
>  * I am sure others can add better heurisitics in is_better_name()
>    for comparing names based on non-tag refs, and I do not mind
>    people disagreeing with the logic that this patch happens to
>    implement.  This is done primarily to illustrate the value of
>    using a separate helper function is_better_name() instead of
>    open-coding the selection logic in name_rev() function.
> ---
>  builtin/name-rev.c | 57 +++++++++++++++++++++++++++++++++++++++++++++---------
>  t/t4202-log.sh     |  2 +-
>  2 files changed, 49 insertions(+), 10 deletions(-)
> 
> diff --git a/builtin/name-rev.c b/builtin/name-rev.c
> index f64c71d9bc..eac0180c62 100644
> --- a/builtin/name-rev.c
> +++ b/builtin/name-rev.c
> @@ -13,6 +13,7 @@ typedef struct rev_name {
>  	unsigned long taggerdate;
>  	int generation;
>  	int distance;
> +	int from_tag;
>  } rev_name;
>  
>  static long cutoff = LONG_MAX;
> @@ -24,16 +25,47 @@ static int is_better_name(struct rev_name *name,
>  			  const char *tip_name,
>  			  unsigned long taggerdate,
>  			  int generation,
> -			  int distance)
> +			  int distance,
> +			  int from_tag)
>  {
> -	return (name->taggerdate > taggerdate ||
> -		(name->taggerdate == taggerdate &&
> -		 name->distance > distance));
> +	/*
> +	 * When comparing names based on tags, prefer names
> +	 * based on the older tag, even if it is farther away.
> +	 */
> +	if (from_tag && name->from_tag)
> +		return (name->taggerdate > taggerdate ||
> +			(name->taggerdate == taggerdate &&
> +			 name->distance > distance));
> +
> +#define COMPARE(attribute, smaller_is_better)	 \
> +	if (name->attribute > attribute) \
> +		return smaller_is_better; \
> +	if (name->attribute < attribute) \
> +		return !smaller_is_better

I find that define pretty confusing. On first reading, the "==" case
seems to be missing, but that is basically "pass" as one can see in the
later code.

Also, the comparison ">"  and "<" is used to switch between the cases
"tag vs. non-tag" and "non-tag vs. tag" which happen to be encoded by
the from_tag attribute beeing "1 vs. 0" resp "0 vs. 1" in the following:

> +
> +	/*
> +	 * We know that at least one of them is a non-tag at this point.
> +	 * favor a tag over a non-tag.
> +	 */
> +	COMPARE(from_tag, 0);
> +

But in the next two instances you use it to do "actual" comparisons
between distances and dates:

> +	/*
> +	 * We are now looking at two non-tags.  Tiebreak to favor
> +	 * shorter hops.
> +	 */
> +	COMPARE(distance, 1);
> +
> +	/* ... or tiebreak to favor older date */
> +	COMPARE(taggerdate, 1);
> +
> +	/* keep the current one if we cannot decide */
> +	return 0;
> +#undef COMPARE
>  }

So, while I do understand that now, I'm wondering whether I will next
time ;)

How about something like

/* favor tag over non-tag */
if (name->from_tag != from_tag)
	return from_tag;

at least for the first instance and possibly

/* favor shorter hops for non-tags */
if (name->distance != distance)
	return name->distance > distance;

/* tie-break by date */
if (name->taggerdate != taggerdate)
	return name->taggerdate > taggerdate;

>  
>  static void name_rev(struct commit *commit,
>  		const char *tip_name, unsigned long taggerdate,
> -		int generation, int distance,
> +		int generation, int distance, int from_tag,
>  		int deref)
>  {
>  	struct rev_name *name = (struct rev_name *)commit->util;
> @@ -57,12 +89,13 @@ static void name_rev(struct commit *commit,
>  		commit->util = name;
>  		goto copy_data;
>  	} else if (is_better_name(name, tip_name, taggerdate,
> -				  generation, distance)) {
> +				  generation, distance, from_tag)) {
>  copy_data:
>  		name->tip_name = tip_name;
>  		name->taggerdate = taggerdate;
>  		name->generation = generation;
>  		name->distance = distance;
> +		name->from_tag = from_tag;
>  	} else
>  		return;
>  
> @@ -82,10 +115,12 @@ static void name_rev(struct commit *commit,
>  						   parent_number);
>  
>  			name_rev(parents->item, new_name, taggerdate, 0,
> -				distance + MERGE_TRAVERSAL_WEIGHT, 0);
> +				 distance + MERGE_TRAVERSAL_WEIGHT,
> +				 from_tag, 0);
>  		} else {
>  			name_rev(parents->item, tip_name, taggerdate,
> -				generation + 1, distance + 1, 0);
> +				 generation + 1, distance + 1,
> +				 from_tag, 0);
>  		}
>  	}
>  }
> @@ -184,9 +219,13 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
>  	}
>  	if (o && o->type == OBJ_COMMIT) {
>  		struct commit *commit = (struct commit *)o;
> +		int from_tag = starts_with(path, "refs/tags/");
>  
> +		if (taggerdate == ULONG_MAX)
> +			taggerdate = ((struct commit *)o)->date;
>  		path = name_ref_abbrev(path, can_abbreviate_output);
> -		name_rev(commit, xstrdup(path), taggerdate, 0, 0, deref);
> +		name_rev(commit, xstrdup(path), taggerdate, 0, 0,
> +			 from_tag, deref);
>  	}
>  	return 0;
>  }
> diff --git a/t/t4202-log.sh b/t/t4202-log.sh
> index 48b55bfd27..038911f230 100755
> --- a/t/t4202-log.sh
> +++ b/t/t4202-log.sh
> @@ -398,7 +398,7 @@ cat > expect <<\EOF
>  | |
>  | |     Merge branch 'side'
>  | |
> -| * commit side
> +| * commit tags/side-2
>  | | Author: A U Thor <author@example.com>
>  | |
>  | |     side-2
> 

  parent reply	other threads:[~2017-03-17 11:31 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-15 13:15 [PATCH 0/3] describe --contains sanity Michael J Gruber
2017-03-15 13:15 ` [PATCH 1/3] describe: debug is incompatible with contains Michael J Gruber
2017-03-15 19:21   ` Junio C Hamano
2017-03-17 10:54     ` Michael J Gruber
2017-03-15 13:15 ` [PATCH 2/3] git-prompt: add a describe style for any tags Michael J Gruber
2017-03-15 19:25   ` Junio C Hamano
2017-03-17 10:56     ` Michael J Gruber
2017-03-15 13:15 ` [RFD PATCH 3/3] name-rev: Allow lightweight tags and branch refs Michael J Gruber
2017-03-15 16:14   ` Junio C Hamano
2017-03-15 19:50   ` Junio C Hamano
2017-03-15 20:51     ` Junio C Hamano
2017-03-15 22:50       ` [PATCH 0/2] Teach name-rev to pay more attention to lightweight tags Junio C Hamano
2017-03-15 22:50         ` [PATCH 1/2] name-rev: refactor logic to see if a new candidate is a better name Junio C Hamano
2017-03-15 22:50         ` [PATCH 2/2] name-rev: favor describing with tags and use committer date to tiebreak Junio C Hamano
2017-03-17  4:07           ` Lars Schneider
2017-03-17  5:45             ` Junio C Hamano
2017-03-17  5:56               ` Junio C Hamano
2017-03-17 17:09                 ` Lars Schneider
2017-03-17 17:17                   ` Junio C Hamano
2017-03-17 22:43                     ` Junio C Hamano
2017-03-29 14:39                       ` [PATCH v2 0/3] name-rev sanity Michael J Gruber
2017-03-29 14:39                         ` [PATCH v2 1/3] name-rev: refactor logic to see if a new candidate is a better name Michael J Gruber
2017-03-29 14:39                         ` [PATCH v2 2/3] name-rev: favor describing with tags and use committer date to tiebreak Michael J Gruber
2017-03-29 14:39                         ` [PATCH v2 3/3] name-rev: provide debug output Michael J Gruber
2017-03-29 17:15                         ` [PATCH v2 0/3] name-rev sanity Junio C Hamano
2017-03-29 17:43                           ` Junio C Hamano
2017-03-30 13:48                             ` Michael J Gruber
2017-03-30 17:30                               ` Junio C Hamano
2017-03-31 13:51                                 ` [PATCH v3 0/4] " Michael J Gruber
2017-03-31 13:51                                   ` [PATCH v3 1/4] name-rev: refactor logic to see if a new candidate is a better name Michael J Gruber
2017-03-31 13:51                                   ` [PATCH v3 2/4] name-rev: favor describing with tags and use committer date to tiebreak Michael J Gruber
2017-03-31 13:51                                   ` [PATCH v3 3/4] name-rev: provide debug output Michael J Gruber
2017-03-31 16:52                                     ` Junio C Hamano
2017-03-31 16:55                                       ` Junio C Hamano
2017-03-31 18:02                                       ` Michael J Gruber
2017-03-31 18:06                                         ` Junio C Hamano
2017-03-31 18:33                                           ` Junio C Hamano
2017-04-03 14:46                                             ` Michael J Gruber
2017-04-03 17:07                                               ` Junio C Hamano
2017-05-20  5:19                                               ` Junio C Hamano
2017-03-31 19:10                                         ` Junio C Hamano
2017-03-31 13:51                                   ` [PATCH v3 4/4] describe: pass --debug down to name-rev Michael J Gruber
2017-03-17 11:25           ` Michael J Gruber [this message]
2017-03-17 16:03             ` [PATCH 2/2] name-rev: favor describing with tags and use committer date to tiebreak Junio C Hamano
2017-03-16  0:14         ` [PATCH 0/2] Teach name-rev to pay more attention to lightweight tags Stefan Beller
2017-03-16 10:28         ` Jacob Keller

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=ce5252a5-b94a-a389-6b3e-0e4d7b243210@drmicha.warpmail.net \
    --to=git@drmicha.warpmail.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /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).