git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2] log: add log.excludeDecoration config option

From
Derrick Stolee <stolee@gmail.com>
Date
Apr 16, 2020, 12:46 UTC
Message-ID
<a8380ed7-d3a1-873d-7f65-099fd55a3988@gmail.com>
In-Reply-To
<xmqqftd47jce.fsf@gitster.c.googlers.com>
On 4/15/2020 1:24 PM, Junio C Hamano wrote:
Show 34 quoted lines
> "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com> writes:
> 
>> Add the 'log.excludeDecoration' config option so users can exclude
>> some refs from decorations by default instead of needing to use
>> --decorate-refs-exclude manually. The config value is multi-valued
>> much like the command-line option. The documentation is careful to
>> point out that the config value can be overridden by the
>> --decorate-refs option, even though --decorate-refs-exclude would
>> always "win" over --decorate-refs.
>>
>> Since the 'log.excludeDecoration' takes lower precedence to
>> --decorate-refs, and --decorate-refs-exclude takes higher
>> precedence, the struct decoration_filter needed another field.
>> This led also to new logic in load_ref_decorations() and
>> ref_filter_match().
> 
> All of the above makes sense to me.
> 
>> diff --git a/Documentation/config/log.txt b/Documentation/config/log.txt
>> index e9e1e397f3f..1a158324f79 100644
>> --- a/Documentation/config/log.txt
>> +++ b/Documentation/config/log.txt
>> @@ -18,6 +18,11 @@ log.decorate::
>>  	names are shown. This is the same as the `--decorate` option
>>  	of the `git log`.
>>  
>> +log.excludeDecoration::
>> +	Exclude the specified patterns from the log decorations. This multi-
>> +	valued config option is the same as the `--decorate-refs-exclude`
>> +	option of `git log`.
> 
> Can the config still be "the same as" that option, though, with the
> new "unlike --decorate-refs-exclude that always wins, config is at
> the lowest precedence" rule?

I thought I had updated this to make that clearer, but it looks like I missed it when staging.

What I had meant to write was this:
log.excludeDecoration::
	Exclude the specified patterns from the log decorations. This is
	similar to the `--decorate-refs-exclude` command-line option, but
	the config option can be overridden by the `--decorate-refs`
	option.
Show 26 quoted lines
>> diff --git a/log-tree.c b/log-tree.c
>> index 52127427ffe..bd8d4c07bb8 100644
>> --- a/log-tree.c
>> +++ b/log-tree.c
>> @@ -90,7 +90,8 @@ static int add_ref_decoration(const char *refname, const struct object_id *oid,
>>  
>>  	if (filter && !ref_filter_match(refname,
>>  			      filter->include_ref_pattern,
>> -			      filter->exclude_ref_pattern))
>> +			      filter->exclude_ref_pattern,
>> +			      filter->exclude_ref_config_pattern))
>>  		return 0;
> 
> As there is only one caller of the ref_filter_match() helper, I
> wonder if we want to
> 
>  (1) move the helper to log-tree.c, make it static and remove its
>      definition from refs.h, and optionally rename it so that it is
>      clear that this is not part of the "ref_filter" API that drives
>      "for-each-ref" and friends;
> 
>  (2) instead of adding yet another pattern to the parameter list,
>      make the helper take the whole "filter" instance as a single
>      parameter.
> 
> as a clean-up.

This is a good idea. I was thinking the code was "smelly" when I had to jump through so many hoops to get it working. I'll add a refactor patch in front of this one.

