git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, me@ttaylorr.com, vdye@github.com,
	steadmon@google.com, Derrick Stolee <derrickstolee@github.com>,
	Derrick Stolee <derrickstolee@github.com>
Subject: [PATCH 2/3] log: add default decoration filter
Date: Tue, 26 Jul 2022 14:04:09 +0000	[thread overview]
Message-ID: <6b40b84773c70244bb13204ec566b713f1bdf865.1658844250.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1301.git.1658844250.gitgitgadget@gmail.com>

From: Derrick Stolee <derrickstolee@github.com>

When a user runs 'git log', they expect a certain set of helpful
decorations. This includes:

* The HEAD ref
* Branches (refs/heads/)
* Notes (refs/notes/)
* Stashes (refs/stash/)
* Tags (refs/tags/)
* Remote branches (refs/remotes/)

However, there are other refs that are less helpful to show as
decoration:

* Prefetch refs (refs/prefetch/)
* Rebase refs (refs/rebase-merge/ and refs/rebase-apply/)
* Bundle refs (refs/bundle/) [!]

In the case of prefetch refs, 96eaffebbf3d0 (maintenance: set
log.excludeDecoration durin prefetch, 2021-01-19) added logic to add
refs/prefetch/ to the log.excludeDecoration config option. Additional
feedback pointed out that having such a side-effect can be confusing and
perhaps not helpful to users. Instead, we should hide these ref
namespaces that are being used by Git for internal reasons but are not
helpful for the users to see.

The way to provide a seamless user experience without setting the config
is to modify the default decoration filters to match our expectation of
what refs the user actually wants to see.

In builtin/log.c, after parsing the --decorate-refs and
--decorate-refs-exclude options from the command-line, call
set_default_decoration_filter(). This method populates the exclusions
from log.excludeDecoration, then checks if the list of pattern
modifications are empty. If none are specified, then the default set is
restricted to the set of inclusions mentioned earlier (HEAD, branches,
etc.).

Note that the logic in ref_filter_match() in log-tree.c follows this
matching pattern:

 1. If there are exclusion patterns and the ref matches one, then ignore
    the decoration.

 2. If there are inclusion patterns and the ref matches one, then
    definitely include the decoration.

 3. If there are config-based exclusions from log.excludeDecoration and
    the ref matches one, then ignore the decoration.

With this logic in mind, we need to ensure that we do not populate our
new defaults if any of these filters are manually set. Specifically, if
a user runs

	git -c log.excludeDecoration=HEAD log

then we expect the HEAD decoration to not appear. If we left the default
inclusions in the set, then HEAD would match that inclusion before
reaching the config-based exclusions.

A potential alternative would be to check the list of default inclusions
at the end, after the config-based exclusions. This would still create a
behavior change for some uses of --decorate-refs-exclude=<X>, and could
be overwritten somewhat with --decorate-refs=refs/ and
--decorate-refs=HEAD. However, it no longer becomes possible to include
refs outside of the defaults while also excluding some using
log.excludeDecoration.

Add a test that checks that the defaults are not added when
--decorate-refs is specified. We verify this by showing that HEAD is not
included as it normally would.  Also add a test that shows that the
default filter avoids the unwanted decorations from refs/prefetch,
refs/rebase-merge,
and refs/bundle.

There are several tests throughout the codebase that verify that
--decorate-refs, --decorate-refs-exclude, and log.excludeDecoration work
as designed and the tests continue to pass without intervention.

[!] The bundle refs are part of a parallel series that bootstraps a repo
from a bundle file, storing the bundle's refs into the repo's
refs/bundle/ namespace.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
---
 Documentation/git-log.txt |  7 ++++--
 builtin/log.c             | 53 +++++++++++++++++++++++++++++----------
 t/t4202-log.sh            | 23 +++++++++++++++++
 3 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index 20e87cecf49..14b67f3d058 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -45,13 +45,16 @@ OPTIONS
 
 --decorate-refs=<pattern>::
 --decorate-refs-exclude=<pattern>::
