log: decorate HEAD with branch name under --decorate=full, too

The previous step to teach "log --decorate" to show "HEAD -> master" instead of "HEAD, master" when showing the commit at the tip of the 'master' branch, when the 'master' branch is checked out, did not work for "log --decorate=full". The commands in the "log" family prepare commit decorations for all refs upfront, and the actual string used in a decoration depends on how load_ref_decorations() is called very early in the process. By default, "git log --decorate" stores names with common prefixes such as "refs/heads" stripped; "git log --decorate=full" stores the full refnames. When the current_pointed_by_HEAD() function has to decide if "HEAD" points at the branch a decoration describes, however, what was passed to load_ref_decorations() to decide to strip (or keep) such a common prefix is long lost. This makes it impossible to reliably tell if a decoration that stores "refs/heads/master", for example, is the 'master' branch (under "--decorate" with prefix omitted) or 'refs/heads/master' branch (under "--decorate=full"). Keep what was passed to load_ref_decorations() in a global next to the global variable name_decoration, and use that to decide how to match what was read from "HEAD" and what is in a decoration. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed May 13, 2015 at 10:25 UTC 76c61fbdbab6241af5b229a314946714fdc45908
2 files changed +19 -6
log-tree.c
+18 -5
@@ -13,6 +13,8 @@
13 #include "line-log.h"
14
15 static struct decoration name_decoration = { "object names" };
16 +static int decoration_loaded;
17 +static int decoration_flags;
18
19 static char decoration_colors[][COLOR_MAXLEN] = {
20 GIT_COLOR_RESET,
@@ -146,9 +148,9 @@ static int add_graft_decoration(const struct commit_graft *graft, void *cb_data)
148
149 void load_ref_decorations(int flags)
150 {
149 - static int loaded;
150 - if (!loaded) {
151 - loaded = 1;
151 + if (!decoration_loaded) {
152 + decoration_loaded = 1;
153 + decoration_flags = flags;
154 for_each_ref(add_ref_decoration, &flags);
155 head_ref(add_ref_decoration, &flags);
156 for_each_commit_graft(add_graft_decoration, NULL);
@@ -196,8 +198,19 @@ static const struct name_decoration *current_pointed_by_HEAD(const struct name_d
198 branch_name = resolve_ref_unsafe("HEAD", 0, unused, &rru_flags);
199 if (!(rru_flags & REF_ISSYMREF))
200 return NULL;
199 - if (!skip_prefix(branch_name, "refs/heads/", &branch_name))
200 - return NULL;
201 +
202 + if ((decoration_flags == DECORATE_SHORT_REFS)) {
203 + if (!skip_prefix(branch_name, "refs/heads/", &branch_name))
204 + return NULL;
205 + } else {
206 + /*
207 + * Each decoration has a refname in full; keep
208 + * branch_name also in full, but still make sure
209 + * HEAD is a reasonable ref.
210 + */
211 + if (!starts_with(branch_name, "refs/"))
212 + return NULL;
213 + }
214
215 /* OK, do we have that ref in the list? */
216 for (list = decoration; list; list = list->next)
t/t4013/diff.log_--decorate=full_--all
+1 -1
@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000
5
6 Rearranged lines in dir/sub
7
8 -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, refs/heads/master)
8 +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD -> refs/heads/master)
9 Merge: 9a6d494 c7a2ab9
10 Author: A U Thor <author@example.com>
11 Date: Mon Jun 26 00:04:00 2006 +0000