Show 40 quoted lines
>> diff --git a/refs.c b/refs.c
>> index 1ab0bb54d3d..63d8b569333 100644
>> --- a/refs.c
>> +++ b/refs.c
>> @@ -339,9 +339,11 @@ static int match_ref_pattern(const char *refname,
>>  
>>  int ref_filter_match(const char *refname,
>>  		     const struct string_list *include_patterns,
>> -		     const struct string_list *exclude_patterns)
>> +		     const struct string_list *exclude_patterns,
>> +		     const struct string_list *exclude_patterns_config)
>>  {
>>  	struct string_list_item *item;
>> +	int found = 0;
>>  
>>  	if (exclude_patterns && exclude_patterns->nr) {
>>  		for_each_string_list_item(item, exclude_patterns) {
>> @@ -351,7 +353,6 @@ int ref_filter_match(const char *refname,
>>  	}
>>  
>>  	if (include_patterns && include_patterns->nr) {
>> -		int found = 0;
>>  		for_each_string_list_item(item, include_patterns) {
>>  			if (match_ref_pattern(refname, item)) {
>>  				found = 1;
>> @@ -362,6 +363,16 @@ int ref_filter_match(const char *refname,
>>  		if (!found)
>>  			return 0;
>>  	}
>> +
>> +	if (!found &&
>> +	    exclude_patterns_config &&
>> +	    exclude_patterns_config->nr) {
>> +		for_each_string_list_item(item, exclude_patterns_config) {
>> +			if (match_ref_pattern(refname, item))
>> +				return 0;
>> +		}
>> +	}
> 
> Hmph.  Do we still need "found" here? ...

You included an excellent update in another response, which I have squashed locally.

Show 23 quoted lines
>>  /*
>> + * Returns 0 if the refname matches any of the exclude_patterns.
>> + *
>> + * Returns 0 if include_patterns is non-empty but refname does not match
>> + * any of those patterns.
>> + *
>> + * Returns 0 if refname matches a pattern in exclude_patterns_config but
>> + * does not match any pattern in inclue_patterns.
>> + *
>> + * Otherwise, returns 1.
>>   *
>>   * This has the effect of matching everything by default, unless the user
>>   * specifies rules otherwise.
>>   */
> 
> The above is not wrong per-se, but feels somewhat roundabout way to
> define what it does, from the viewpoint of somebody who may want to
> call or understand it.  "What matches one of the exclude patterns is
> excluded.  If the include patterns is empty, what did not match
> exclude patterns is included unless it matches one of the exclude
> configs.  But if the include patterns is not empty, what did not
> match exclude patterns is included only if it matches one of the
> include patterns."
Your new logic for the method makes this a bit simpler to write:
/*
 * Returns 0 if the refname matches any of the exclude_patterns.
 *
 * Otherwise, returns 1 if the refname matches any of the include_patterns.
 *
 * Otherwise, returns 0 if include_patterns is non-empty.
 *
 * Otherwise, returns 0 if the refname matches any of the patterns
 * in exclude_patterns_config.
 *
 * Finally, if none of the above apply, return 1.
 */

However, if I pull this method into a static helper method, then the documentation is unnecessary.

Thanks for the careful review!
-Stolee
Previous: Derrick StoleeNext: Derrick Stolee via GitGitGadget
Message 15 of 22 in “log: add log.excludeDecoration config option”
  1. log: add log.excludeDecoration config optionDerrick Stolee via GitGitGadget, Apr 13, 2020
  2. Taylor BlauApr 13, 2020
  3. Derrick StoleeApr 14, 2020
  4. Taylor BlauApr 14, 2020
  5. Derrick StoleeApr 14, 2020
  6. Junio C HamanoApr 14, 2020
  7. Derrick StoleeApr 14, 2020
  8. Junio C HamanoApr 14, 2020
  9. Derrick StoleeApr 15, 2020
  10. log: add log.excludeDecoration config optionDerrick Stolee via GitGitGadget, Apr 15, 2020
  11. Taylor BlauApr 15, 2020
  12. Junio C HamanoApr 15, 2020
  13. Junio C HamanoApr 15, 2020
  14. Derrick StoleeApr 16, 2020
  15. Derrick StoleeApr 16, 2020
  16. 0/2 log: add log.excludeDecoration config optionDerrick Stolee via GitGitGadget, Apr 16, 2020
  17. 2/2 log: add log.excludeDecoration config optionDerrick Stolee via GitGitGadget, Apr 16, 2020
  18. Junio C HamanoApr 16, 2020
  19. Junio C HamanoApr 16, 2020
  20. Derrick StoleeApr 17, 2020
  21. Junio C HamanoApr 17, 2020
  22. 1/2 log-tree: make ref_filter_match() a helper methodDerrick Stolee via GitGitGadget, Apr 16, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.