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 <git@drmicha.warpmail.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Mar 10, 2015 at 14:53 UTC
51ff0f27bc6bfe83da7304ef9db77f3a2a4a47b0
3 files changed
+72
-13
log-tree.c
+68
-9
@@ -172,6 +172,43 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre
172
}
173
}
174
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
+
212
/*
213
* The caller makes sure there is no funny color before calling.
214
* format_decorations_extended makes sure the same after return.
@@ -184,6 +221,7 @@ void format_decorations_extended(struct strbuf *sb,
221
const char *suffix)
222
{
223
const struct name_decoration *decoration;
224
+ const struct name_decoration *current_and_HEAD;
225
const char *color_commit =
226
diff_get_color(use_color, DIFF_COMMIT);
227
const char *color_reset =
@@ -192,16 +230,37 @@ void format_decorations_extended(struct strbuf *sb,
230
decoration = get_name_decoration(&commit->object);
231
if (!decoration)
232
return;
233
+
234
+ current_and_HEAD = current_pointed_by_HEAD(decoration);
235
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
+ }
264
decoration = decoration->next;
265
}
266
strbuf_addstr(sb, color_commit);
t/t4013/diff.log_--decorate_--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, master)
8
+commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD -> master)
9
Merge: 9a6d494 c7a2ab9
10
Author: A U Thor <author@example.com>
11
Date: Mon Jun 26 00:04:00 2006 +0000
t/t4207-log-decoration-colors.sh
+3
-3
@@ -44,10 +44,10 @@ test_expect_success setup '
44
'
45
46
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},\
49
${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
51
${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_tag}tag: A1${c_reset}${c_commit},\
52
${c_reset}${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset} A1
53
${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\