Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit f4ed0af

Browse files
committed
Merge branch 'nd/columns'
A couple of commands learn --column option to produce columnar output. By Nguyễn Thái Ngọc Duy (9) and Zbigniew Jędrzejewski-Szmek (1) * nd/columns: tag: add --column column: support piping stdout to external git-column process status: add --column branch: add --column help: reuse print_columns() for help -a column: add dense layout support t9002: work around shells that are unable to set COLUMNS to 1 column: add columnar layout Stop starting pager recursively Add column layout skeleton and git-column
2 parents 9a7b0bc + d96e3c1 commit f4ed0af

27 files changed

+1105
-48
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
/git-cherry-pick
2727
/git-clean
2828
/git-clone
29+
/git-column
2930
/git-commit
3031
/git-commit-tree
3132
/git-config

Documentation/config.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,44 @@ color.ui::
856856
`never` if you prefer git commands not to use color unless enabled
857857
explicitly with some other configuration or the `--color` option.
858858

859+
column.ui::
860+
Specify whether supported commands should output in columns.
861+
This variable consists of a list of tokens separated by spaces
862+
or commas:
863+
+
864+
--
865+
`always`;;
866+
always show in columns
867+
`never`;;
868+
never show in columns
869+
`auto`;;
870+
show in columns if the output is to the terminal
871+
`column`;;
872+
fill columns before rows (default)
873+
`row`;;
874+
fill rows before columns
875+
`plain`;;
876+
show in one column
877+
`dense`;;
878+
make unequal size columns to utilize more space
879+
`nodense`;;
880+
make equal size columns
881+
--
882+
+
883+
This option defaults to 'never'.
884+
885+
column.branch::
886+
Specify whether to output branch listing in `git branch` in columns.
887+
See `column.ui` for details.
888+
889+
column.status::
890+
Specify whether to output untracked files in `git status` in columns.
891+
See `column.ui` for details.
892+
893+
column.tag::
894+
Specify whether to output tag listing in `git tag` in columns.
895+
See `column.ui` for details.
896+
859897
commit.status::
860898
A boolean to enable/disable inclusion of status information in the
861899
commit message template when using an editor to prepare the commit

Documentation/git-branch.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ SYNOPSIS
1010
[verse]
1111
'git branch' [--color[=<when>] | --no-color] [-r | -a]
1212
[--list] [-v [--abbrev=<length> | --no-abbrev]]
13+
[--column[=<options>] | --no-column]
1314
[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
1415
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
1516
'git branch' (-m | -M) [<oldbranch>] <newbranch>
@@ -107,6 +108,14 @@ OPTIONS
107108
default to color output.
108109
Same as `--color=never`.
109110

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+
110119
-r::
111120
--remotes::
112121
List or delete (if used with -d) the remote-tracking branches.

Documentation/git-column.txt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
git-column(1)
2+
=============
3+
4+
NAME
5+
----
6+
git-column - Display data in columns
7+
8+
SYNOPSIS
9+
--------
10+
[verse]
11+
'git column' [--command=<name>] [--[raw-]mode=<mode>] [--width=<width>]
12+
[--indent=<string>] [--nl=<string>] [--pading=<n>]
13+
14+
DESCRIPTION
15+
-----------
16+
This command formats its input into multiple columns.
17+
18+
OPTIONS
19+
-------
20+
--command=<name>::
21+
Look up layout mode using configuration variable column.<name> and
22+
column.ui.
23+
24+
--mode=<mode>::
25+
Specify layout mode. See configuration variable column.ui for option
26+
syntax.
27+
28+
--raw-mode=<n>::
29+
Same as --mode but take mode encoded as a number. This is mainly used
30+
by other commands that have already parsed layout mode.
31+
32+
--width=<width>::
33+
Specify the terminal width. By default 'git column' will detect the
34+
terminal width, or fall back to 80 if it is unable to do so.
35+
36+
--indent=<string>::
37+
String to be printed at the beginning of each line.
38+
39+
--nl=<N>::
40+
String to be printed at the end of each line,
41+
including newline character.
42+
43+
--padding=<N>::
44+
The number of spaces between columns. One space by default.
45+
46+
47+
Author
48+
------
49+
Written by Nguyen Thai Ngoc Duy <[email protected]>
50+
51+
GIT
52+
---
53+
Part of the linkgit:git[1] suite

Documentation/git-status.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ configuration variable documented in linkgit:git-config[1].
7777
Terminate entries with NUL, instead of LF. This implies
7878
the `--porcelain` output format if no other format is given.
7979

80+
--column[=<options>]::
81+
--no-column::
82+
Display untracked files in columns. See configuration variable
83+
column.status for option syntax.`--column` and `--no-column`
84+
without options are equivalent to 'always' and 'never'
85+
respectively.
86+
8087

8188
OUTPUT
8289
------

Documentation/git-tag.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ SYNOPSIS
1313
<tagname> [<commit> | <object>]
1414
'git tag' -d <tagname>...
1515
'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]
16+
[--column[=<options>] | --no-column] [<pattern>...]
1617
[<pattern>...]
1718
'git tag' -v <tagname>...
1819

@@ -84,6 +85,14 @@ OPTIONS
8485
using fnmatch(3)). Multiple patterns may be given; if any of
8586
them matches, the tag is shown.
8687

