Skip to content

Commit

Permalink
Merge branch 'nd/columns'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gitster committed May 3, 2012
2 parents 9a7b0bc + d96e3c1 commit f4ed0af
Show file tree
Hide file tree
Showing 27 changed files with 1,105 additions and 48 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
/git-cherry-pick
/git-clean
/git-clone
/git-column
/git-commit
/git-commit-tree
/git-config
Expand Down
38 changes: 38 additions & 0 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,44 @@ color.ui::
`never` if you prefer git commands not to use color unless enabled
explicitly with some other configuration or the `--color` option.

column.ui::
Specify whether supported commands should output in columns.
This variable consists of a list of tokens separated by spaces
or commas:
+
--
`always`;;
always show in columns
`never`;;
never show in columns
`auto`;;
show in columns if the output is to the terminal
`column`;;
fill columns before rows (default)
`row`;;
fill rows before columns
`plain`;;
show in one column
`dense`;;
make unequal size columns to utilize more space
`nodense`;;
make equal size columns
--
+
This option defaults to 'never'.

column.branch::
Specify whether to output branch listing in `git branch` in columns.
See `column.ui` for details.

column.status::
Specify whether to output untracked files in `git status` in columns.
See `column.ui` for details.

column.tag::
Specify whether to output tag listing in `git tag` in columns.
See `column.ui` for details.

commit.status::
A boolean to enable/disable inclusion of status information in the
commit message template when using an editor to prepare the commit
Expand Down
9 changes: 9 additions & 0 deletions Documentation/git-branch.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SYNOPSIS
[verse]
'git branch' [--color[=<when>] | --no-color] [-r | -a]
[--list] [-v [--abbrev=<length> | --no-abbrev]]
[--column[=<options>] | --no-column]
[(--merged | --no-merged | --contains) [<commit>]] [<pattern>...]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
'git branch' (-m | -M) [<oldbranch>] <newbranch>
Expand Down Expand Up @@ -107,6 +108,14 @@ OPTIONS
default to color output.
Same as `--color=never`.

--column[=<options>]::
--no-column::
Display branch listing in columns. See configuration variable
column.branch for option syntax.`--column` and `--no-column`
without options are equivalent to 'always' and 'never' respectively.
+
This option is only applicable in non-verbose mode.

-r::
--remotes::
List or delete (if used with -d) the remote-tracking branches.
Expand Down
53 changes: 53 additions & 0 deletions Documentation/git-column.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
git-column(1)
=============

NAME
----
git-column - Display data in columns

SYNOPSIS
--------
[verse]
'git column' [--command=<name>] [--[raw-]mode=<mode>] [--width=<width>]
[--indent=<string>] [--nl=<string>] [--pading=<n>]

DESCRIPTION
-----------
This command formats its input into multiple columns.

OPTIONS
-------
--command=<name>::
Look up layout mode using configuration variable column.<name> and
column.ui.

--mode=<mode>::
Specify layout mode. See configuration variable column.ui for option
syntax.

--raw-mode=<n>::
Same as --mode but take mode encoded as a number. This is mainly used
by other commands that have already parsed layout mode.

--width=<width>::
Specify the terminal width. By default 'git column' will detect the
terminal width, or fall back to 80 if it is unable to do so.

--indent=<string>::
String to be printed at the beginning of each line.

--nl=<N>::
String to be printed at the end of each line,
including newline character.

--padding=<N>::
The number of spaces between columns. One space by default.


Author
------
Written by Nguyen Thai Ngoc Duy <pclouds@gmail.com>

GIT
---
Part of the linkgit:git[1] suite
7 changes: 7 additions & 0 deletions Documentation/git-status.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ configuration variable documented in linkgit:git-config[1].
Terminate entries with NUL, instead of LF. This implies
the `--porcelain` output format if no other format is given.

--column[=<options>]::
--no-column::
Display untracked files in columns. See configuration variable
column.status for option syntax.`--column` and `--no-column`
without options are equivalent to 'always' and 'never'
respectively.


