From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v7 01/9] Add column layout skeleton and git-column
Date: Tue, 13 Mar 2012 19:09:13 +0700 [thread overview]
Message-ID: <1294ed94f981a7029b47a44143c3eb9fb6b820f1.1331638663.git.pclouds@gmail.com> (raw)
In-Reply-To: <cover.1331638663.git.pclouds@gmail.com>
A column option string consists of many token separated by either
a space or a comma. A token belongs to one of three groups:
- enabling: always, never and auto
- layout mode: currently plain (which does not layout at all)
- other future tuning flags
git-column can be used to pipe output to from a command that wants
column layout, but not to mess with its own output code. Simpler output
code can be changed to use column layout code directly.
Thanks-to: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
.gitignore | 1 +
Documentation/config.txt | 18 +++++
Documentation/git-column.txt | 53 +++++++++++++
Makefile | 3 +
builtin.h | 1 +
builtin/column.c | 59 +++++++++++++++
column.c | 170 ++++++++++++++++++++++++++++++++++++++++++
column.h | 35 +++++++++
command-list.txt | 1 +
git.c | 1 +
parse-options.h | 2 +
t/t9002-column.sh | 45 +++++++++++
12 files changed, 389 insertions(+), 0 deletions(-)
create mode 100644 Documentation/git-column.txt
create mode 100644 builtin/column.c
create mode 100644 column.c
create mode 100644 column.h
create mode 100755 t/t9002-column.sh
diff --git a/.gitignore b/.gitignore
index 87fcc5f..2540264 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@
/git-cherry-pick
/git-clean
/git-clone
+/git-column
/git-commit
/git-commit-tree
/git-config
diff --git a/Documentation/config.txt b/Documentation/config.txt
index abeb82b..147c41c 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -821,6 +821,24 @@ 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
+`plain`;;
+ show in one column
+--
++
+ This option defaults to 'never'.
+
commit.status::
A boolean to enable/disable inclusion of status information in the
commit message template when using an editor to prepare the commit
diff --git a/Documentation/git-column.txt b/Documentation/git-column.txt
new file mode 100644
index 0000000..9be16ee
--- /dev/null
+++ b/Documentation/git-column.txt
@@ -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
diff --git a/Makefile b/Makefile
index a0de4e9..0998f0d 100644
--- a/Makefile
+++ b/Makefile
@@ -646,6 +646,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
@@ -774,6 +775,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
@@ -2166,6 +2168,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
+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
diff --git a/builtin.h b/builtin.h
index 857b9c8..338f540 100644
--- a/builtin.h
+++ b/builtin.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);
diff --git a/builtin/column.c b/builtin/column.c
new file mode 100644
index 0000000..5ea798a
--- /dev/null
+++ b/builtin/column.c
@@ -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;
+}
diff --git a/column.c b/column.c
new file mode 100644
index 0000000..f0877c0
--- /dev/null
+++ b/column.c
@@ -0,0 +1,170 @@
+#include "cache.h"
+#include "column.h"
+#include "string-list.h"
+#include "parse-options.h"
+
+/* Display without layout when not enabled */
+static void display_plain(const struct string_list *list,
+ const char *indent, const char *nl)
+{
+ int i;
+
+ for (i = 0; i < list->nr; i++)
+ printf("%s%s%s", indent, list->items[i].string, nl);
+}
+
+void print_columns(const struct string_list *list, unsigned int colopts,
+ const struct column_options *opts)
+{
+ struct column_options nopts;
+
+ if (!list->nr)
+ return;
+ assert(COL_ENABLE(colopts) != COL_AUTO);
+
+ memset(&nopts, 0, sizeof(nopts));
+ nopts.indent = opts && opts->indent ? opts->indent : "";
+ nopts.nl = opts && opts->nl ? opts->nl : "\n";
+ nopts.padding = opts ? opts->padding : 1;
+ nopts.width = opts && opts->width ? opts->width : term_columns() - 1;
+ if (!COL_ENABLE(colopts)) {
+ display_plain(list, "", "\n");
+ return;
+ }
+ switch (COL_LAYOUT(colopts)) {
+ case COL_PLAIN:
+ display_plain(list, nopts.indent, nopts.nl);
+ break;
+ default:
+ die("BUG: invalid layout mode %d", COL_LAYOUT(colopts));
+ }
+}
+
+int finalize_colopts(unsigned int *colopts, int stdout_is_tty)
+{
+ if (COL_ENABLE(*colopts) == COL_AUTO) {
+ if (stdout_is_tty < 0)
+ stdout_is_tty = isatty(1);
+ *colopts &= ~COL_ENABLE_MASK;
+ if (stdout_is_tty)
+ *colopts |= COL_ENABLED;
+ }
+ return 0;
+}
+
+struct colopt {
+ const char *name;
+ unsigned int value;
+ unsigned int mask;
+};
+
+#define LAYOUT_SET 1
+#define ENABLE_SET 2
+
+static int parse_option(const char *arg, int len, unsigned int *colopts,
+ int *group_set)
+{
+ struct colopt opts[] = {
+ { "always", COL_ENABLED, COL_ENABLE_MASK },
+ { "never", COL_DISABLED, COL_ENABLE_MASK },
+ { "auto", COL_AUTO, COL_ENABLE_MASK },
+ { "plain", COL_PLAIN, COL_LAYOUT_MASK },
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(opts); i++) {
+ int arg_len = len, name_len;
+ const char *arg_str = arg;
+
+ name_len = strlen(opts[i].name);
+ if (arg_len != name_len ||
+ strncmp(arg_str, opts[i].name, name_len))
+ continue;
+
+ switch (opts[i].mask) {
+ case COL_ENABLE_MASK:
+ *group_set |= ENABLE_SET;
+ break;
+ case COL_LAYOUT_MASK:
+ *group_set |= LAYOUT_SET;
+ break;
+ }
+
+ if (opts[i].mask)
+ *colopts = (*colopts & ~opts[i].mask) | opts[i].value;
+ return 0;
+ }
+
+ return error("unsupported option '%s'", arg);
+}
+
+static int parse_config(unsigned int *colopts, const char *value)
+{
+ const char *sep = " ,";
+ int group_set = 0;
+
+ while (*value) {
+ int len = strcspn(value, sep);
+ if (len) {
+ if (parse_option(value, len, colopts, &group_set))
+ return -1;
+
+ value += len;
+ }
+ value += strspn(value, sep);
+ }
+ /*
+ * Setting layout implies "always" if neither always, never
+ * nor auto is specified.
+ *
+ * Current COL_ENABLE() value is disregarded. This means if
+ * you set column.ui = auto and pass --column=row, then "auto"
+ * will become "always".
+ */
+ if ((group_set & LAYOUT_SET) && !(group_set & ENABLE_SET))
+ *colopts = (*colopts & ~COL_ENABLE_MASK) | COL_ENABLED;
+ return 0;
+}
+
+static int column_config(const char *var, const char *value,
+ const char *key, unsigned int *colopts)
+{
+ if (parse_config(colopts, value))
+ return error("invalid %s mode %s", key, value);
+ return 0;
+}
+
+int git_column_config(const char *var, const char *value,
+ const char *command, unsigned int *colopts)
+{
+ if (!strcmp(var, "column.ui"))
+ return column_config(var, value, "column.ui", colopts);
+
+ if (command) {
+ struct strbuf sb = STRBUF_INIT;
+ int ret = 0;
+ strbuf_addf(&sb, "column.%s", command);
+ if (!strcmp(var, sb.buf))
+ ret = column_config(var, value, sb.buf, colopts);
+ strbuf_release(&sb);
+ return ret;
+ }
+
+ return 0;
+}
+
+int parseopt_column_callback(const struct option *opt,
+ const char *arg, int unset)
+{
+ unsigned int *colopts = opt->value;
+ *colopts |= COL_PARSEOPT;
+ *colopts &= ~COL_ENABLE_MASK;
+ if (unset) /* --no-column == never */
+ return 0;
+ /* --column == always unless "arg" states otherwise */
+ *colopts |= COL_ENABLED;
+ if (arg)
+ return parse_config(colopts, arg);
+
+ return 0;
+}
diff --git a/column.h b/column.h
new file mode 100644
index 0000000..778a71c
--- /dev/null
+++ b/column.h
@@ -0,0 +1,35 @@
+#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_ENABLE(c) ((c) & COL_ENABLE_MASK)
+#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_PLAIN 15 /* one column */
+
+#define explicitly_enable_column(c) \
+ (((c) & COL_PARSEOPT) && COL_ENABLE(c) == COL_ENABLED)
+
+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);
+
+extern void print_columns(const struct string_list *list, unsigned int colopts,
+ const struct column_options *opts);
+
+#endif
diff --git a/command-list.txt b/command-list.txt
index a36ee9b..fe06f15 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -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
diff --git a/git.c b/git.c
index 3805616..ee727cb 100644
--- a/git.c
+++ b/git.c
@@ -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 },
diff --git a/parse-options.h b/parse-options.h
index 2e811dc..56fcafd 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -238,5 +238,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
diff --git a/t/t9002-column.sh b/t/t9002-column.sh
new file mode 100755
index 0000000..a7f3cd9
--- /dev/null
+++ b/t/t9002-column.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+test_description='git column'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ cat >lista <<\EOF
+one
+two
+three
+four
+five
+six
+seven
+eight
+nine
+ten
+eleven
+EOF
+'
+
+test_expect_success 'never' '
+ git column --indent=Z --mode=never <lista >actual &&
+ test_cmp lista actual
+'
+
+test_expect_success 'always' '
+ cat >expected <<\EOF &&
+Zone
+Ztwo
+Zthree
+Zfour
+Zfive
+Zsix
+Zseven
+Zeight
+Znine
+Zten
+Zeleven
+EOF
+ git column --indent=Z --mode=plain <lista >actual &&
+ test_cmp expected actual
+'
+
+test_done
--
1.7.8.36.g69ee2
next prev parent reply other threads:[~2012-03-13 12:06 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-25 11:41 [PATCH v6 00/11] Column display Nguyễn Thái Ngọc Duy
2012-02-25 11:41 ` [PATCH v6 01/11] column: add API to print items in columns Nguyễn Thái Ngọc Duy
2012-02-25 11:41 ` [PATCH v6 02/11] Add git-column and column mode parsing Nguyễn Thái Ngọc Duy
2012-02-27 20:09 ` Ramsay Jones
2012-02-28 11:00 ` Nguyen Thai Ngoc Duy
2012-02-25 11:41 ` [PATCH v6 03/11] Stop starting pager recursively Nguyễn Thái Ngọc Duy
2012-02-25 11:41 ` [PATCH v6 04/11] column: add columnar layout Nguyễn Thái Ngọc Duy
2012-02-25 11:41 ` [PATCH v6 05/11] column: support columns with different widths Nguyễn Thái Ngọc Duy
2012-02-26 23:12 ` Junio C Hamano
2012-02-25 11:41 ` [PATCH v6 06/11] column: add column.ui for default column output settings Nguyễn Thái Ngọc Duy
2012-02-27 6:20 ` Junio C Hamano
2012-02-27 7:04 ` Nguyen Thai Ngoc Duy
2012-02-25 11:41 ` [PATCH v6 07/11] help: reuse print_columns() for help -a Nguyễn Thái Ngọc Duy
2012-02-25 11:41 ` [PATCH v6 08/11] branch: add --column Nguyễn Thái Ngọc Duy
2012-02-25 11:41 ` [PATCH v6 09/11] status: " Nguyễn Thái Ngọc Duy
2012-02-25 11:41 ` [PATCH v6 10/11] column: support piping stdout to external git-column process Nguyễn Thái Ngọc Duy
2012-02-25 11:41 ` [PATCH v6 11/11] tag: add --column Nguyễn Thái Ngọc Duy
2012-02-26 23:02 ` [PATCH v6 00/11] Column display Junio C Hamano
2012-02-27 0:40 ` Nguyen Thai Ngoc Duy
2012-02-27 1:37 ` Junio C Hamano
2012-02-27 7:46 ` Junio C Hamano
2012-02-27 8:14 ` Nguyen Thai Ngoc Duy
2012-02-28 11:58 ` [PATCH v7 00/10] " Nguyễn Thái Ngọc Duy
2012-02-28 11:58 ` [PATCH v7 01/10] Add git-column for columnar display Nguyễn Thái Ngọc Duy
2012-02-28 18:10 ` Junio C Hamano
2012-03-02 12:36 ` Nguyen Thai Ngoc Duy
2012-02-28 11:58 ` [PATCH v7 02/10] Stop starting pager recursively Nguyễn Thái Ngọc Duy
2012-02-28 18:13 ` Junio C Hamano
2012-02-28 19:10 ` Junio C Hamano
2012-02-29 1:54 ` Nguyen Thai Ngoc Duy
2012-02-29 3:37 ` Junio C Hamano
2012-02-29 3:40 ` Nguyen Thai Ngoc Duy
2012-02-29 4:51 ` Junio C Hamano
2012-02-28 11:58 ` [PATCH v7 03/10] column: add columnar layout Nguyễn Thái Ngọc Duy
2012-02-28 18:22 ` Junio C Hamano
2012-02-28 11:58 ` [PATCH v7 04/10] column: add dense layout support Nguyễn Thái Ngọc Duy
2012-02-28 18:27 ` Junio C Hamano
2012-03-02 12:47 ` Nguyen Thai Ngoc Duy
2012-03-02 17:37 ` Junio C Hamano
2012-02-28 11:58 ` [PATCH v7 05/10] column: add column.ui for default column output settings Nguyễn Thái Ngọc Duy
2012-02-28 18:44 ` Junio C Hamano
2012-02-28 11:58 ` [PATCH v7 06/10] help: reuse print_columns() for help -a Nguyễn Thái Ngọc Duy
2012-02-28 11:58 ` [PATCH v7 07/10] branch: add --column Nguyễn Thái Ngọc Duy
2012-02-28 11:58 ` [PATCH v7 08/10] status: " Nguyễn Thái Ngọc Duy
2012-02-28 11:58 ` [PATCH v7 09/10] column: support piping stdout to external git-column process Nguyễn Thái Ngọc Duy
2012-02-28 11:58 ` [PATCH v7 10/10] tag: add --column Nguyễn Thái Ngọc Duy
2012-03-02 11:25 ` [PATCH v7 00/10] Column display Thomas Rast
2012-03-11 7:02 ` Nguyen Thai Ngoc Duy
2012-03-12 6:02 ` Junio C Hamano
2012-03-13 12:09 ` [PATCH v7 00/9] " Nguyễn Thái Ngọc Duy
2012-03-13 12:08 ` Nguyen Thai Ngoc Duy
2012-03-13 12:09 ` Nguyễn Thái Ngọc Duy [this message]
2012-03-13 12:09 ` [PATCH v7 02/9] Stop starting pager recursively Nguyễn Thái Ngọc Duy
2012-03-13 12:09 ` [PATCH v7 03/9] column: add columnar layout Nguyễn Thái Ngọc Duy
2012-03-13 12:09 ` [PATCH v7 04/9] column: add dense layout support Nguyễn Thái Ngọc Duy
2012-03-13 12:09 ` [PATCH v7 05/9] help: reuse print_columns() for help -a Nguyễn Thái Ngọc Duy
2012-03-13 12:09 ` [PATCH v7 06/9] branch: add --column Nguyễn Thái Ngọc Duy
2012-03-13 12:09 ` [PATCH v7 07/9] status: " Nguyễn Thái Ngọc Duy
2012-03-13 12:09 ` [PATCH v7 08/9] column: support piping stdout to external git-column process Nguyễn Thái Ngọc Duy
2012-03-13 12:09 ` [PATCH v7 09/9] tag: add --column Nguyễn Thái Ngọc Duy
2012-03-13 12:11 ` [PATCH v7 10/9] ls-files: support --column Nguyễn Thái Ngọc Duy
2012-03-13 12:11 ` [PATCH v7 11/9] column: support "denser" mode Nguyễn Thái Ngọc Duy
2012-03-13 12:11 ` [PATCH v7 12/9] column: support grouping entries Nguyễn Thái Ngọc Duy
2012-03-13 22:24 ` [PATCH v7 01/9] Add column layout skeleton and git-column Junio C Hamano
2012-03-14 11:17 ` Nguyen Thai Ngoc Duy
2012-03-14 18:29 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1294ed94f981a7029b47a44143c3eb9fb6b820f1.1331638663.git.pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).