Subject: [PATCH v3 0/2] log: add log.excludeDecoration config option

From: "Derrick Stolee via GitGitGadget" <[email-masked]>
Date: Thu, 16 Apr 2020 14:15:47 +0000

This was something hinted at in the "fetch" step of the background
maintenance RFC. Should be a relatively minor addition to our config
options.

We definitely want this feature for microsoft/git (we would set
log.excludeDecoration=refs/scalar/* in all Scalar repos), but we will wait
for feedback from the community.

Updates in v2:

 * Use for_each_string_list_item()

 * Update the matching logic to allow --decorate-refs to override the config
   option.

Updates in v3:

 * Moved and refactored the ref_filter_match() in a preparation patch.

 * Used Junio's new logic in ref_filter_match()

 * Updated the config documentation to be more clear.

Thanks, -Stolee

Derrick Stolee (2):
  log-tree: make ref_filter_match() a helper method
  log: add log.excludeDecoration config option

 Documentation/config/log.txt |  6 ++++
 Documentation/git-log.txt    |  5 +++-
 builtin/log.c                | 16 +++++++++-
 log-tree.c                   | 58 ++++++++++++++++++++++++++++++++++--
 log-tree.h                   |  4 ++-
 refs.c                       | 44 ---------------------------
 refs.h                       | 12 --------
 t/t4202-log.sh               | 51 ++++++++++++++++++++++++++++++-
 8 files changed, 133 insertions(+), 63 deletions(-)

base-commit: 274b9cc25322d9ee79aa8e6d4e86f0ffe5ced925
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-610%2Fderrickstolee%2Flog-exclude-decoration-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-610/derrickstolee/log-exclude-decoration-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/610

Range-diff vs v2:

 -:  ----------- > 1:  6840f8801e4 log-tree: make ref_filter_match() a helper method
 1:  cbdaef4a8e1 ! 2:  96c865e9214 log: add log.excludeDecoration config option
     @@ Commit message
          [1] https://github.com/microsoft/scalar
          [2] https://lore.kernel.org/git/77b1[email-masked]/
      
     +    Helped-by: Junio C Hamano <[email-masked]>
          Signed-off-by: Derrick Stolee <[email-masked]>
      
       ## Documentation/config/log.txt ##
     @@ Documentation/config/log.txt: log.decorate::
       	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`.
     ++	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.
      +
       log.follow::
       	If `true`, `git log` will act as if the `--follow` option was used when
     @@ builtin/log.c: static void cmd_log_init_finish(int argc, const char **argv, cons

       ## log-tree.c ##
     -@@ log-tree.c: static int add_ref_decoration(const char *refname, const struct object_id *oid,
     +@@ log-tree.c: static int ref_filter_match(const char *refname,
     + 	struct string_list_item *item;
     + 	const struct string_list *exclude_patterns = filter->exclude_ref_pattern;
     + 	const struct string_list *include_patterns = filter->include_ref_pattern;
     ++	const struct string_list *exclude_patterns_config =
     ++				filter->exclude_ref_config_pattern;
     + 
     + 	if (exclude_patterns && exclude_patterns->nr) {
     + 		for_each_string_list_item(item, exclude_patterns) {
     +@@ log-tree.c: static 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;
     +-				break;
     ++				return 1;
     + 			}
     + 		}
     ++		return 0;
     ++	}
       
     - 	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;
     +-		if (!found)
     +-			return 0;
     ++	if (exclude_patterns_config && exclude_patterns_config->nr) {
     ++		for_each_string_list_item(item, exclude_patterns_config) {
     ++			if (match_ref_pattern(refname, item))
     ++				return 0;
     ++		}
     + 	}
     ++
     + 	return 1;
     + }
       
     - 	if (starts_with(refname, git_replace_ref_base)) {
      @@ log-tree.c: void load_ref_decorations(struct decoration_filter *filter, int flags)
       			for_each_string_list_item(item, filter->include_ref_pattern) {
       				normalize_glob_ref(item, NULL, item->string);
     @@ log-tree.h: struct log_info {
       
       int parse_decorate_color_config(const char *var, const char *slot_name, const char *value);
      
     - ## refs.c ##
     -@@ refs.c: 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) {
     -@@ refs.c: 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;
     -@@ refs.c: 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;
     -+		}
     -+	}
     -+
     - 	return 1;
     - }
     - 
     -
     - ## refs.h ##
     -@@ refs.h: void normalize_glob_ref(struct string_list_item *item, const char *prefix,
     - 			const char *pattern);
     - 
     - /*
     -- * Returns 0 if refname matches any of the exclude_patterns, or if it doesn't
     -- * match any of the include_patterns. Returns 1 otherwise.
     -+ * 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.
     -  *
     -- * If pattern list is NULL or empty, matching against that list is skipped.
     -  * This has the effect of matching everything by default, unless the user
     -  * specifies rules otherwise.
     -  */
     - 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);
     - 
     - static inline const char *has_glob_specials(const char *pattern)
     - {
     -
       ## t/t4202-log.sh ##
      @@ t/t4202-log.sh: test_expect_success 'decorate-refs with glob' '
       	octopus-a (octopus-a)

-- 
gitgitgadget