All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jay Soffian <jaysoffian@gmail.com>
To: git@vger.kernel.org
Cc: Jay Soffian <jaysoffian@gmail.com>
Subject: [PATCH] builtin-branch: improve output when displaying remote branches
Date: Tue, 10 Feb 2009 06:01:41 -0500	[thread overview]
Message-ID: <1234263701-95463-1-git-send-email-jaysoffian@gmail.com> (raw)

When displaying local and remote branches, prefix the remote branch names with
"remotes/" to make the remote branches clear from the local branches. If
displaying only the remote branches, the prefix is not shown since it would be
redundant.

When displaying a remote branch HEAD (which is a sane symref), show what it
points to similar to how "ls -l" show symlinks. Also in this case, do not show
verbose output for the HEAD itself as it is shown immediately below on the
pointed to branch.

Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
---
I think this addresses the feedback I got on the original patch,
http://article.gmane.org/gmane.comp.version-control.git/109161

Some sample output:

$ git branch -a
  master
  next
* wip/branch-show-remote-HEAD-2
  wip/push-docs
  remotes/origin/HEAD -> master
  remotes/origin/html
  remotes/origin/maint
  remotes/origin/man
  remotes/origin/master
  remotes/origin/next
  remotes/origin/pu
  remotes/origin/todo

$ git branch -r
  origin/HEAD -> master
  origin/html
  origin/maint
  origin/man
  origin/master
  origin/next
  origin/pu
  origin/todo

$ git branch -rv
  origin/HEAD -> master
  origin/html           6116912 Autogenerated HTML docs for v1.6.2-rc0-10-gf6b9
  origin/maint          7e1100e gitweb: add $prevent_xss option to prevent XSS by repository content
  origin/man            67cb1a7 Autogenerated manpages for v1.6.2-rc0-10-gf6b9
  origin/master         f6b98e4 git-web--browse: Fix check for /bin/start
  origin/next           417ce12 Merge branch 'master' into next
  origin/pu             9d798e7 Merge branch 'db/foreign-scm' into pu
  origin/todo           5ed7079 What's in update

Notice that the verbose output for HEAD is squelched as it would be identical to
what is shown below in "origin/master". Of course, if <remote>/HEAD does not
resolve as a symref pointing to a branch inside <remote> (I don't know why this
would happen though...), then it is shown like the other branches.

BTW, I noticed that "git branch -a --merged" and "git branch -av --merged"
return a different set of branches. I'm not sure why though (but it isn't due to
this patch).

 builtin-branch.c |   68 ++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/builtin-branch.c b/builtin-branch.c
index 56a1971..03ad757 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -181,7 +181,8 @@ static int delete_branches(int argc, const char **argv, int force, int kinds)
 
 struct ref_item {
 	char *name;
-	unsigned int kind;
+	char *dest;
+	unsigned int kind, len;
 	struct commit *commit;
 };
 
@@ -193,13 +194,23 @@ struct ref_list {
 	int kinds;
 };
 
+static char *resolve_remote_head_symref(const char *head_name) {
+	unsigned char sha1[20];
+	int flag;
+	const char *refname;
+	refname = resolve_ref(head_name, sha1, 0, &flag);
+	if (refname && (flag & REF_ISSYMREF) &&
+	    !prefixcmp(refname, "refs/remotes/"))
+		return xstrdup(refname + strlen(head_name) - 4);
+	return NULL;
+}
+
 static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
 {
 	struct ref_list *ref_list = (struct ref_list*)(cb_data);
 	struct ref_item *newitem;
 	struct commit *commit;
 	int kind;
-	int len;
 
 	/* Detect kind */
 	if (!prefixcmp(refname, "refs/heads/")) {
@@ -239,9 +250,20 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
 	newitem->name = xstrdup(refname);
 	newitem->kind = kind;
 	newitem->commit = commit;
-	len = strlen(newitem->name);
-	if (len > ref_list->maxwidth)
-		ref_list->maxwidth = len;
+	newitem->len = strlen(newitem->name);
+	newitem->dest = (newitem->kind == REF_REMOTE_BRANCH &&
+			 newitem->len > 5 &&
+			 !strcmp(newitem->name + newitem->len - 5, "/HEAD"))
+			? resolve_remote_head_symref(refname - 13) : NULL;
+	/* adjust for " -> " */
+	if (newitem->dest)
+		newitem->len += strlen(newitem->dest) + 4;
+	/* adjust for "remotes/" */
+	if (newitem->kind == REF_REMOTE_BRANCH &&
+	    ref_list->kinds != REF_REMOTE_BRANCH)
+		newitem->len += 8;
+	if (newitem->len > ref_list->maxwidth)
+		ref_list->maxwidth = newitem->len;
 
 	return 0;
 }
@@ -250,8 +272,11 @@ static void free_ref_list(struct ref_list *ref_list)
 {
 	int i;
 
-	for (i = 0; i < ref_list->index; i++)
+	for (i = 0; i < ref_list->index; i++) {
 		free(ref_list->list[i].name);
+		if (ref_list->list[i].dest)
+			free(ref_list->list[i].dest);
+	}
 	free(ref_list->list);
 }
 
@@ -292,7 +317,7 @@ static int matches_merge_filter(struct commit *commit)
 }
 
 static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