88+
--column[=<options>]::
89+
--no-column::
90+
Display tag listing in columns. See configuration variable
91+
column.tag for option syntax.`--column` and `--no-column`
92+
without options are equivalent to 'always' and 'never' respectively.
93+
+
94+
This option is only applicable when listing tags without annotation lines.
95+
8796
--contains <commit>::
8897
Only list tags which contain the specified commit.
8998

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,7 @@ LIB_OBJS += bulk-checkin.o
688688
LIB_OBJS += bundle.o
689689
LIB_OBJS += cache-tree.o
690690
LIB_OBJS += color.o
691+
LIB_OBJS += column.o
691692
LIB_OBJS += combine-diff.o
692693
LIB_OBJS += commit.o
693694
LIB_OBJS += compat/obstack.o
@@ -818,6 +819,7 @@ BUILTIN_OBJS += builtin/checkout-index.o
818819
BUILTIN_OBJS += builtin/checkout.o
819820
BUILTIN_OBJS += builtin/clean.o
820821
BUILTIN_OBJS += builtin/clone.o
822+
BUILTIN_OBJS += builtin/column.o
821823
BUILTIN_OBJS += builtin/commit-tree.o
822824
BUILTIN_OBJS += builtin/commit.o
823825
BUILTIN_OBJS += builtin/config.o
@@ -2224,6 +2226,7 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h
22242226
builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
22252227
builtin/tar-tree.o archive-tar.o: tar.h
22262228
connect.o transport.o url.o http-backend.o: url.h
2229+
builtin/branch.o builtin/commit.o builtin/tag.o column.o help.o pager.o: column.h
22272230
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
22282231
http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
22292232

builtin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ extern int cmd_cherry(int argc, const char **argv, const char *prefix);
6161
extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);
6262
extern int cmd_clone(int argc, const char **argv, const char *prefix);
6363
extern int cmd_clean(int argc, const char **argv, const char *prefix);
64+
extern int cmd_column(int argc, const char **argv, const char *prefix);
6465
extern int cmd_commit(int argc, const char **argv, const char *prefix);
6566
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
6667
extern int cmd_config(int argc, const char **argv, const char *prefix);

builtin/branch.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "branch.h"
1616
#include "diff.h"
1717
#include "revision.h"
18+
#include "string-list.h"
19+
#include "column.h"
1820

