[PATCH 1/2] log: handle --decorate-refs with userformat "%d"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In order to show ref decorations, we first have to load them. If you
run:

  git log --decorate

then git-log will recognize the option and load them up front via
cmd_log_init(). Likewise if log.decorate is set.

If you don't say --decorate explicitly, but do mention "%d" or "%D" in
the output format, like so:

  git log --format=%d

then this also works, because we lazy-load the ref decorations. This has
been true since 3b3d443feb (add '%d' pretty format specifier to show
decoration, 2008-09-04), though the lazy-load was later moved into
log-tree.c.

But there's one problem: that lazy-load just uses the defaults; it
doesn't take into account any --decorate-refs options (or its exclude
variant, or their config). So this does not work:

  git log --decorate-refs=whatever --format=%d

It will decorate using all refs, not just the specified ones. This has
been true since --decorate-refs was added in 65516f586b (log: add option
to choose which refs to decorate, 2017-11-21). Adding further confusion
is that it _may_ work because of the auto-decoration feature. If that's
in use (and it often is, as it's the default), then if the output is
going to stdout, we do enable decorations early (and so load them up
front, respecting the extra options). But otherwise we do not. So:

  git log --decorate-refs=whatever --format=%d >some-file

would typically behave differently than it does when the output goes to
the pager or terminal!

The solution is simple: we should recognize in cmd_log_init() that we're
going to show decorations, and make sure we load them there. We already
check userformat_find_requirements(), so we can couple this with our
existing code there.

There are two new tests. The first shows off the actual fix. The second
makes sure that our fix doesn't cause us to stomp on an existing
--decorate option (see the new comment in the code, as well).

Reported-by: Josh Rampersad <josh.rampersad@xxxxxxxxxxxxx>
Signed-off-by: Jeff King <peff@xxxxxxxx>
---
 builtin/log.c  | 18 ++++++++++++++++--
 t/t4202-log.sh | 22 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/builtin/log.c b/builtin/log.c
index f75d87e8d7..a924f56299 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -245,8 +245,22 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
 			rev->abbrev_commit = 0;
 	}
 
-	if (rev->commit_format == CMIT_FMT_USERFORMAT && !w.decorate)
-		decoration_style = 0;
+	if (rev->commit_format == CMIT_FMT_USERFORMAT) {
+		if (!w.decorate) {
+			/*
+			 * Disable decoration loading if the format will not
+			 * show them anyway.
+			 */
+			decoration_style = 0;
+		} else if (!decoration_style) {
+			/*
+			 * If we are going to show them, make sure we do load
+			 * them here, but taking care not to override a
+			 * specific style set by config or --decorate.
+			 */
+			decoration_style = DECORATE_SHORT_REFS;
+		}
+	}
 
 	if (decoration_style) {
 		const struct string_list *config_exclude =
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 7884e3d46b..5f0ae7a785 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -952,6 +952,28 @@ test_expect_success 'decorate-refs-exclude and simplify-by-decoration' '
 	test_cmp expect.decorate actual
 '
 
+test_expect_success 'decorate-refs with implied decorate from format' '
+	cat >expect <<-\EOF &&
+	side-2 (tag: side-2)
+	side-1
+	EOF
+	git log --no-walk --format="%s%d" \
+		--decorate-refs="*side-2" side-1 side-2 \
+		>actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'implied decorate does not override option' '
+	cat >expect <<-\EOF &&
+	side-2 (tag: refs/tags/side-2, refs/heads/side)
+	side-1 (tag: refs/tags/side-1)
+	EOF
+	git log --no-walk --format="%s%d" \
+		--decorate=full side-1 side-2 \
+		>actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'log.decorate config parsing' '
 	git log --oneline --decorate=full >expect.full &&
 	git log --oneline --decorate=short >expect.short &&
-- 
2.34.1.328.g8a543840e4




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux