Commit f4ed0af6 authored by Junio C Hamano's avatar Junio C Hamano

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
parents 9a7b0bca d96e3c15
......@@ -26,6 +26,7 @@
/git-cherry-pick
/git-clean
/git-clone
/git-column
/git-commit
/git-commit-tree
/git-config
......
......@@ -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
......
......@@ -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>
......@@ -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.
......
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 <[email protected]>
GIT
---
Part of the linkgit:git[1] suite
......@@ -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
------
......
......@@ -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>...
......@@ -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.
......
......@@ -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
......@@ -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
......@@ -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
......
......@@ -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);
......
......@@ -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]",
......@@ -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"))
......@@ -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;
......@@ -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);
}
......@@ -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(),
};
......@@ -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);
......@@ -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;
......
#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;
}
......@@ -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>...",
......@@ -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
......@@ -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);
......@@ -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(),
};
......@@ -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;
......
......@@ -9,6 +9,7 @@
#include "common-cmds.h"
#include "parse-options.h"
#include "run-command.h"
#include "column.h"
#include "help.h"
static struct man_viewer_list {
......@@ -30,6 +31,7 @@ enum help_format {
};
static int show_all = 0;
static unsigned int colopts;
static enum help_format help_format = HELP_FORMAT_NONE;
static struct option builtin_help_options[] = {
OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
......@@ -251,6 +253,8 @@ static int add_man_viewer_info(const char *var, const char *value)
static int git_help_config(const char *var, const char *value, void *cb)
{
if (!prefixcmp(var, "column."))
return git_column_config(var, value, "help", &colopts);
if (!strcmp(var, "help.format")) {
if (!value)
return config_error_nonbool(var);
......@@ -424,8 +428,9 @@ int cmd_help(int argc, const char **argv, const char *prefix)
parsed_help_format = help_format;
if (show_all) {
git_config(git_help_config, NULL);
printf(_("usage: %s%s"), _(git_usage_string), "\n\n");
list_commands(&main_cmds, &other_cmds);
list_commands(colopts, &main_cmds, &other_cmds);
printf("%s\n", _(git_more_info_string));
return 0;
}
......
......@@ -16,6 +16,7 @@
#include "revision.h"
#include "gpg-interface.h"
#include "sha1-array.h"
#include "column.h"
static const char * const git_tag_usage[] = {
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
......@@ -33,6 +34,7 @@ struct tag_filter {
};
static struct sha1_array points_at;
static unsigned int colopts;
static int match_pattern(const char **patterns, const char *ref)
{
......@@ -263,6 +265,8 @@ static int git_tag_config(const char *var, const char *value, void *cb)
int status = git_gpg_config(var, value, cb);
if (status)
return status;
if (!prefixcmp(var, "column."))
return git_column_config(var, value, "tag", &colopts);
return git_default_config(var, value, cb);
}
......@@ -459,6 +463,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
OPT_STRING('u', "local-user", &keyid, "key-id",
"use another key to sign the tag"),
OPT__FORCE(&force, "replace the tag if exists"),
OPT_COLUMN(0, "column", &colopts, "show tag list in columns"),
OPT_GROUP("Tag listing options"),
{
......@@ -495,9 +500,25 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
if (list + delete + verify > 1)
usage_with_options(git_tag_usage, options);
if (list)
return list_tags(argv, lines == -1 ? 0 : lines,
with_commit);
finalize_colopts(&colopts, -1);
if (list && lines != -1) {
if (explicitly_enable_column(colopts))
die(_("--column and -n are incompatible"));
colopts = 0;
}
if (list) {
int ret;
if (column_active(colopts)) {
struct column_options copts;
memset(&copts, 0, sizeof(copts));
copts.padding = 2;
run_column_filter(colopts, &copts);
}
ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit);
if (column_active(colopts))
stop_column_filter();
return ret;
}
if (lines != -1)
die(_("-n option is only allowed with -l."));
if (with_commit)
......
This diff is collapsed.
#ifndef COLUMN_H
#define COLUMN_H
#define COL_LAYOUT_MASK 0x000F
#define COL_ENABLE_MASK 0x0030 /* always, never or auto */
#define COL_PARSEOPT 0x0040 /* --column is given from cmdline */
#define COL_DENSE 0x0080 /* Shrink columns when possible,
making space for more columns */
#define COL_DISABLED 0x0000 /* must be zero */
#define COL_ENABLED 0x0010
#define COL_AUTO 0x0020
#define COL_LAYOUT(c) ((c) & COL_LAYOUT_MASK)
#define COL_COLUMN 0 /* Fill columns before rows */
#define COL_ROW 1 /* Fill rows before columns */
#define COL_PLAIN 15 /* one column */
#define explicitly_enable_column(c) \
(((c) & COL_PARSEOPT) && column_active(c))
struct column_options {
int width;
int padding;
const char *indent;
const char *nl;
};
struct option;
extern int parseopt_column_callback(const struct option *, const char *, int);
extern int git_column_config(const char *var, const char *value,
const char *command, unsigned int *colopts);
extern int finalize_colopts(unsigned int *colopts, int stdout_is_tty);
static inline int column_active(unsigned int colopts)
{
return (colopts & COL_ENABLE_MASK) == COL_ENABLED;
}
extern void print_columns(const struct string_list *list, unsigned int colopts,
const struct column_options *opts);
extern int run_column_filter(int colopts, const struct column_options *);
extern int stop_column_filter(void);
#endif
......@@ -20,6 +20,7 @@ git-cherry-pick mainporcelain
git-citool mainporcelain
git-clean mainporcelain
git-clone mainporcelain common
git-column purehelpers
git-commit mainporcelain common
git-commit-tree plumbingmanipulators
git-config ancillarymanipulators
......
......@@ -348,6 +348,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
{ "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
{ "clone", cmd_clone },
{ "column", cmd_column, RUN_SETUP_GENTLY },
{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config, RUN_SETUP_GENTLY },
......
......@@ -4,6 +4,8 @@
#include "levenshtein.h"
#include "help.h"
#include "common-cmds.h"
#include "string-list.h"
#include "column.h"
void add_cmdname(struct cmdnames *cmds, const char *name, int len)
{
......@@ -70,31 +72,25 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
cmds->cnt = cj;
}
static void pretty_print_string_list(struct cmdnames *cmds, int longest)
static void pretty_print_string_list(struct cmdnames *cmds,
unsigned int colopts)
{
int cols = 1, rows;
int space = longest + 1; /* min 1 SP between words */
int max_cols = term_columns() - 1; /* don't print *on* the edge */
int i, j;
if (space < max_cols)
cols = max_cols / space;
rows = DIV_ROUND_UP(cmds->cnt, cols);
for (i = 0; i < rows; i++) {
printf(" ");
struct string_list list = STRING_LIST_INIT_NODUP;
struct column_options copts;
int i;
for (j = 0; j < cols; j++) {
int n = j * rows + i;
int size = space;
if (n >= cmds->cnt)
break;
if (j == cols-1 || n + rows >= cmds->cnt)
size = 1;
printf("%-*s", size, cmds->names[n]->name);
}
putchar('\n');
}
for (i = 0; i < cmds->cnt; i++)
string_list_append(&list, cmds->names[i]->name);
/*
* always enable column display, we only consult column.*
* about layout strategy and stuff
*/
colopts = (colopts & ~COL_ENABLE_MASK) | COL_ENABLED;
memset(&copts, 0, sizeof(copts));
copts.indent = " ";
copts.padding = 2;
print_columns(&list, colopts, &copts);
string_list_clear(&list, 0);
}
static int is_executable(const char *name)
......@@ -203,29 +199,21 @@ void load_command_list(const char *prefix,
exclude_cmds(other_cmds, main_cmds);
}
void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds)
void list_commands(unsigned int colopts,
struct cmdnames *main_cmds, struct cmdnames *other_cmds)
{
int i, longest = 0;
for (i = 0; i < main_cmds->cnt; i++)
if (longest < main_cmds->names[i]->len)
longest = main_cmds->names[i]->len;
for (i = 0; i < other_cmds->cnt; i++)
if (longest < other_cmds->names[i]->len)
longest = other_cmds->names[i]->len;
if (main_cmds->cnt) {
const char *exec_path = git_exec_path();
printf_ln(_("available git commands in '%s'"), exec_path);
putchar('\n');
pretty_print_string_list(main_cmds, longest);
pretty_print_string_list(main_cmds, colopts);
putchar('\n');
}
if (other_cmds->cnt) {
printf_ln(_("git commands available from elsewhere on your $PATH"));
putchar('\n');
pretty_print_string_list(other_cmds, longest);
pretty_print_string_list(other_cmds, colopts);
putchar('\n');
}
}
......
......@@ -25,7 +25,6 @@ extern void add_cmdname(struct cmdnames *cmds, const char *name, int len);
/* Here we require that excludes is a sorted list. */
extern void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);
extern int is_in_cmdlist(struct cmdnames *cmds, const char *name);
extern void list_commands(struct cmdnames *main_cmds,
struct cmdnames *other_cmds);
extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds);
#endif /* HELP_H */
......@@ -73,7 +73,7 @@ void setup_pager(void)
{
const char *pager = git_pager(isatty(1));
if (!pager)
if (!pager || pager_in_use())
return;
/*
......
......@@ -234,5 +234,7 @@ extern int parse_opt_noop_cb(const struct option *, const char *, int);
PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
#define OPT__COLOR(var, h) \
OPT_COLOR_FLAG(0, "color", (var), (h))
#define OPT_COLUMN(s, l, v, h) \
{ OPTION_CALLBACK, (s), (l), (v), "style", (h), PARSE_OPT_OPTARG, parseopt_column_callback }
#endif
......@@ -160,6 +160,83 @@ test_expect_success 'git branch --list -d t should fail' '
test_path_is_missing .git/refs/heads/t
'
test_expect_success 'git branch --column' '
COLUMNS=81 git branch --column=column >actual &&
cat >expected <<\EOF &&
a/b/c bam foo l * master n o/p r
abc bar j/k m/m master2 o/o q
EOF
test_cmp expected actual
'
test_expect_success 'git branch --column with an extremely long branch name' '
long=this/is/a/part/of/long/branch/name &&
long=z$long/$long/$long/$long &&
test_when_finished "git branch -d $long" &&
git branch $long &&
COLUMNS=80 git branch --column=column >actual &&
cat >expected <<EOF &&
a/b/c
abc
bam
bar
foo
j/k
l
m/m
* master
master2
n
o/o
o/p
q
r
$long
EOF
test_cmp expected actual
'
test_expect_success 'git branch with column.*' '
git config column.ui column &&
git config column.branch "dense" &&
COLUMNS=80 git branch >actual &&
git config --unset column.branch &&
git config --unset column.ui &&
cat >expected <<\EOF &&
a/b/c bam foo l * master n o/p r
abc bar j/k m/m master2 o/o q
EOF
test_cmp expected actual
'
test_expect_success 'git branch --column -v should fail' '
test_must_fail git branch --column -v
'
test_expect_success 'git branch -v with column.ui ignored' '
git config column.ui column &&
COLUMNS=80 git branch -v | cut -c -10 | sed "s/ *$//" >actual &&
git config --unset column.ui &&
cat >expected <<\EOF &&
a/b/c
abc
bam
bar
foo
j/k
l
m/m
* master
master2
n
o/o
o/p
q
r
EOF
test_cmp expected actual
'
mv .git/config .git/config-saved