-	If no `--decorate-refs` is given, pretend as if all refs were
-	included.  For each candidate, do not use it for decoration if it
+	For each candidate reference, do not use it for decoration if it
 	matches any patterns given to `--decorate-refs-exclude` or if it
 	doesn't match any of the patterns given to `--decorate-refs`. The
 	`log.excludeDecoration` config option allows excluding refs from
 	the decorations, but an explicit `--decorate-refs` pattern will
 	override a match in `log.excludeDecoration`.
++
+If none of these options or config settings are given, then references are
+used as decoration if they match `HEAD`, `refs/heads/`, `refs/notes/`,
+`refs/remotes/`, `refs/stash/`, or `refs/tags/`.
 
 --source::
 	Print out the ref name given on the command line by which each
diff --git a/builtin/log.c b/builtin/log.c
index 88a5e98875a..dca06612b8e 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -162,6 +162,40 @@ static void cmd_log_init_defaults(struct rev_info *rev)
 		parse_date_format(default_date_mode, &rev->date_mode);
 }
 
+static void set_default_decoration_filter(struct decoration_filter *decoration_filter)
+{
+	const struct string_list *config_exclude =
+		repo_config_get_value_multi(the_repository, "log.excludeDecoration");
+
+	if (config_exclude) {
+		struct string_list_item *item;
+		for_each_string_list_item(item, config_exclude)
+			string_list_append(decoration_filter->exclude_ref_config_pattern,
+					   item->string);
+	}
+
+	if (!decoration_filter->exclude_ref_pattern->nr &&
+	    !decoration_filter->include_ref_pattern->nr &&
+	    !decoration_filter->exclude_ref_config_pattern->nr) {
+		/*
+		 * No command-line or config options were given, so
+		 * populate with sensible defaults.
+		 */
+		string_list_append(decoration_filter->include_ref_pattern,
+				   "refs/heads/");
+		string_list_append(decoration_filter->include_ref_pattern,
+				   "refs/notes/");
+		string_list_append(decoration_filter->include_ref_pattern,
+				   "refs/stash/");
+		string_list_append(decoration_filter->include_ref_pattern,
+				   "refs/tags/");
+		string_list_append(decoration_filter->include_ref_pattern,
+				   "refs/remotes/");
+		string_list_append(decoration_filter->include_ref_pattern,
+				   "HEAD");
+	}
+}
+
 static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 			 struct rev_info *rev, struct setup_revision_opt *opt)
 {
@@ -171,9 +205,11 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 	static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP;
 	static struct string_list decorate_refs_exclude_config = STRING_LIST_INIT_NODUP;
 	static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP;
-	struct decoration_filter decoration_filter = {&decorate_refs_include,
-						      &decorate_refs_exclude,
-						      &decorate_refs_exclude_config};
+	struct decoration_filter decoration_filter = {
+		.exclude_ref_pattern = &decorate_refs_exclude,
+		.include_ref_pattern = &decorate_refs_include,
+		.exclude_ref_config_pattern = &decorate_refs_exclude_config,
+	};
 	static struct revision_sources revision_sources;
 
 	const struct option builtin_log_options[] = {
@@ -265,16 +301,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 	}
 
 	if (decoration_style || rev->simplify_by_decoration) {
-		const struct string_list *config_exclude =
-			repo_config_get_value_multi(the_repository,
-						    "log.excludeDecoration");
-
-		if (config_exclude) {
-			struct string_list_item *item;
-			for_each_string_list_item(item, config_exclude)
-				string_list_append(&decorate_refs_exclude_config,
-						   item->string);
-		}
+		set_default_decoration_filter(&decoration_filter);
 
 		if (decoration_style)
 			rev->show_decorations = 1;
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 6b7d8e269f7..1a41096c8e2 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -1031,6 +1031,12 @@ test_expect_success 'decorate-refs-exclude HEAD' '
 	! grep HEAD actual
 '
 
+test_expect_success 'decorate-refs focus from default' '
+	git log --decorate=full --oneline \
+		--decorate-refs="refs/heads" >actual &&
+	! grep HEAD actual
+'
+
 test_expect_success 'log.decorate config parsing' '
 	git log --oneline --decorate=full >expect.full &&
 	git log --oneline --decorate=short >expect.short &&
@@ -2198,6 +2204,23 @@ test_expect_success 'log --decorate includes all levels of tag annotated tags' '
 	test_cmp expect actual
 '
 
+test_expect_success 'log --decorate does not include things outside filter' '
+	reflist="refs/prefetch/ refs/rebase-merge/ refs/bundle/" &&
+
+	for ref in $reflist
+	do
+		mkdir -p .git/$ref &&
+		echo $(git rev-parse HEAD) >.git/$ref/fake || return 1
+	done &&
+
+	git log --decorate=full --oneline >actual &&
+
+	for ref in $reflist
+	do
+		! grep $ref/fake actual || return 1
+	done
+'
+
 test_expect_success 'log --end-of-options' '
        git update-ref refs/heads/--source HEAD &&
        git log --end-of-options --source >actual &&
-- 
gitgitgadget


  parent reply	other threads:[~2022-07-26 14:04 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-26 14:04 [PATCH 0/3] log: create tighter default decoration filter Derrick Stolee via GitGitGadget
2022-07-26 14:04 ` [PATCH 1/3] refs: allow "HEAD" as " Derrick Stolee via GitGitGadget
2022-07-26 15:10   ` Ævar Arnfjörð Bjarmason
2022-07-29 13:23     ` Derrick Stolee
2022-07-26 14:04 ` Derrick Stolee via GitGitGadget [this message]
2022-07-26 14:39   ` [PATCH 2/3] log: add default " Ævar Arnfjörð Bjarmason
2022-07-29 13:25     ` Derrick Stolee
2022-07-26 15:04   ` Ævar Arnfjörð Bjarmason
2022-07-27 14:50   ` Junio C Hamano
2022-07-27 19:07     ` Derrick Stolee
2022-07-27 19:38       ` Junio C Hamano
2022-07-29 20:32     ` Jeff King
2022-07-26 14:04 ` [PATCH 3/3] maintenance: stop writing log.excludeDecoration Derrick Stolee via GitGitGadget
2022-07-27 14:50   ` Junio C Hamano
2022-07-26 14:44 ` [PATCH 0/3] log: create tighter default decoration filter Ævar Arnfjörð Bjarmason
2022-07-26 16:38   ` Derrick Stolee
2022-07-26 18:19     ` Ævar Arnfjörð Bjarmason
2022-07-27 13:41       ` Derrick Stolee
2022-07-27 20:40         ` Ævar Arnfjörð Bjarmason
2022-07-29 19:29 ` [PATCH v2 00/10] " Derrick Stolee via GitGitGadget
2022-07-29 19:29   ` [PATCH v2 01/10] refs: allow "HEAD" as " Derrick Stolee via GitGitGadget
2022-08-03  6:03     ` Junio C Hamano
2022-08-04 13:22       ` Derrick Stolee
2022-07-29 19:29   ` [PATCH v2 02/10] t4207: test coloring of grafted decorations Derrick Stolee via GitGitGadget
2022-08-03  6:25     ` Ævar Arnfjörð Bjarmason
2022-08-03  6:44       ` Eric Sunshine
2022-08-03 13:03         ` Ævar Arnfjörð Bjarmason
2022-08-04  4:05           ` Eric Sunshine
2022-08-04 17:23             ` Junio C Hamano
2022-08-05 14:21               ` Derrick Stolee
2022-07-29 19:29   ` [PATCH v2 03/10] refs: add array of ref namespaces Derrick Stolee via GitGitGadget
2022-08-03  6:16     ` Junio C Hamano
2022-08-04 13:29       ` Derrick Stolee
2022-08-04 16:16         ` Junio C Hamano
2022-08-03 22:39     ` Josh Steadmon
2022-08-04 13:29       ` Derrick Stolee
2022-07-29 19:29   ` [PATCH v2 04/10] refs: use ref_namespaces for replace refs base Derrick Stolee via GitGitGadget
2022-08-03 22:38     ` Josh Steadmon
2022-08-04 13:30       ` Derrick Stolee
2022-07-29 19:29   ` [PATCH v2 05/10] log-tree: use ref_namespaces instead of if/else-if Derrick Stolee via GitGitGadget
2022-08-03  6:31     ` Junio C Hamano
2022-08-04 13:31       ` Derrick Stolee
2022-08-04 14:34         ` Derrick Stolee
2022-08-04 14:50           ` Derrick Stolee
2022-08-04 17:40             ` Junio C Hamano
2022-08-04 20:17               ` Derrick Stolee
2022-07-29 19:29   ` [PATCH v2 06/10] log: add default decoration filter Derrick Stolee via GitGitGadget
2022-08-04  7:08     ` Ævar Arnfjörð Bjarmason
2022-08-05 14:27       ` Derrick Stolee
2022-08-05 14:50         ` Ævar Arnfjörð Bjarmason
2022-08-05 15:09           ` Derrick Stolee
2022-08-11 19:30             ` Ævar Arnfjörð Bjarmason
2022-08-12 19:37               ` Derrick Stolee
2022-07-29 19:29   ` [PATCH v2 07/10] log: add --decorate-all option Derrick Stolee via GitGitGadget
2022-08-04 16:57     ` Junio C Hamano
2022-07-29 19:29   ` [PATCH v2 08/10] log: create log.decorateFilter=all Derrick Stolee via GitGitGadget
2022-08-03 22:42     ` Josh Steadmon
2022-08-04 13:38       ` Derrick Stolee
2022-07-29 19:29   ` [PATCH v2 09/10] maintenance: stop writing log.excludeDecoration Derrick Stolee via GitGitGadget
2022-08-03  6:36     ` Junio C Hamano
2022-07-29 19:29   ` [PATCH v2 10/10] fetch: use ref_namespaces during prefetch Derrick Stolee via GitGitGadget
2022-08-05 17:58   ` [PATCH v3 00/11] log: create tighter default decoration filter Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 01/11] refs: allow "HEAD" as " Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 02/11] t4207: modernize test Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 03/11] t4207: test coloring of grafted decorations Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 04/11] refs: add array of ref namespaces Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 05/11] refs: use ref_namespaces for replace refs base Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 06/11] log-tree: use ref_namespaces instead of if/else-if Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 07/11] log: add default decoration filter Derrick Stolee via GitGitGadget
2022-09-08 21:13       ` Glen Choo
2022-09-09 12:23         ` Derrick Stolee
2022-09-09 16:19           ` Junio C Hamano
2022-09-09 16:40             ` Derrick Stolee
2022-09-09 17:41               ` Junio C Hamano
2022-09-09 17:12             ` Glen Choo
2022-08-05 17:58     ` [PATCH v3 08/11] log: add --clear-decorations option Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 09/11] log: create log.initialDecorationSet=all Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 10/11] maintenance: stop writing log.excludeDecoration Derrick Stolee via GitGitGadget
2022-08-05 17:58     ` [PATCH v3 11/11] fetch: use ref_namespaces during prefetch Derrick Stolee via GitGitGadget

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=6b40b84773c70244bb13204ec566b713f1bdf865.1658844250.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=derrickstolee@github.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=me@ttaylorr.com \
    --cc=steadmon@google.com \
    --cc=vdye@github.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).