All of lore.kernel.org
 help / color / mirror / 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

* 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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.