Skip to content

Commit 51ff0f2

Browse files
committed
log: decorate HEAD with branch name
Currently, log decorations do not indicate which branch is checked out and whether HEAD is detached. When branch foo is checked out, change the "HEAD, foo" part of the decorations to "HEAD -> foo". This serves to indicate both ref decorations (helped by the spacing) as well as their relationshsip. As a consequence, "HEAD" without any " -> " denotes a detached HEAD now. Signed-off-by: Michael J Gruber <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4ab682e commit 51ff0f2

File tree

3 files changed

+72
-13
lines changed

3 files changed

+72
-13
lines changed

log-tree.c

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,43 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre
172172
}
173173
}
174174

175+
/*
176+
* Do we have HEAD in the output, and also the branch it points at?
177+
* If so, find that decoration entry for that current branch.
178+
*/
179+
static const struct name_decoration *current_pointed_by_HEAD(const struct name_decoration *decoration)
180+
{
181+
const struct name_decoration *list, *head = NULL;
182+
const char *branch_name = NULL;
183+
unsigned char unused[20];
184+
int rru_flags;
185+
186+
/* First find HEAD */
187+
for (list = decoration; list; list = list->next)
188+
if (list->type == DECORATION_REF_HEAD) {
189+
head = list;
190+
break;
191+
}
192+
if (!head)
193+
return NULL;
194+
195+
/* Now resolve and find the matching current branch */
196+
branch_name = resolve_ref_unsafe("HEAD", 0, unused, &rru_flags);
197+
if (!(rru_flags & REF_ISSYMREF))
198+
return NULL;
199+
if (!skip_prefix(branch_name, "refs/heads/", &branch_name))
200+
return NULL;
201+
202+
/* OK, do we have that ref in the list? */
203+
for (list = decoration; list; list = list->next)
204+
if ((list->type == DECORATION_REF_LOCAL) &&
205+
!strcmp(branch_name, list->name)) {
206+
return list;
207+
}
208+
209+
return NULL;
210+
}
211+
175212
/*
176213
* The caller makes sure there is no funny color before calling.
177214
* format_decorations_extended makes sure the same after return.
@@ -184,6 +221,7 @@ void format_decorations_extended(struct strbuf *sb,
184221
const char *suffix)
185222
{
186223
const struct name_decoration *decoration;
224+
const struct name_decoration *current_and_HEAD;
187225
const char *color_commit =
188226
diff_get_color(use_color, DIFF_COMMIT);
189227
const char *color_reset =
@@ -192,16 +230,37 @@ void format_decorations_extended(struct strbuf *sb,
192230
decoration = get_name_decoration(&commit->object);
193231
if (!decoration)
194232
return;
233+
234+
current_and_HEAD = current_pointed_by_HEAD(decoration);
195235
while (decoration) {
196-
strbuf_addstr(sb, color_commit);
197-
strbuf_addstr(sb, prefix);
198-
strbuf_addstr(sb, color_reset);
199-
strbuf_addstr(sb, decorate_get_color(use_color, decoration->type));
200-
if (decoration->type == DECORATION_REF_TAG)
201-
strbuf_addstr(sb, "tag: ");
202-
strbuf_addstr(sb, decoration->name);
203-
strbuf_addstr(sb, color_reset);
204-
prefix = separator;
236+
/*
237+
* When both current and HEAD are there, only
238+
* show HEAD->current where HEAD would have
239+
* appeared, skipping the entry for current.
240+
*/
241+
if (decoration != current_and_HEAD) {
242+
strbuf_addstr(sb, color_commit);
243+
strbuf_addstr(sb, prefix);
244+
strbuf_addstr(sb, color_reset);
245+
strbuf_addstr(sb, decorate_get_color(use_color, decoration->type));
246+
if (decoration->type == DECORATION_REF_TAG)
247+
strbuf_addstr(sb, "tag: ");
248+
249+
strbuf_addstr(sb, decoration->name);
250+
251+
if (current_and_HEAD &&
252+
decoration->type == DECORATION_REF_HEAD) {
253+
strbuf_addstr(sb, color_reset);
254+
strbuf_addstr(sb, color_commit);
255+
strbuf_addstr(sb, " -> ");
256+
strbuf_addstr(sb, color_reset);
257+
strbuf_addstr(sb, decorate_get_color(use_color, current_and_HEAD->type));
258+
strbuf_addstr(sb, current_and_HEAD->name);
259+
}
260+
strbuf_addstr(sb, color_reset);
261+
262+
prefix = separator;
263+
}
205264
decoration = decoration->next;
206265
}
207266
strbuf_addstr(sb, color_commit);

t/t4013/diff.log_--decorate_--all

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000
55

66
Rearranged lines in dir/sub
77

8-
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, master)
8+
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD -> master)
99
Merge: 9a6d494 c7a2ab9
1010
Author: A U Thor <[email protected]>
1111
Date: Mon Jun 26 00:04:00 2006 +0000

t/t4207-log-decoration-colors.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ test_expect_success setup '
4444
'
4545

4646
cat >expected <<EOF
47-
${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_HEAD}HEAD${c_reset}${c_commit},\
47+
${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_HEAD}HEAD${c_reset}${c_commit} ->\
48+
${c_reset}${c_branch}master${c_reset}${c_commit},\
4849
${c_reset}${c_tag}tag: v1.0${c_reset}${c_commit},\
49-
${c_reset}${c_tag}tag: B${c_reset}${c_commit},\
50-
${c_reset}${c_branch}master${c_reset}${c_commit})${c_reset} B
50+
${c_reset}${c_tag}tag: B${c_reset}${c_commit})${c_reset} B
5151
${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_tag}tag: A1${c_reset}${c_commit},\
5252
${c_reset}${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset} A1
5353
${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\

0 commit comments

Comments
 (0)