git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] log: decorate detached HEAD differently

From
Junio C Hamano <gitster@pobox.com>
Date
Mar 10, 2015, 02:03 UTC
Message-ID
<xmqqh9tt623d.fsf@gitster.dls.corp.google.com>
In-Reply-To
<54FD64D1.6080103@drmicha.warpmail.net>
Michael J Gruber <git@drmicha.warpmail.net> writes:
Show 12 quoted lines
> Junio C Hamano venit, vidit, dixit 06.03.2015 20:03:
>> Michael J Gruber <git@drmicha.warpmail.net> writes:
>>>     
>>>     Note that now a checked branch is listed twice, once as target of the
>>>     HEAD, once as branch: They are two different refs and colored differently.
>> 
>> The pointee of HEAD would always be branch and will always appear on
>> the output when you show HEAD->$name_of_that_branch; is it feasible
>> to drop the duplicate, I wonder?
>
> It's doable but not nice, because we cannot take the order in which refs
> are processed for granted.

That is true, but when we format them into a single line in the header in response to --decorate (or %d), don't we have all of them already at hand---does the order still matter?

Here is an illustration of what I had in mind, made on a random commit I happened to have checked out that does not have your patches on this topic. Half of the change is a new helper function, and the other half is mostly reindenting.

 log-tree.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 63 insertions(+), 8 deletions(-)
diff --git a/log-tree.c b/log-tree.c
index 7f0890e..e0c5865 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -173,6 +173,43 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre
 }
 
 /*
+ * Do we have HEAD in the output, and also the branch it points at?
+ * If so, find that decoration entry for that current branch.
+ */
+static const struct name_decoration *current_pointed_by_HEAD(const struct name_decoration *decoration)
+{
+	const struct name_decoration *list, *head = NULL;
+	const char *branch_name = NULL;
+	unsigned char unused[20];
+	int rru_flags;
+
+	/* First find HEAD */
+	for (list = decoration; list; list = list->next)
+		if (list->type == DECORATION_REF_HEAD) {
+			head = list;
+			break;
+		}
+	if (!head)
+		return NULL;
+
+	/* Now resolve and find the matching current branch */
+	branch_name = resolve_ref_unsafe("HEAD", 0, unused, &rru_flags);
+	if (!(rru_flags & REF_ISSYMREF))
+		return NULL;
+	if (!skip_prefix(branch_name, "refs/heads/", &branch_name))
+		return NULL;
+
+	/* OK, do we have that ref in the list? */
+	for (list = decoration; list; list = list->next)
+		if ((list->type == DECORATION_REF_LOCAL) &&
+		    !strcmp(branch_name, list->name)) {
+			return list;
+		}
+
+	return NULL;
+}
+
+/*
  * The caller makes sure there is no funny color before calling.
  * format_decorations_extended makes sure the same after return.
  */
@@ -184,6 +221,7 @@ void format_decorations_extended(struct strbuf *sb,
 			const char *suffix)
 {
 	const struct name_decoration *decoration;
+	const struct name_decoration *current_and_HEAD;
 	const char *color_commit =
 		diff_get_color(use_color, DIFF_COMMIT);
 	const char *color_reset =
@@ -192,15 +230,32 @@ void format_decorations_extended(struct strbuf *sb,
 	decoration = get_name_decoration(&commit->object);
 	if (!decoration)
 		return;
+
+	current_and_HEAD = current_pointed_by_HEAD(decoration);
 	while (decoration) {
-		strbuf_addstr(sb, color_commit);
-		strbuf_addstr(sb, prefix);
-		strbuf_addstr(sb, decorate_get_color(use_color, decoration->type));
-		if (decoration->type == DECORATION_REF_TAG)
-			strbuf_addstr(sb, "tag: ");
-		strbuf_addstr(sb, decoration->name);
-		strbuf_addstr(sb, color_reset);
-		prefix = separator;
+		/*
+		 * When both current and HEAD are there, only
+		 * show HEAD->current where HEAD would have
+		 * appeaed, skipping the entry for current.
+		 */
+		if (current_and_HEAD && decoration == current_and_HEAD)
+			;
+		else {
+			strbuf_addstr(sb, color_commit);
+			strbuf_addstr(sb, prefix);
+			strbuf_addstr(sb, decorate_get_color(use_color, decoration->type));
+			if (decoration->type == DECORATION_REF_TAG)
+				strbuf_addstr(sb, "tag: ");
+
+			if (current_and_HEAD &&
+			    decoration->type == DECORATION_REF_HEAD)
+				strbuf_addf(sb, "HEAD->%s", current_and_HEAD->name);
+			else
+				strbuf_addstr(sb, decoration->name);
+			strbuf_addstr(sb, color_reset);
+
+			prefix = separator;
+		}
 		decoration = decoration->next;
 	}
 	strbuf_addstr(sb, color_commit);
Previous: Michael J GruberNext: Michael J Gruber
Message 16 of 23 in “Should "git log --decorate" indicate whether the HEAD is detached?”
  1. Julien CretelFeb 16, 2015
  2. Junio C HamanoFeb 16, 2015
  3. Julien CretelFeb 16, 2015
  4. Michael J GruberFeb 18, 2015
  5. log: decorate detached HEAD differentlyMichael J Gruber, Feb 18, 2015
  6. Junio C HamanoFeb 18, 2015
  7. Michael J GruberFeb 18, 2015
  8. Junio C HamanoFeb 18, 2015
  9. Michael J GruberFeb 19, 2015
  10. Julien CretelFeb 19, 2015
  11. Junio C HamanoFeb 20, 2015
  12. log: decorate detached HEAD differentlyMichael J Gruber, Mar 6, 2015
  13. Michael J GruberMar 6, 2015
  14. Junio C HamanoMar 6, 2015
  15. Michael J GruberMar 9, 2015
  16. Junio C HamanoMar 10, 2015
  17. Michael J GruberMar 10, 2015
  18. 0/2 log decorations for HEADMichael J Gruber, Mar 10, 2015
  19. Junio C HamanoMar 10, 2015
  20. Michael J GruberMar 11, 2015
  21. Julien CretelMar 23, 2015
  22. 1/2 log-tree: properly reset colorsMichael J Gruber, Mar 10, 2015
  23. 2/2 log: decorate HEAD with branch nameMichael J Gruber, Mar 10, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.