branch: add --column

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Apr 13, 2012 at 17:54 UTC ebe31ef2ed539ec93f87c6705852f29347410b48
5 files changed +119 -5
Documentation/config.txt
+4
@@ -862,6 +862,10 @@ column.ui::
862 +
863 This option defaults to 'never'.
864
865 +column.branch::
866 + Specify whether to output branch listing in `git branch` in columns.
867 + See `column.ui` for details.
868 +
869 commit.status::
870 A boolean to enable/disable inclusion of status information in the
871 commit message template when using an editor to prepare the commit
Documentation/git-branch.txt
+9
@@ -10,6 +10,7 @@ SYNOPSIS
10 [verse]
11 'git branch' [--color[=<when>] | --no-color] [-r | -a]
12 [--list] [-v [--abbrev=<length> | --no-abbrev]]
13 + [--column[=<options>] | --no-column]
14 [(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
15 'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
16 'git branch' (-m | -M) [<oldbranch>] <newbranch>
@@ -107,6 +108,14 @@ OPTIONS
108 default to color output.
109 Same as `--color=never`.
110
111 +--column[=<options>]::
112 +--no-column::
113 + Display branch listing in columns. See configuration variable
114 + column.branch for option syntax.`--column` and `--no-column`
115 + without options are equivalent to 'always' and 'never' respectively.
116 ++
117 +This option is only applicable in non-verbose mode.
118 +
119 -r::
120 --remotes::
121 List or delete (if used with -d) the remote-tracking branches.
Makefile
+1 -1
@@ -2168,7 +2168,7 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h
2168 builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
2169 builtin/tar-tree.o archive-tar.o: tar.h
2170 connect.o transport.o url.o http-backend.o: url.h
2171 -column.o help.o pager.o: column.h
2171 +builtin/branch.o column.o help.o pager.o: column.h
2172 http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
2173 http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
2174
builtin/branch.c
+28 -4
@@ -15,6 +15,8 @@
15 #include "branch.h"
16 #include "diff.h"
17 #include "revision.h"
18 +#include "string-list.h"
19 +#include "column.h"
20
21 static const char * const builtin_branch_usage[] = {
22 "git branch [options] [-r | -a] [--merged | --no-merged]",
@@ -53,6 +55,9 @@ static enum merge_filter {
55 } merge_filter;
56 static unsigned char merge_filter_ref[20];
57
58 +static struct string_list output = STRING_LIST_INIT_DUP;
59 +static unsigned int colopts;
60 +
61 static int parse_branch_color_slot(const char *var, int ofs)
62 {
63 if (!strcasecmp(var+ofs, "plain"))
@@ -70,6 +75,8 @@ static int parse_branch_color_slot(const char *var, int ofs)
75
76 static int git_branch_config(const char *var, const char *value, void *cb)
77 {
78 + if (!prefixcmp(var, "column."))
79 + return git_column_config(var, value, "branch", &colopts);
80 if (!strcmp(var, "color.branch")) {
81 branch_use_color = git_config_colorbool(var, value);
82 return 0;
@@ -474,7 +481,12 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
481 else if (verbose)
482 /* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
483 add_verbose_info(&out, item, verbose, abbrev);
477 - printf("%s\n", out.buf);
484 + if (column_active(colopts)) {
485 + assert(!verbose && "--column and --verbose are incompatible");
486 + string_list_append(&output, out.buf);
487 + } else {
488 + printf("%s\n", out.buf);
489 + }
490 strbuf_release(&name);
491 strbuf_release(&out);
492 }
@@ -727,6 +739,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
739 PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
740 opt_parse_merge_filter, (intptr_t) "HEAD",
741 },
742 + OPT_COLUMN(0, "column", &colopts, "list branches in columns"),
743 OPT_END(),
744 };
745
@@ -749,6 +762,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
762 }
763 hashcpy(merge_filter_ref, head_sha1);
764
765 +
766 argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
767 0);
768
@@ -760,12 +774,22 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
774
775 if (abbrev == -1)
776 abbrev = DEFAULT_ABBREV;
777 + finalize_colopts(&colopts, -1);
778 + if (verbose) {
779 + if (explicitly_enable_column(colopts))
780 + die(_("--column and --verbose are incompatible"));
781 + colopts = 0;
782 + }
783
784 if (delete)
785 return delete_branches(argc, argv, delete > 1, kinds);
766 - else if (list)
767 - return print_ref_list(kinds, detached, verbose, abbrev,
768 - with_commit, argv);
786 + else if (list) {
787 + int ret = print_ref_list(kinds, detached, verbose, abbrev,
788 + with_commit, argv);
789 + print_columns(&output, colopts, NULL);
790 + string_list_clear(&output, 0);
791 + return ret;
792 + }
793 else if (edit_description) {
794 const char *branch_name;
795 struct strbuf branch_ref = STRBUF_INIT;
t/t3200-branch.sh
+77
@@ -160,6 +160,83 @@ test_expect_success 'git branch --list -d t should fail' '
160 test_path_is_missing .git/refs/heads/t
161 '
162
163 +test_expect_success 'git branch --column' '
164 + COLUMNS=81 git branch --column=column >actual &&
165 + cat >expected <<\EOF &&
166 + a/b/c bam foo l * master n o/p r
167 + abc bar j/k m/m master2 o/o q
168 +EOF
169 + test_cmp expected actual
170 +'
171 +
172 +test_expect_success 'git branch --column with an extremely long branch name' '
173 + long=this/is/a/part/of/long/branch/name &&
174 + long=z$long/$long/$long/$long &&
175 + test_when_finished "git branch -d $long" &&
176 + git branch $long &&
177 + COLUMNS=80 git branch --column=column >actual &&
178 + cat >expected <<EOF &&
179 + a/b/c
180 + abc
181 + bam
182 + bar
183 + foo
184 + j/k
185 + l
186 + m/m
187 +* master
188 + master2
189 + n
190 + o/o
191 + o/p
192 + q
193 + r
194 + $long
195 +EOF
196 + test_cmp expected actual
197 +'
198 +
199 +test_expect_success 'git branch with column.*' '
200 + git config column.ui column &&
201 + git config column.branch "dense" &&
202 + COLUMNS=80 git branch >actual &&
203 + git config --unset column.branch &&
204 + git config --unset column.ui &&
205 + cat >expected <<\EOF &&
206 + a/b/c bam foo l * master n o/p r
207 + abc bar j/k m/m master2 o/o q
208 +EOF
209 + test_cmp expected actual
210 +'
211 +
212 +test_expect_success 'git branch --column -v should fail' '
213 + test_must_fail git branch --column -v
214 +'
215 +
216 +test_expect_success 'git branch -v with column.ui ignored' '
217 + git config column.ui column &&
218 + COLUMNS=80 git branch -v | cut -c -10 | sed "s/ *$//" >actual &&
219 + git config --unset column.ui &&
220 + cat >expected <<\EOF &&
221 + a/b/c
222 + abc
223 + bam
224 + bar
225 + foo
226 + j/k
227 + l
228 + m/m
229 +* master
230 + master2
231 + n
232 + o/o
233 + o/p
234 + q
235 + r
236 +EOF
237 + test_cmp expected actual
238 +'
239 +
240 mv .git/config .git/config-saved
241
242 test_expect_success 'git branch -m q q2 without config should succeed' '