OUTPUT
------
Expand Down
9 changes: 9 additions & 0 deletions Documentation/git-tag.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SYNOPSIS
<tagname> [<commit> | <object>]
'git tag' -d <tagname>...
'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]
[--column[=<options>] | --no-column] [<pattern>...]
[<pattern>...]
'git tag' -v <tagname>...

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

--column[=<options>]::
--no-column::
Display tag listing in columns. See configuration variable
column.tag for option syntax.`--column` and `--no-column`
without options are equivalent to 'always' and 'never' respectively.
+
This option is only applicable when listing tags without annotation lines.

--contains <commit>::
Only list tags which contain the specified commit.

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ LIB_OBJS += bulk-checkin.o
LIB_OBJS += bundle.o
LIB_OBJS += cache-tree.o
LIB_OBJS += color.o
LIB_OBJS += column.o
LIB_OBJS += combine-diff.o
LIB_OBJS += commit.o
LIB_OBJS += compat/obstack.o
Expand Down Expand Up @@ -818,6 +819,7 @@ BUILTIN_OBJS += builtin/checkout-index.o
BUILTIN_OBJS += builtin/checkout.o
BUILTIN_OBJS += builtin/clean.o
BUILTIN_OBJS += builtin/clone.o
BUILTIN_OBJS += builtin/column.o
BUILTIN_OBJS += builtin/commit-tree.o
BUILTIN_OBJS += builtin/commit.o
BUILTIN_OBJS += builtin/config.o
Expand Down Expand Up @@ -2224,6 +2226,7 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h
builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
builtin/tar-tree.o archive-tar.o: tar.h
connect.o transport.o url.o http-backend.o: url.h
builtin/branch.o builtin/commit.o builtin/tag.o column.o help.o pager.o: column.h
http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h

Expand Down
1 change: 1 addition & 0 deletions builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ extern int cmd_cherry(int argc, const char **argv, const char *prefix);
extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix);
extern int cmd_clone(int argc, const char **argv, const char *prefix);
extern int cmd_clean(int argc, const char **argv, const char *prefix);
extern int cmd_column(int argc, const char **argv, const char *prefix);
extern int cmd_commit(int argc, const char **argv, const char *prefix);
extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
extern int cmd_config(int argc, const char **argv, const char *prefix);
Expand Down
32 changes: 28 additions & 4 deletions builtin/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "branch.h"
#include "diff.h"
#include "revision.h"
#include "string-list.h"
#include "column.h"

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

static struct string_list output = STRING_LIST_INIT_DUP;
static unsigned int colopts;