-			   int abbrev, int current)
+			   int abbrev, int current, char *prefix)
 {
 	char c;
 	int color;
@@ -319,8 +344,13 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 		color = COLOR_BRANCH_CURRENT;
 	}
 
-	if (verbose) {
+	if (item->dest) {
+		printf("%c %s%s%s%s -> %s\n", c, branch_get_color(color),
+		       prefix, item->name,
+		       branch_get_color(COLOR_BRANCH_RESET), item->dest);
+	} else if (verbose) {
 		struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT;
+		struct strbuf name = STRBUF_INIT;
 		const char *sub = " **** invalid ref ****";
 
 		commit = item->commit;
@@ -333,28 +363,29 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
 		if (item->kind == REF_LOCAL_BRANCH)
 			fill_tracking_info(&stat, item->name);
 
+		strbuf_addf(&name, "%s%s", prefix, item->name);
 		printf("%c %s%-*s%s %s %s%s\n", c, branch_get_color(color),
-		       maxwidth, item->name,
+		       maxwidth, name.buf,
 		       branch_get_color(COLOR_BRANCH_RESET),
 		       find_unique_abbrev(item->commit->object.sha1, abbrev),
 		       stat.buf, sub);
 		strbuf_release(&stat);
 		strbuf_release(&subject);
+		strbuf_release(&name);
 	} else {
-		printf("%c %s%s%s\n", c, branch_get_color(color), item->name,
-		       branch_get_color(COLOR_BRANCH_RESET));
+		printf("%c %s%s%s%s\n", c, branch_get_color(color), prefix,
+		       item->name, branch_get_color(COLOR_BRANCH_RESET));
 	}
 }
 
 static int calc_maxwidth(struct ref_list *refs)
 {
-	int i, l, w = 0;
+	int i, w = 0;
 	for (i = 0; i < refs->index; i++) {
 		if (!matches_merge_filter(refs->list[i].commit))
 			continue;
-		l = strlen(refs->list[i].name);
-		if (l > w)
-			w = l;
+		if (refs->list[i].len > w)
+			w = refs->list[i].len;
 	}
 	return w;
 }
@@ -394,7 +425,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str
 		item.commit = head_commit;
 		if (strlen(item.name) > ref_list.maxwidth)
 			ref_list.maxwidth = strlen(item.name);
-		print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1);
+		print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1, "");
 		free(item.name);
 	}
 
@@ -402,8 +433,11 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str
 		int current = !detached &&
 			(ref_list.list[i].kind == REF_LOCAL_BRANCH) &&
 			!strcmp(ref_list.list[i].name, head);
+		char *prefix = (kinds != REF_REMOTE_BRANCH &&
+				ref_list.list[i].kind == REF_REMOTE_BRANCH)
+				? "remotes/" : "";
 		print_ref_item(&ref_list.list[i], ref_list.maxwidth, verbose,
-			       abbrev, current);
+			       abbrev, current, prefix);
 	}
 
 	free_ref_list(&ref_list);
-- 
1.6.2.rc0.12.gbd893

             reply	other threads:[~2009-02-10 11:03 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-10 11:01 Jay Soffian [this message]
2009-02-11  6:47 ` [PATCH] builtin-branch: improve output when displaying remote branches Jay Soffian
2009-02-12  3:49 ` Junio C Hamano
2009-02-12  4:30   ` Jay Soffian
2009-02-12  5:42     ` Junio C Hamano
2009-02-13  5:34       ` [PATCH v2] " Jay Soffian
2009-02-13  6:35         ` Junio C Hamano
2009-02-13  6:45           ` Jay Soffian
2009-02-13  7:52             ` Junio C Hamano
2009-02-13  8:06               ` Jay Soffian
2009-02-13  9:40                 ` [PATCH v3] " Jay Soffian
2009-02-13  6:47           ` [PATCH v2] " martin f krafft
2009-02-13  7:36             ` Junio C Hamano
2009-02-13  7:37         ` Johannes Sixt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1234263701-95463-1-git-send-email-jaysoffian@gmail.com \
    --to=jaysoffian@gmail.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.