From eb3005e274d6d342cd4766598d9210995b5dca0c Mon Sep 17 00:00:00 2001 From: Nazri Ramliy Date: Sat, 19 Jun 2010 09:37:33 +0800 Subject: commit.h: add 'type' to struct name_decoration This allows for semantically better handling of decoration type. Signed-off-by: Nazri Ramliy Signed-off-by: Junio C Hamano diff --git a/commit.h b/commit.h index 6ef88dc..ba818fc 100644 --- a/commit.h +++ b/commit.h @@ -28,6 +28,7 @@ extern const char *commit_type; extern struct decoration name_decoration; struct name_decoration { struct name_decoration *next; + int type; char name[1]; }; -- cgit v0.10.2-6-g49f6 From a7524128750ebf34fe0639e1e5d7abd03aff0302 Mon Sep 17 00:00:00 2001 From: Nazri Ramliy Date: Sat, 19 Jun 2010 09:37:34 +0800 Subject: log-tree.c: Use struct name_decoration's type for classifying decoration The "tag: " prefix is no longer prepended to the name of the decoration. It is now printed conditionally by show_decorations if the decoration type is DECORATION_REF_TAG. Signed-off-by: Nazri Ramliy Signed-off-by: Junio C Hamano diff --git a/log-tree.c b/log-tree.c index 2e2be7c..bec6096 100644 --- a/log-tree.c +++ b/log-tree.c @@ -10,29 +10,50 @@ struct decoration name_decoration = { "object names" }; -static void add_name_decoration(const char *prefix, const char *name, struct object *obj) +enum decoration_type { + DECORATION_NONE = 0, + DECORATION_REF_LOCAL, + DECORATION_REF_REMOTE, + DECORATION_REF_TAG, + DECORATION_REF_STASH, + DECORATION_REF_HEAD, +}; + +static void add_name_decoration(enum decoration_type type, const char *name, struct object *obj) { - int plen = strlen(prefix); int nlen = strlen(name); - struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + plen + nlen); - memcpy(res->name, prefix, plen); - memcpy(res->name + plen, name, nlen + 1); + struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + nlen); + memcpy(res->name, name, nlen + 1); + res->type = type; res->next = add_decoration(&name_decoration, obj, res); } static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data) { struct object *obj = parse_object(sha1); + enum decoration_type type = DECORATION_NONE; if (!obj) return 0; + + if (!prefixcmp(refname, "refs/heads")) + type = DECORATION_REF_LOCAL; + else if (!prefixcmp(refname, "refs/remotes")) + type = DECORATION_REF_REMOTE; + else if (!prefixcmp(refname, "refs/tags")) + type = DECORATION_REF_TAG; + else if (!prefixcmp(refname, "refs/stash")) + type = DECORATION_REF_STASH; + else if (!prefixcmp(refname, "HEAD")) + type = DECORATION_REF_HEAD; + if (!cb_data || *(int *)cb_data == DECORATE_SHORT_REFS) refname = prettify_refname(refname); - add_name_decoration("", refname, obj); + add_name_decoration(type, refname, obj); while (obj->type == OBJ_TAG) { obj = ((struct tag *)obj)->tagged; if (!obj) break; - add_name_decoration("tag: ", refname, obj); + add_name_decoration(DECORATION_REF_TAG, refname, obj); } return 0; } @@ -70,7 +91,10 @@ void show_decorations(struct rev_info *opt, struct commit *commit) return; prefix = " ("; while (decoration) { - printf("%s%s", prefix, decoration->name); + printf("%s", prefix); + if (decoration->type == DECORATION_REF_TAG) + printf("tag: "); + printf("%s", decoration->name); prefix = ", "; decoration = decoration->next; } -- cgit v0.10.2-6-g49f6 From 67a4b5864f9423ccfe8090365029dae918504830 Mon Sep 17 00:00:00 2001 From: Nazri Ramliy Date: Sat, 19 Jun 2010 09:37:35 +0800 Subject: log --decorate: Colorize commit decorations This makes the decorations stand out more and easier to distinguish and spot because they are colored differently depending on their type. Signed-off-by: Nazri Ramliy Signed-off-by: Junio C Hamano diff --git a/log-tree.c b/log-tree.c index bec6096..61680f4 100644 --- a/log-tree.c +++ b/log-tree.c @@ -7,6 +7,7 @@ #include "reflog-walk.h" #include "refs.h" #include "string-list.h" +#include "color.h" struct decoration name_decoration = { "object names" }; @@ -19,6 +20,29 @@ enum decoration_type { DECORATION_REF_HEAD, }; +static char decoration_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_BOLD_GREEN, /* REF_LOCAL */ + GIT_COLOR_BOLD_RED, /* REF_REMOTE */ + GIT_COLOR_BOLD_YELLOW, /* REF_TAG */ + GIT_COLOR_BOLD_MAGENTA, /* REF_STASH */ + GIT_COLOR_BOLD_CYAN, /* REF_HEAD */ +}; + +static const char *decorate_get_color(int decorate_use_color, enum decoration_type ix) +{ + if (decorate_use_color) + return decoration_colors[ix]; + return ""; +} + +/* + * log-tree.c uses DIFF_OPT_TST for determining whether to use color + * for showing the commit sha1, use the same check for --decorate + */ +#define decorate_get_color_opt(o, ix) \ + decorate_get_color(DIFF_OPT_TST((o), COLOR_DIFF), ix) + static void add_name_decoration(enum decoration_type type, const char *name, struct object *obj) { int nlen = strlen(name); @@ -81,6 +105,10 @@ void show_decorations(struct rev_info *opt, struct commit *commit) { const char *prefix; struct name_decoration *decoration; + const char *color_commit = + diff_get_color_opt(&opt->diffopt, DIFF_COMMIT); + const char *color_reset = + decorate_get_color_opt(&opt->diffopt, DECORATION_NONE); if (opt->show_source && commit->util) printf("\t%s", (char *) commit->util); @@ -92,9 +120,13 @@ void show_decorations(struct rev_info *opt, struct commit *commit) prefix = " ("; while (decoration) { printf("%s", prefix); + fputs(decorate_get_color_opt(&opt->diffopt, decoration->type), + stdout); if (decoration->type == DECORATION_REF_TAG) - printf("tag: "); + fputs("tag: ", stdout); printf("%s", decoration->name); + fputs(color_reset, stdout); + fputs(color_commit, stdout); prefix = ", "; decoration = decoration->next; } -- cgit v0.10.2-6-g49f6 From 5e11bee65f601ba97dc4c61c75fcb2f448fdcb1c Mon Sep 17 00:00:00 2001 From: Nazri Ramliy Date: Thu, 24 Jun 2010 08:21:16 +0800 Subject: Allow customizable commit decorations colors Signed-off-by: Nazri Ramliy Signed-off-by: Junio C Hamano diff --git a/Documentation/config.txt b/Documentation/config.txt index 7afd0a3..89cb487 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -683,6 +683,11 @@ color.diff.:: (highlighting whitespace errors). The values of these variables may be specified as in color.branch.. +color.decorate.:: + Use customized color for 'git log --decorate' output. `` is one + of `branch`, `remoteBranch`, `tag`, `stash` or `HEAD` for local + branches, remote tracking branches, tags, stash and HEAD, respectively. + color.grep:: When set to `always`, always highlight matches. When `false` (or `never`), never. When set to `true` or `auto`, use color only diff --git a/builtin/log.c b/builtin/log.c index 976e16f9..0835866 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -296,6 +296,9 @@ static int git_log_config(const char *var, const char *value, void *cb) default_show_root = git_config_bool(var, value); return 0; } + if (!prefixcmp(var, "color.decorate.")) + return parse_decorate_color_config(var, 15, value); + return git_diff_ui_config(var, value, cb); } diff --git a/log-tree.c b/log-tree.c index 61680f4..b46ed3b 100644 --- a/log-tree.c +++ b/log-tree.c @@ -36,6 +36,42 @@ static const char *decorate_get_color(int decorate_use_color, enum decoration_ty return ""; } +static int parse_decorate_color_slot(const char *slot) +{ + /* + * We're comparing with 'ignore-case' on + * (because config.c sets them all tolower), + * but let's match the letters in the literal + * string values here with how they are + * documented in Documentation/config.txt, for + * consistency. + * + * We love being consistent, don't we? + */ + if (!strcasecmp(slot, "branch")) + return DECORATION_REF_LOCAL; + if (!strcasecmp(slot, "remoteBranch")) + return DECORATION_REF_REMOTE; + if (!strcasecmp(slot, "tag")) + return DECORATION_REF_TAG; + if (!strcasecmp(slot, "stash")) + return DECORATION_REF_STASH; + if (!strcasecmp(slot, "HEAD")) + return DECORATION_REF_HEAD; + return -1; +} + +int parse_decorate_color_config(const char *var, const int ofs, const char *value) +{ + int slot = parse_decorate_color_slot(var + ofs); + if (slot < 0) + return 0; + if (!value) + return config_error_nonbool(var); + color_parse(value, var, decoration_colors[slot]); + return 0; +} + /* * log-tree.c uses DIFF_OPT_TST for determining whether to use color * for showing the commit sha1, use the same check for --decorate diff --git a/log-tree.h b/log-tree.h index 3f7b400..5c4cf7c 100644 --- a/log-tree.h +++ b/log-tree.h @@ -7,6 +7,7 @@ struct log_info { struct commit *commit, *parent; }; +int parse_decorate_color_config(const char *var, const int ofs, const char *value); void init_log_tree_opt(struct rev_info *); int log_tree_diff_flush(struct rev_info *); int log_tree_commit(struct rev_info *, struct commit *); -- cgit v0.10.2-6-g49f6 From 567102819ac56ccf7eb638ea8b5c975c03e88558 Mon Sep 17 00:00:00 2001 From: Nazri Ramliy Date: Tue, 29 Jun 2010 15:47:08 +0800 Subject: Add test for correct coloring of git log --decoration Signed-off-by: Nazri Ramliy Signed-off-by: Junio C Hamano diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh new file mode 100755 index 0000000..bbde31b --- /dev/null +++ b/t/t4207-log-decoration-colors.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# +# Copyright (c) 2010 Nazri Ramliy +# + +test_description='Test for "git log --decorate" colors' + +. ./test-lib.sh + +get_color () +{ + git config --get-color no.such.slot "$1" +} + +test_expect_success setup ' + git config diff.color.commit yellow && + git config color.decorate.branch green && + git config color.decorate.remoteBranch red && + git config color.decorate.tag "reverse bold yellow" && + git config color.decorate.stash magenta && + git config color.decorate.HEAD cyan && + + c_reset=$(get_color reset) && + + c_commit=$(get_color yellow) && + c_branch=$(get_color green) && + c_remoteBranch=$(get_color red) && + c_tag=$(get_color "reverse bold yellow") && + c_stash=$(get_color magenta) && + c_HEAD=$(get_color cyan) && + + test_commit A && + git clone . other && + ( + cd other && + test_commit A1 + ) && + + git remote add -f other ./other && + test_commit B && + git tag v1.0 && + echo >>A.t && + git stash save Changes to A.t +' + +cat >expected <out && + test_cmp expected out +' + +test_done -- cgit v0.10.2-6-g49f6