static int parse_branch_color_slot(const char *var, int ofs)
{
if (!strcasecmp(var+ofs, "plain"))
Expand All @@ -70,6 +75,8 @@ static int parse_branch_color_slot(const char *var, int ofs)

static int git_branch_config(const char *var, const char *value, void *cb)
{
if (!prefixcmp(var, "column."))
return git_column_config(var, value, "branch", &colopts);
if (!strcmp(var, "color.branch")) {
branch_use_color = git_config_colorbool(var, value);
return 0;
Expand Down Expand Up @@ -482,7 +489,12 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
else if (verbose)
/* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
add_verbose_info(&out, item, verbose, abbrev);
printf("%s\n", out.buf);
if (column_active(colopts)) {
assert(!verbose && "--column and --verbose are incompatible");
string_list_append(&output, out.buf);
} else {
printf("%s\n", out.buf);
}
strbuf_release(&name);
strbuf_release(&out);
}
Expand Down Expand Up @@ -741,6 +753,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NONEG,
opt_parse_merge_filter, (intptr_t) "HEAD",
},
OPT_COLUMN(0, "column", &colopts, "list branches in columns"),
OPT_END(),
};

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


argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
0);

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

if (abbrev == -1)
abbrev = DEFAULT_ABBREV;
finalize_colopts(&colopts, -1);
if (verbose) {
if (explicitly_enable_column(colopts))
die(_("--column and --verbose are incompatible"));
colopts = 0;
}

if (delete)
return delete_branches(argc, argv, delete > 1, kinds, quiet);
else if (list)
return print_ref_list(kinds, detached, verbose, abbrev,
with_commit, argv);
else if (list) {
int ret = print_ref_list(kinds, detached, verbose, abbrev,
with_commit, argv);
print_columns(&output, colopts, NULL);
string_list_clear(&output, 0);
return ret;
}
else if (edit_description) {
const char *branch_name;
struct strbuf branch_ref = STRBUF_INIT;
Expand Down
59 changes: 59 additions & 0 deletions builtin/column.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "builtin.h"
#include "cache.h"
#include "strbuf.h"
#include "parse-options.h"
#include "string-list.h"
#include "column.h"

static const char * const builtin_column_usage[] = {
"git column [options]",
NULL
};
static unsigned int colopts;

static int column_config(const char *var, const char *value, void *cb)
{
return git_column_config(var, value, cb, &colopts);
}

int cmd_column(int argc, const char **argv, const char *prefix)
{
struct string_list list = STRING_LIST_INIT_DUP;
struct strbuf sb = STRBUF_INIT;
struct column_options copts;
const char *command = NULL, *real_command = NULL;
struct option options[] = {
OPT_STRING(0, "command", &real_command, "name", "lookup config vars"),
OPT_COLUMN(0, "mode", &colopts, "layout to use"),
OPT_INTEGER(0, "raw-mode", &colopts, "layout to use"),
OPT_INTEGER(0, "width", &copts.width, "Maximum width"),
OPT_STRING(0, "indent", &copts.indent, "string", "Padding space on left border"),
OPT_INTEGER(0, "nl", &copts.nl, "Padding space on right border"),
OPT_INTEGER(0, "padding", &copts.padding, "Padding space between columns"),
OPT_END()
};

/* This one is special and must be the first one */
if (argc > 1 && !prefixcmp(argv[1], "--command=")) {
command = argv[1] + 10;
git_config(column_config, (void *)command);
} else
git_config(column_config, NULL);

memset(&copts, 0, sizeof(copts));
copts.width = term_columns();
copts.padding = 1;
argc = parse_options(argc, argv, "", options, builtin_column_usage, 0);
if (argc)
usage_with_options(builtin_column_usage, options);
if (real_command || command) {
if (!real_command || !command || strcmp(real_command, command))
die(_("--command must be the first argument"));
}
finalize_colopts(&colopts, -1);
while (!strbuf_getline(&sb, stdin, '\n'))
string_list_append(&list, sb.buf);

print_columns(&list, colopts, &copts);
return 0;
}
7 changes: 7 additions & 0 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "quote.h"
#include "submodule.h"
#include "gpg-interface.h"
#include "column.h"

static const char * const builtin_commit_usage[] = {
"git commit [options] [--] <filepattern>...",
Expand Down Expand Up @@ -88,6 +89,7 @@ static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
static int no_post_rewrite, allow_empty_message;
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
static char *sign_commit;
static unsigned int colopts;

/*
* The default commit message cleanup mode will remove the lines
Expand Down Expand Up @@ -1173,6 +1175,8 @@ static int git_status_config(const char *k, const char *v, void *cb)
{
struct wt_status *s = cb;

if (!prefixcmp(k, "column."))
return git_column_config(k, v, "status", &colopts);
if (!strcmp(k, "status.submodulesummary")) {
int is_bool;
s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
Expand Down Expand Up @@ -1238,6 +1242,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
{ OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, "when",
"ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)",
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
OPT_COLUMN(0, "column", &colopts, "list untracked files in columns"),
OPT_END(),
};

Expand All @@ -1251,6 +1256,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix,
builtin_status_options,
builtin_status_usage, 0);
finalize_colopts(&colopts, -1);
s.colopts = colopts;

if (null_termination && status_format == STATUS_FORMAT_LONG)
status_format = STATUS_FORMAT_PORCELAIN;
Expand Down
Loading

0 comments on commit f4ed0af

Please sign in to comment.