Michael J Gruber <g...@drmicha.warpmail.net> writes:

> Junio C Hamano venit, vidit, dixit 06.03.2015 20:03:
>> Michael J Gruber <g...@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);
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to