From: Aviv Eyal <avivey@gmail.com>
To: git@vger.kernel.org
Cc: Aviv Eyal <avivey@gmail.com>
Subject: [PATCH] Support specific color for a specific remote branches
Date: Mon, 8 Aug 2011 18:49:13 +0300 [thread overview]
Message-ID: <1312818553-25042-1-git-send-email-avivey@gmail.com> (raw)
Program 'show branch -a' supports different colors for 'local' and 'remote' branches.
When tracking more then one remote, all branches have the same color.
This change lets the user define a color for each remote, providing better visual distinction for different remotes.
Signed-off-by: Aviv Eyal <avivey@gmail.com>
---
Since my C days are now ancient history, I'm worried I might leak some char*s down there. Also,
I might have missed some apis that would have made this patch smaller.
I'm using a sorted list as a dictionary (Remote name -> Color), which is not too elegant but
probably 'good enough', considering I expect it to be a very small (<3) list.
Aviv.
Documentation/config.txt | 6 ++
builtin/branch.c | 119 +++++++++++++++++++++++++++++++++++++---------
2 files changed, 102 insertions(+), 23 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 0658ffb..efdb61f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -700,6 +700,7 @@ color.branch.<slot>::
`current` (the current branch), `local` (a local branch),
`remote` (a remote-tracking branch in refs/remotes/), `plain` (other
refs).
+ See also `remote.<name>.color`.
+
The value for these configuration variables is a list of colors (at most
two) and attributes (at most one), separated by spaces. The colors
@@ -1658,6 +1659,11 @@ remote.<name>.mirror::
If true, pushing to this remote will automatically behave
as if the `\--mirror` option was given on the command line.
+remote.<name>.color:
+ If set, the `branch` command will use the colors specified here
+ for the names of all branches tracking this remote. Colors
+ specified here take precedent over `color.branch.remote` config.
+
remote.<name>.skipDefaultUpdate::
If true, this remote will be skipped by default when updating
using linkgit:git-fetch[1] or the `update` subcommand of
diff --git a/builtin/branch.c b/builtin/branch.c
index 3142daa..85e6920 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -15,6 +15,7 @@
#include "branch.h"
#include "diff.h"
#include "revision.h"
+#include "string-list.h"
static const char * const builtin_branch_usage[] = {
"git branch [options] [-r | -a] [--merged | --no-merged]",
@@ -46,6 +47,9 @@ enum color_branch {
BRANCH_COLOR_CURRENT = 4
};
+// this string_list is used as a basic dictionary.
+struct string_list custom_colors = STRING_LIST_INIT_DUP;
+
static enum merge_filter {
NO_FILTER = 0,
SHOW_NOT_MERGED,
@@ -68,6 +72,52 @@ static int parse_branch_color_slot(const char *var, int ofs)
return -1;
}
+static char *strclone(const char *start, int len)
+{
+ char *result = malloc((len + 1) * sizeof(char));
+ if (!result)
+ return NULL;
+ strncpy(result, start, len);
+ result[len] = '\0';
+ return result;
+}
+
+static int git_branch_config_custom_color_remote(const char *var, const char *value)
+{
+ struct string_list_item *item;
+ char *name, *color;
+ name = strclone(var + 7, strlen(var) - 13); // "remote."=7, "remote..color"=13.
+ if (!name)
+ return 0;
+ color = malloc(COLOR_MAXLEN * sizeof(char));
+ if (!color) {
+ free(name);
+ return 0;
+ }
+ item = string_list_insert(&custom_colors, name);
+ color_parse(value, var, color);
+ item->util = color;
+ return 0;
+}
+
+static char *git_branch_get_custom_color_remote(const char *name)
+{
+ int name_len;
+ char* repo_name;
+ struct string_list_item *custom;
+ name_len = strchr(name, '/') - name;
+ repo_name = strclone(name, name_len);
+ if (!repo_name)
+ return NULL;
+
+ custom = string_list_lookup(&custom_colors, repo_name);
+ free(repo_name);
+ if (custom)
+ return (char*) custom->util;
+ return NULL;
+}
+
+
static int git_branch_config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "color.branch")) {
@@ -83,14 +133,10 @@ static int git_branch_config(const char *var, const char *value, void *cb)
color_parse(value, var, branch_colors[slot]);
return 0;
}
- return git_color_default_config(var, value, cb);
-}
+ if (!prefixcmp(var, "remote.") && !suffixcmp(var, ".color"))
+ return git_branch_config_custom_color_remote(var, value);
-static const char *branch_get_color(enum color_branch ix)
-{
- if (branch_use_color > 0)
- return branch_colors[ix];
- return "";
+ return git_color_default_config(var, value, cb);
}
static int branch_merged(int kind, const char *name,
@@ -354,6 +400,43 @@ static int ref_cmp(const void *r1, const void *r2)
return strcmp(c1->name, c2->name);
}
+static const char *branch_get_color(struct ref_item *item, int current)
+{
+ int index;
+ char *color;
+
+ if (branch_use_color <= 0)
+ return "";
+
+ if (!item)
+ index = BRANCH_COLOR_RESET;
+ else if (current)
+ index = BRANCH_COLOR_CURRENT;
+ else switch (item->kind) {
+ case REF_LOCAL_BRANCH:
+ index = BRANCH_COLOR_LOCAL;
+ break;
+ case REF_REMOTE_BRANCH:
+ index = BRANCH_COLOR_REMOTE;
+ color = git_branch_get_custom_color_remote(item->name);
+ if (color)
+ return color;
+ break;
+ default:
+ index = BRANCH_COLOR_PLAIN;
+ break;
+ }
+
+ return branch_colors[index];
+}
+
+static const char *branch_get_color_reset()
+{
+ if (branch_use_color <= 0)
+ return "";
+ return branch_colors[BRANCH_COLOR_RESET];
+}
+
static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
int show_upstream_ref)
{
@@ -424,18 +507,6 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
if (!matches_merge_filter(commit))
return;
- switch (item->kind) {
- case REF_LOCAL_BRANCH:
- color = BRANCH_COLOR_LOCAL;
- break;
- case REF_REMOTE_BRANCH:
- color = BRANCH_COLOR_REMOTE;
- break;
- default:
- color = BRANCH_COLOR_PLAIN;
- break;
- }
-
c = ' ';
if (current) {
c = '*';
@@ -444,12 +515,12 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
strbuf_addf(&name, "%s%s", prefix, item->name);
if (verbose)
- strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color),
+ strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(item, current),
maxwidth, name.buf,
- branch_get_color(BRANCH_COLOR_RESET));
+ branch_get_color_reset());
else
- strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(color),
- name.buf, branch_get_color(BRANCH_COLOR_RESET));
+ strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(item, current),
+ name.buf, branch_get_color_reset());
if (item->dest)
strbuf_addf(&out, " -> %s", item->dest);
@@ -712,5 +783,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
} else
usage_with_options(builtin_branch_usage, options);
+ string_list_clear(&custom_colors, 1);
+
return 0;
}
--
1.7.4.1
next reply other threads:[~2011-08-08 15:50 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-08 15:49 Aviv Eyal [this message]
2011-08-08 18:08 ` [PATCH] Support specific color for a specific remote branches Junio C Hamano
2011-08-08 20:52 ` Jeff King
2011-08-08 21:31 ` Junio C Hamano
2011-08-10 12:16 ` Jeff King
2011-08-09 18:59 ` Aviv Eyal
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=1312818553-25042-1-git-send-email-avivey@gmail.com \
--to=avivey@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).