1921
static const char * const builtin_branch_usage[] = {
2022
"git branch [options] [-r | -a] [--merged | --no-merged]",
@@ -53,6 +55,9 @@ static enum merge_filter {
5355
} merge_filter;
5456
static unsigned char merge_filter_ref[20];
5557

58+
static struct string_list output = STRING_LIST_INIT_DUP;
59+
static unsigned int colopts;
60+
5661
static int parse_branch_color_slot(const char *var, int ofs)
5762
{
5863
if (!strcasecmp(var+ofs, "plain"))
@@ -70,6 +75,8 @@ static int parse_branch_color_slot(const char *var, int ofs)
7075

7176
static int git_branch_config(const char *var, const char *value, void *cb)
7277
{
78+
if (!prefixcmp(var, "column."))
79+
return git_column_config(var, value, "branch", &colopts);
7380
if (!strcmp(var, "color.branch")) {
7481
branch_use_color = git_config_colorbool(var, value);
7582
return 0;
@@ -482,7 +489,12 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
482489
else if (verbose)
483490
/* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
484491
add_verbose_info(&out, item, verbose, abbrev);
485-
printf("%s\n", out.buf);
492+
if (column_active(colopts)) {
493+
assert(!verbose && "--column and --verbose are incompatible");
494+
string_list_append(&output, out.buf);
495+
} else {
496+
printf("%s\n", out.buf);
497+
}
486498
strbuf_release(&name);
487499
strbuf_release(&out);
488500
}
@@ -741,6 +753,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
741753
PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
742754
opt_parse_merge_filter, (intptr_t) "HEAD",
743755
},
756+
OPT_COLUMN(0, "column", &colopts, "list branches in columns"),
744757
OPT_END(),
745758
};
746759

@@ -763,6 +776,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
763776
}
764777
hashcpy(merge_filter_ref, head_sha1);
765778

779+
766780
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
767781
0);
768782

@@ -774,12 +788,22 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
774788

775789
if (abbrev == -1)
776790
abbrev = DEFAULT_ABBREV;
791+
finalize_colopts(&colopts, -1);
792+
if (verbose) {
793+
if (explicitly_enable_column(colopts))
794+
die(_("--column and --verbose are incompatible"));
795+
colopts = 0;
796+
}
777797

778798
if (delete)
779799
return delete_branches(argc, argv, delete > 1, kinds, quiet);
780-
else if (list)
781-
return print_ref_list(kinds, detached, verbose, abbrev,
782-
with_commit, argv);
800+
else if (list) {
801+
int ret = print_ref_list(kinds, detached, verbose, abbrev,
802+
with_commit, argv);
803+
print_columns(&output, colopts, NULL);
804+
string_list_clear(&output, 0);
805+
return ret;
806+
}
783807
else if (edit_description) {
784808
const char *branch_name;
785809
struct strbuf branch_ref = STRBUF_INIT;

builtin/column.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "builtin.h"
2+
#include "cache.h"
3+
#include "strbuf.h"
4+
#include "parse-options.h"
5+
#include "string-list.h"
6+
#include "column.h"
7+
8+
static const char * const builtin_column_usage[] = {
9+
"git column [options]",
10+
NULL
11+
};
12+
static unsigned int colopts;
13+
14+
static int column_config(const char *var, const char *value, void *cb)
15+
{
16+
return git_column_config(var, value, cb, &colopts);
17+
}
18+
19+
int cmd_column(int argc, const char **argv, const char *prefix)
20+
{
21+
struct string_list list = STRING_LIST_INIT_DUP;
22+
struct strbuf sb = STRBUF_INIT;
23+
struct column_options copts;
24+
const char *command = NULL, *real_command = NULL;
25+
struct option options[] = {
26+
OPT_STRING(0, "command", &real_command, "name", "lookup config vars"),
27+
OPT_COLUMN(0, "mode", &colopts, "layout to use"),
28+
OPT_INTEGER(0, "raw-mode", &colopts, "layout to use"),
29+
OPT_INTEGER(0, "width", &copts.width, "Maximum width"),
30+
OPT_STRING(0, "indent", &copts.indent, "string", "Padding space on left border"),
31+
OPT_INTEGER(0, "nl", &copts.nl, "Padding space on right border"),
32+
OPT_INTEGER(0, "padding", &copts.padding, "Padding space between columns"),
33+
OPT_END()
34+
};
35+
36+
/* This one is special and must be the first one */
37+
if (argc > 1 && !prefixcmp(argv[1], "--command=")) {
38+
command = argv[1] + 10;
39+
git_config(column_config, (void *)command);
40+
} else
41+
git_config(column_config, NULL);
42+
43+
memset(&copts, 0, sizeof(copts));
44+
copts.width = term_columns();
45+
copts.padding = 1;
46+
argc = parse_options(argc, argv, "", options, builtin_column_usage, 0);
47+
if (argc)
48+
usage_with_options(builtin_column_usage, options);
49+
if (real_command || command) {
50+
if (!real_command || !command || strcmp(real_command, command))
51+
die(_("--command must be the first argument"));
52+
}
53+
finalize_colopts(&colopts, -1);
54+
while (!strbuf_getline(&sb, stdin, '\n'))
55+
string_list_append(&list, sb.buf);
56+
57+
print_columns(&list, colopts, &copts);
58+
return 0;
59+
}

0 commit comments

Comments
 (0)