All of lore.kernel.org
 help / color / mirror / Atom feed
* (unknown), 
@ 2012-02-09 23:58 Zbigniew Jędrzejewski-Szmek
  2012-02-09 23:58 ` [PATCH 1/4] Move git_version_string to help.c in preparation for diff changes Zbigniew Jędrzejewski-Szmek
                   ` (3 more replies)
  0 siblings, 4 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-09 23:58 UTC (permalink / raw)
  To: git; +Cc: gitster, Michael J Gruber

Hi,

this is a patch series to make 'git diff --stat' use full terminal
width instead of hard-coded 80 columns.

This is quite useful when working on projects with nested directory
structure, e.g. Java:
 .../{ => workspace/tasks}/GetTaskResultAction.java |   10 +-
 .../tasks}/RemoveAllAbortedTasksAction.java        |    7 +-
 .../tasks}/RemoveAllFailedTasksAction.java         |    7 +-
is changed to display full paths if the terminal window is wide
enough.

Git usually uses the full terminal width automatically, so it should
do so with --stat too.

The "big" functional change in the patch series is s/80/term_columns()/
in show_stats(). The fourth patch also changes the partitioning of
available columns to dedicate more space to file names.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 1/4] Move git_version_string to help.c in preparation for diff changes
  2012-02-09 23:58 (unknown), Zbigniew Jędrzejewski-Szmek
@ 2012-02-09 23:58 ` Zbigniew Jędrzejewski-Szmek
  2012-02-10  0:46   ` Junio C Hamano
  2012-02-09 23:58 ` [PATCH 2/4] help.c: make term_columns() cached and export it Zbigniew Jędrzejewski-Szmek
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-09 23:58 UTC (permalink / raw)
  To: git; +Cc: gitster, Michael J Gruber, Zbigniew Jędrzejewski-Szmek

git_version_string is declared in builtins.h, but lived in git.c.

When diff.c starts to use functions from help.c, linking against
libgit.a will fail, unless git.o containing git_version_string is
linked too. This variable is only used in a couple of places, help.c
being one of them. git.o is biggish, so it let's move
git_version_string to help.c.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 Makefile |    5 +++--
 git.c    |    2 --
 help.c   |    2 ++
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index a782409..264fe4f 100644
--- a/Makefile
+++ b/Makefile
@@ -1851,7 +1851,7 @@ strip: $(PROGRAMS) git$X
 	$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
 
 git.o: common-cmds.h
-git.sp git.s git.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"' \
+git.sp git.s git.o: EXTRA_CPPFLAGS = \
 	'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
 	'-DGIT_MAN_PATH="$(mandir_SQ)"' \
 	'-DGIT_INFO_PATH="$(infodir_SQ)"'
@@ -1860,7 +1860,8 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
 		$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
 
-help.sp help.o: common-cmds.h
+help.o: common-cmds.h
+help.sp help.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"'
 
 builtin/help.sp builtin/help.o: common-cmds.h
 builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
diff --git a/git.c b/git.c
index 3805616..a24a0fd 100644
--- a/git.c
+++ b/git.c
@@ -256,8 +256,6 @@ static int handle_alias(int *argcp, const char ***argv)
 	return ret;
 }
 
-const char git_version_string[] = GIT_VERSION;
-
 #define RUN_SETUP		(1<<0)
 #define RUN_SETUP_GENTLY	(1<<1)
 #define USE_PAGER		(1<<2)
diff --git a/help.c b/help.c
index cbbe966..bc15066 100644
--- a/help.c
+++ b/help.c
@@ -409,6 +409,8 @@ const char *help_unknown_cmd(const char *cmd)
 	exit(1);
 }
 
+const char git_version_string[] = GIT_VERSION;
+
 int cmd_version(int argc, const char **argv, const char *prefix)
 {
 	printf("git version %s\n", git_version_string);
-- 
1.7.9.rc2.127.gcb239

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 2/4] help.c: make term_columns() cached and export it
  2012-02-09 23:58 (unknown), Zbigniew Jędrzejewski-Szmek
  2012-02-09 23:58 ` [PATCH 1/4] Move git_version_string to help.c in preparation for diff changes Zbigniew Jędrzejewski-Szmek
@ 2012-02-09 23:58 ` Zbigniew Jędrzejewski-Szmek
  2012-02-10  0:50   ` Junio C Hamano
  2012-02-09 23:58 ` [PATCH 3/4] diff --stat: use the real terminal width Zbigniew Jędrzejewski-Szmek
  2012-02-09 23:58 ` [PATCH 4/4] diff --stat: use most of the space for file names Zbigniew Jędrzejewski-Szmek
  3 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-09 23:58 UTC (permalink / raw)
  To: git; +Cc: gitster, Michael J Gruber, Zbigniew Jędrzejewski-Szmek

Since term_columns() will usually fail, when a pager is installed,
the cache is primed before the pager is installed. If a pager is not
installed, then the cache will be set on first use.

Conforms to The Single UNIX Specification, Version 2
(http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003).

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 help.c  |   31 +++++++++++++++++++++++--------
 help.h  |    2 ++
 pager.c |    5 +++++
 3 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/help.c b/help.c
index bc15066..75b8d4b 100644
--- a/help.c
+++ b/help.c
@@ -5,26 +5,41 @@
 #include "help.h"
 #include "common-cmds.h"
 
-/* most GUI terminals set COLUMNS (although some don't export it) */
-static int term_columns(void)
+/* cache for term_columns() value. Set on first use or when
+ * installing a pager and replacing stdout.
+ */
+static int term_columns_cache;
+
+/* Return cached value (iff set) or $COLUMNS (iff set and positive) or
+ * ioctl(1, TIOCGWINSZ).ws_col (if positive) or 80.
+ *
+ * $COLUMNS even if set, is usually not exported, so
+ * the variable can be used to override autodection.
+ */
+int term_columns(void)
 {
-	char *col_string = getenv("COLUMNS");
-	int n_cols;
+	if (term_columns_cache)
+		return term_columns_cache;
 
-	if (col_string && (n_cols = atoi(col_string)) > 0)
-		return n_cols;
+	{
+		char *col_string = getenv("COLUMNS");
+		int n_cols;
+
+		if (col_string && (n_cols = atoi(col_string)) > 0)
+			return (term_columns_cache = n_cols);
+	}
 
 #ifdef TIOCGWINSZ
 	{
 		struct winsize ws;
 		if (!ioctl(1, TIOCGWINSZ, &ws)) {
 			if (ws.ws_col)
-				return ws.ws_col;
+				return (term_columns_cache = ws.ws_col);
 		}
 	}
 #endif
 
-	return 80;
+	return (term_columns_cache = 80);
 }
 
 void add_cmdname(struct cmdnames *cmds, const char *name, int len)
diff --git a/help.h b/help.h
index b6b12d5..880a4b4 100644
--- a/help.h
+++ b/help.h
@@ -29,4 +29,6 @@ extern void list_commands(const char *title,
 			  struct cmdnames *main_cmds,
 			  struct cmdnames *other_cmds);
 
+extern int term_columns(void);
+
 #endif /* HELP_H */
diff --git a/pager.c b/pager.c
index 975955b..e7032de 100644
--- a/pager.c
+++ b/pager.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "run-command.h"
 #include "sigchain.h"
+#include "help.h"
 
 #ifndef DEFAULT_PAGER
 #define DEFAULT_PAGER "less"
@@ -76,6 +77,10 @@ void setup_pager(void)
 	if (!pager)
 		return;
 
+	/* prime the term_columns() cache before it is too
+	 * late and stdout is replaced */
+	(void) term_columns();
+
 	setenv("GIT_PAGER_IN_USE", "true", 1);
 
 	/* spawn the pager */
-- 
1.7.9.rc2.127.gcb239

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 3/4] diff --stat: use the real terminal width
  2012-02-09 23:58 (unknown), Zbigniew Jędrzejewski-Szmek
  2012-02-09 23:58 ` [PATCH 1/4] Move git_version_string to help.c in preparation for diff changes Zbigniew Jędrzejewski-Szmek
  2012-02-09 23:58 ` [PATCH 2/4] help.c: make term_columns() cached and export it Zbigniew Jędrzejewski-Szmek
@ 2012-02-09 23:58 ` Zbigniew Jędrzejewski-Szmek
  2012-02-10  0:54   ` Junio C Hamano
  2012-02-10  6:15   ` Nguyen Thai Ngoc Duy
  2012-02-09 23:58 ` [PATCH 4/4] diff --stat: use most of the space for file names Zbigniew Jędrzejewski-Szmek
  3 siblings, 2 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-09 23:58 UTC (permalink / raw)
  To: git; +Cc: gitster, Michael J Gruber, Zbigniew Jędrzejewski-Szmek

Some projects (especially in Java), have long filename paths, with
nested directories or long individual filenames. When files are
renamed, the stat output can be almost useless. If the middle part
between { and } is long (because the file was moved to a completely
different directory), then most of the path would be truncated.

It makes sense to use the full terminal width.

The output is still not optimal, because too many columns are devoted
to +- output, and not enough to filenames, but this is a policy
question, changed in next commit.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 diff.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/diff.c b/diff.c
index 7e15426..8406a0d 100644
--- a/diff.c
+++ b/diff.c
@@ -7,6 +7,7 @@
 #include "diffcore.h"
 #include "delta.h"
 #include "xdiff-interface.h"
+#include "help.h"
 #include "color.h"
 #include "attr.h"
 #include "run-command.h"
@@ -1341,7 +1342,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		line_prefix = msg->buf;
 	}
 
-	width = options->stat_width ? options->stat_width : 80;
+	width = options->stat_width ? options->stat_width : term_columns();
 	name_width = options->stat_name_width ? options->stat_name_width : 50;
 	count = options->stat_count ? options->stat_count : data->nr;
 
-- 
1.7.9.rc2.127.gcb239

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 4/4] diff --stat: use most of the space for file names
  2012-02-09 23:58 (unknown), Zbigniew Jędrzejewski-Szmek
                   ` (2 preceding siblings ...)
  2012-02-09 23:58 ` [PATCH 3/4] diff --stat: use the real terminal width Zbigniew Jędrzejewski-Szmek
@ 2012-02-09 23:58 ` Zbigniew Jędrzejewski-Szmek
  2012-02-10  0:55   ` Junio C Hamano
  3 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-09 23:58 UTC (permalink / raw)
  To: git; +Cc: gitster, Michael J Gruber, Zbigniew Jędrzejewski-Szmek

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 diff.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/diff.c b/diff.c
index 8406a0d..6220190 100644
--- a/diff.c
+++ b/diff.c
@@ -1343,7 +1343,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	}
 
 	width = options->stat_width ? options->stat_width : term_columns();
-	name_width = options->stat_name_width ? options->stat_name_width : 50;
+	name_width = options->stat_name_width ? options->stat_name_width
+		: term_columns() - 20; /* the graph defaults to 20 columns */
 	count = options->stat_count ? options->stat_count : data->nr;
 
 	/* Sanity: give at least 5 columns to the graph,
-- 
1.7.9.rc2.127.gcb239

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/4] Move git_version_string to help.c in preparation for diff changes
  2012-02-09 23:58 ` [PATCH 1/4] Move git_version_string to help.c in preparation for diff changes Zbigniew Jędrzejewski-Szmek
@ 2012-02-10  0:46   ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-10  0:46 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> git_version_string is declared in builtins.h, but lived in git.c.
>
> When diff.c starts to use functions from help.c, linking against
> libgit.a will fail,  unless git.o containing git_version_string is
> linked too.

Sorry, it is unclear what you mean by the above, nor why you need this
change in the first place. The resulting diff.o will certainly linked to
git.o as it does not have its own "main()" at all.  And builtins.h is a
perfect place to declare things that are for the use of built-in commands
like implementations of diff family of commands, as they all are linked
into git.o (namely the commands[] array in handle_internal_command()) to
be usable.

What am I missing from between the lines of your log message?

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 2/4] help.c: make term_columns() cached and export it
  2012-02-09 23:58 ` [PATCH 2/4] help.c: make term_columns() cached and export it Zbigniew Jędrzejewski-Szmek
@ 2012-02-10  0:50   ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-10  0:50 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> diff --git a/help.c b/help.c
> index bc15066..75b8d4b 100644
> --- a/help.c
> +++ b/help.c
> @@ -5,26 +5,41 @@
>  #include "help.h"
>  #include "common-cmds.h"
>  
> -/* most GUI terminals set COLUMNS (although some don't export it) */
> -static int term_columns(void)
> +/* cache for term_columns() value. Set on first use or when
> + * installing a pager and replacing stdout.
> + */

Just a style.

	/*
         * We format multi-line
         * comment block like
         * this.
         */

> +static int term_columns_cache;
> +
> +/* Return cached value (iff set) or $COLUMNS (iff set and positive) or
> + * ioctl(1, TIOCGWINSZ).ws_col (if positive) or 80.
> + *
> + * $COLUMNS even if set, is usually not exported, so
> + * the variable can be used to override autodection.
> + */
> +int term_columns(void)
>  {
> -	char *col_string = getenv("COLUMNS");
> -	int n_cols;
> +	if (term_columns_cache)
> +		return term_columns_cache;
>  
> -	if (col_string && (n_cols = atoi(col_string)) > 0)
> -		return n_cols;
> +	{
> +		char *col_string = getenv("COLUMNS");
> +		int n_cols;
> +
> +		if (col_string && (n_cols = atoi(col_string)) > 0)
> +			return (term_columns_cache = n_cols);
> +	}

I can see the justification for the existing one inside the #ifdef below,
but why do you need the extra scope above?

We tend to avoid assignment as a part of another expression.  The old code
already violates that convention, but please do not make it worse by
introducing three new ones.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 3/4] diff --stat: use the real terminal width
  2012-02-09 23:58 ` [PATCH 3/4] diff --stat: use the real terminal width Zbigniew Jędrzejewski-Szmek
@ 2012-02-10  0:54   ` Junio C Hamano
  2012-02-10  6:15   ` Nguyen Thai Ngoc Duy
  1 sibling, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-10  0:54 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> Some projects (especially in Java), have long filename paths, with
> nested directories or long individual filenames. When files are
> renamed, the stat output can be almost useless. If the middle part
> between { and } is long (because the file was moved to a completely
> different directory), then most of the path would be truncated.
>
> It makes sense to use the full terminal width.
>
> The output is still not optimal, because too many columns are devoted
> to +- output, and not enough to filenames, but this is a policy
> question, changed in next commit.
>
> Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
> ---
>  diff.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/diff.c b/diff.c
> index 7e15426..8406a0d 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -7,6 +7,7 @@
>  #include "diffcore.h"
>  #include "delta.h"
>  #include "xdiff-interface.h"
> +#include "help.h"
>  #include "color.h"
>  #include "attr.h"
>  #include "run-command.h"
> @@ -1341,7 +1342,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>  		line_prefix = msg->buf;
>  	}
>  
> -	width = options->stat_width ? options->stat_width : 80;
> +	width = options->stat_width ? options->stat_width : term_columns();

The output from "git format-patch" shouldn't be affected at all by the
width of the terminal the patch sender happened to have used when the
command was run when the user did not explicitly ask a custom width by
giving a --stat-width command line option.

How do you prevent regression to the command in this series?

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 4/4] diff --stat: use most of the space for file names
  2012-02-09 23:58 ` [PATCH 4/4] diff --stat: use most of the space for file names Zbigniew Jędrzejewski-Szmek
@ 2012-02-10  0:55   ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-10  0:55 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
> ---
>  diff.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/diff.c b/diff.c
> index 8406a0d..6220190 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -1343,7 +1343,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>  	}
>  
>  	width = options->stat_width ? options->stat_width : term_columns();
> -	name_width = options->stat_name_width ? options->stat_name_width : 50;
> +	name_width = options->stat_name_width ? options->stat_name_width
> +		: term_columns() - 20; /* the graph defaults to 20 columns */

Why?  Isn't 80-50 = 30?

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 3/4] diff --stat: use the real terminal width
  2012-02-09 23:58 ` [PATCH 3/4] diff --stat: use the real terminal width Zbigniew Jędrzejewski-Szmek
  2012-02-10  0:54   ` Junio C Hamano
@ 2012-02-10  6:15   ` Nguyen Thai Ngoc Duy
  2012-02-10 11:25     ` Zbigniew Jędrzejewski-Szmek
  1 sibling, 1 reply; 46+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2012-02-10  6:15 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber

2012/2/10 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>:
> @@ -1341,7 +1342,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>                line_prefix = msg->buf;
>        }
>
> -       width = options->stat_width ? options->stat_width : 80;
> +       width = options->stat_width ? options->stat_width : term_columns();
>        name_width = options->stat_name_width ? options->stat_name_width : 50;
>        count = options->stat_count ? options->stat_count : data->nr;

I tried this in the past and "git log -p" looked ugly on git.git
mainly because commit messages are still ~70 char long lines on my 279
char wide terminal. If this is project dependent, perhaps a config
key? Also the "50" below the changed line, maybe you want to change it
to 0.6 * width.
-- 
Duy

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 3/4] diff --stat: use the real terminal width
  2012-02-10  6:15   ` Nguyen Thai Ngoc Duy
@ 2012-02-10 11:25     ` Zbigniew Jędrzejewski-Szmek
  2012-02-10 13:00       ` Nguyen Thai Ngoc Duy
  2012-02-10 16:39       ` [PATCH 0/3 v2] " Zbigniew Jędrzejewski-Szmek
  0 siblings, 2 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-10 11:25 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy, git, gitster; +Cc: Michael J Gruber

On 02/10/2012 07:15 AM, Nguyen Thai Ngoc Duy wrote:
> 2012/2/10 Zbigniew Jędrzejewski-Szmek<zbyszek@in.waw.pl>:
>> @@ -1341,7 +1342,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>>                 line_prefix = msg->buf;
>>         }
>>
>> -       width = options->stat_width ? options->stat_width : 80;
>> +       width = options->stat_width ? options->stat_width : term_columns();
>>         name_width = options->stat_name_width ? options->stat_name_width : 50;
>>         count = options->stat_count ? options->stat_count : data->nr;
>
> I tried this in the past and "git log -p" looked ugly on git.git
> mainly because commit messages are still ~70 char long lines on my 279
> char wide terminal. If this is project dependent, perhaps a config
> key? Also the "50" below the changed line, maybe you want to change it
> to 0.6 * width.

Thanks for all the comments. I'll post a newer version, but I have two 
questions:

I agree that making the output very wide with lots of +- is not very 
elegant. (E.g. 8f24a6323ece9be1bf1a04b4b5856112438337f2 has
    builtin/grep.c |  142 +++--------------------------------....--
which doesn't look right.). So I think it would make sense to limit
the graph part to something like 50 columns, even if there's more space.
I believe that git.git would look fine with this change. There are some 
fairly long lines 
(t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master 
is 86 chars) but with 50 columns of graph the output would take 140 
columns -- with the graph part slightly sticking out from the 80 column 
descriptions, but still not too ugly.

Should I add a new option --stat-graph-width in analogy to 
--stat-name-width, or should this be hard-coded?

JC:
 > The output from "git format-patch" shouldn't be affected at all by the
 > width of the terminal the patch sender happened to have used when the
 > command was run when the user did not explicitly ask a custom width by
 > giving a --stat-width command line option.
 >
 > How do you prevent regression to the command in this series?
git format-patch is not affected by default. But with --stdout
the width is changed, iff stdout is a tty. When --stdout output
is connected to a pipe, the width is not changed. I think that
this behaviour is OK.

Should a test be added to check that 'git format-patch --stat' output 
doesn't change? Should I test for something else?

--
Zbyszek

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 3/4] diff --stat: use the real terminal width
  2012-02-10 11:25     ` Zbigniew Jędrzejewski-Szmek
@ 2012-02-10 13:00       ` Nguyen Thai Ngoc Duy
  2012-02-10 16:39       ` [PATCH 0/3 v2] " Zbigniew Jędrzejewski-Szmek
  1 sibling, 0 replies; 46+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2012-02-10 13:00 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber

2012/2/10 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>:
>> I tried this in the past and "git log -p" looked ugly on git.git
>> mainly because commit messages are still ~70 char long lines on my 279
>> char wide terminal. If this is project dependent, perhaps a config
>> key? Also the "50" below the changed line, maybe you want to change it
>> to 0.6 * width.
>
>
> Thanks for all the comments. I'll post a newer version, but I have two
> questions:
>
> I agree that making the output very wide with lots of +- is not very
> elegant. (E.g. 8f24a6323ece9be1bf1a04b4b5856112438337f2 has
>   builtin/grep.c |  142 +++--------------------------------....--
> which doesn't look right.). So I think it would make sense to limit
> the graph part to something like 50 columns, even if there's more space.
> I believe that git.git would look fine with this change. There are some
> fairly long lines
> (t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
> is 86 chars) but with 50 columns of graph the output would take 140 columns
> -- with the graph part slightly sticking out from the 80 column
> descriptions, but still not too ugly.

You also need to pay attention, not to exceed term_columns() because
of this dynamic name part. But the idea sounds good to me.

It would be even better if we had some heuristics to shorten
exceptionally long names with ellipsis, to keep the name part from
being overly stretched.

> Should I add a new option --stat-graph-width in analogy to
> --stat-name-width, or should this be hard-coded?

I don't know about other people, but I have no urge to change graph width.
-- 
Duy

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 0/3 v2] diff --stat: use the real terminal width
  2012-02-10 11:25     ` Zbigniew Jędrzejewski-Szmek
  2012-02-10 13:00       ` Nguyen Thai Ngoc Duy
@ 2012-02-10 16:39       ` Zbigniew Jędrzejewski-Szmek
  2012-02-10 16:39         ` [PATCH 1/3] Move git_version_string to help.c before diff changes Zbigniew Jędrzejewski-Szmek
                           ` (3 more replies)
  1 sibling, 4 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-10 16:39 UTC (permalink / raw)
  To: git, gitster, pclouds; +Cc: Michael J Gruber

Hi,
this is version 2.
Changes:

- style fixes
- some tests for git-format-patch added
- patches 3 and 4 squashed together, since they touch the same lines
- graph width is limited to 40 columns, even if there's more space
- patch descriptions extended and cleared up

Description (modified):

this is a patch series to make 'git diff --stat' use full terminal
width instead of hard-coded 80 columns.

This is quite useful when working on projects with nested directory
structure, e.g. Java:
 .../{ => workspace/tasks}/GetTaskResultAction.java |   10 +-
 .../tasks}/RemoveAllAbortedTasksAction.java        |    7 +-
 .../tasks}/RemoveAllFailedTasksAction.java         |    7 +-
is changed to display full paths if the terminal window is wide
enough.

Git usually uses the full terminal width automatically, so it should
do so with --stat too.

The "big" functional change in the patch series is
s/80/term_columns()/ in show_stats(). The partitioning of available
columns is changed to dedicate more space to file names and the number
of columns used for +- graph is limited.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 1/3] Move git_version_string to help.c before diff changes
  2012-02-10 16:39       ` [PATCH 0/3 v2] " Zbigniew Jędrzejewski-Szmek
@ 2012-02-10 16:39         ` Zbigniew Jędrzejewski-Szmek
  2012-02-10 17:58           ` Junio C Hamano
  2012-02-10 16:39         ` [PATCH 2/3] help.c: make term_columns() cached and export it Zbigniew Jędrzejewski-Szmek
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-10 16:39 UTC (permalink / raw)
  To: git, gitster, pclouds; +Cc: Michael J Gruber, Zbigniew Jędrzejewski-Szmek

git_version_string lives in git.c. When diff.c starts to use functions
from help.c, which in turn use git_version_string, linking against
libgit.a will fail. This is because git_version_string is physically
located in git.o, and this object file is not part of libgit.a. One
option would be to add git.o to libgit.a, but git.o is biggish. The
second, better option is to move git_version_string to somewhere where
it'll become part of libgit.a. This variable is only used in a couple
of places, help.c being one of them, so it let's move
git_version_string from git.c to help.c. The git binary is linked with
help.o, so it is not affected by this move.

Without this change the next commit would fail with:
$ gcc  -g -O0 -I. -DUSE_LIBPCRE  -DHAVE_PATHS_H -DHAVE_DEV_TTY -DSHA1_HEADER='<openssl/sha.h>'  -DNO_STRLCPY -DNO_MKSTEMPS -o git-daemon   daemon.o libgit.a xdiff/lib.a  -lpcre -lz  -lcrypto -lpthread
libgit.a(help.o): In function `cmd_version':
/home/zbyszek/git/git/help.c:435: undefined reference to `git_version_string'

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 Makefile |    5 +++--
 git.c    |    2 --
 help.c   |    2 ++
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index 4817157..ccafb95 100644
--- a/Makefile
+++ b/Makefile
@@ -1890,7 +1890,7 @@ strip: $(PROGRAMS) git$X
 	$(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X
 
 git.o: common-cmds.h
-git.sp git.s git.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"' \
+git.sp git.s git.o: EXTRA_CPPFLAGS = \
 	'-DGIT_HTML_PATH="$(htmldir_SQ)"' \
 	'-DGIT_MAN_PATH="$(mandir_SQ)"' \
 	'-DGIT_INFO_PATH="$(infodir_SQ)"'
@@ -1899,7 +1899,8 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
 	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
 		$(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
 
-help.sp help.o: common-cmds.h
+help.o: common-cmds.h
+help.sp help.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"'
 
 builtin/help.sp builtin/help.o: common-cmds.h
 builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
diff --git a/git.c b/git.c
index 3805616..a24a0fd 100644
--- a/git.c
+++ b/git.c
@@ -256,8 +256,6 @@ static int handle_alias(int *argcp, const char ***argv)
 	return ret;
 }
 
-const char git_version_string[] = GIT_VERSION;
-
 #define RUN_SETUP		(1<<0)
 #define RUN_SETUP_GENTLY	(1<<1)
 #define USE_PAGER		(1<<2)
diff --git a/help.c b/help.c
index cbbe966..bc15066 100644
--- a/help.c
+++ b/help.c
@@ -409,6 +409,8 @@ const char *help_unknown_cmd(const char *cmd)
 	exit(1);
 }
 
+const char git_version_string[] = GIT_VERSION;
+
 int cmd_version(int argc, const char **argv, const char *prefix)
 {
 	printf("git version %s\n", git_version_string);
-- 
1.7.9.263.g4be11.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 2/3] help.c: make term_columns() cached and export it
  2012-02-10 16:39       ` [PATCH 0/3 v2] " Zbigniew Jędrzejewski-Szmek
  2012-02-10 16:39         ` [PATCH 1/3] Move git_version_string to help.c before diff changes Zbigniew Jędrzejewski-Szmek
@ 2012-02-10 16:39         ` Zbigniew Jędrzejewski-Szmek
  2012-02-11  4:36           ` Nguyen Thai Ngoc Duy
  2012-02-10 16:39         ` [PATCH 3/3] diff --stat: use the real terminal width Zbigniew Jędrzejewski-Szmek
  2012-02-10 18:24         ` [PATCH 0/3 v2] " Junio C Hamano
  3 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-10 16:39 UTC (permalink / raw)
  To: git, gitster, pclouds; +Cc: Michael J Gruber, Zbigniew Jędrzejewski-Szmek

Since term_columns() will usually fail, when a pager is installed,
the cache is primed before the pager is installed. If a pager is not
installed, then the cache will be set on first use.

Conforms to The Single UNIX Specification, Version 2
(http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003).

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 help.c  |   37 +++++++++++++++++++++++++++++--------
 help.h  |    2 ++
 pager.c |    5 +++++
 3 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/help.c b/help.c
index bc15066..5d1cb1d 100644
--- a/help.c
+++ b/help.c
@@ -5,26 +5,47 @@
 #include "help.h"
 #include "common-cmds.h"
 
-/* most GUI terminals set COLUMNS (although some don't export it) */
-static int term_columns(void)
+/* 
+ * Cache for term_columns() value. Set on first use or when
+ * installing a pager and replacing stdout.
+ */
+static int term_columns_cache;
+
+/* 
+ * Return cached value (if set) or $COLUMNS (if set and positive) or
+ * ioctl(1, TIOCGWINSZ).ws_col (if positive) or 80.
+ *
+ * $COLUMNS even if set, is usually not exported, so
+ * the variable can be used to override autodection.
+ */
+int term_columns(void)
 {
-	char *col_string = getenv("COLUMNS");
+	char *col_string;
 	int n_cols;
 
-	if (col_string && (n_cols = atoi(col_string)) > 0)
-		return n_cols;
+	if (term_columns_cache)
+		return term_columns_cache;
+
+	col_string = getenv("COLUMNS");
+	if (col_string && (n_cols = atoi(col_string)) > 0) {
+		term_columns_cache = n_cols;
+		return term_columns_cache;
+	}
 
 #ifdef TIOCGWINSZ
 	{
 		struct winsize ws;
 		if (!ioctl(1, TIOCGWINSZ, &ws)) {
-			if (ws.ws_col)
-				return ws.ws_col;
+			if (ws.ws_col) {
+				term_columns_cache = ws.ws_col;
+				return term_columns_cache;
+			}
 		}
 	}
 #endif
 
-	return 80;
+	term_columns_cache = 80;
+	return term_columns_cache;
 }
 
 void add_cmdname(struct cmdnames *cmds, const char *name, int len)
diff --git a/help.h b/help.h
index b6b12d5..880a4b4 100644
--- a/help.h
+++ b/help.h
@@ -29,4 +29,6 @@ extern void list_commands(const char *title,
 			  struct cmdnames *main_cmds,
 			  struct cmdnames *other_cmds);
 
+extern int term_columns(void);
+
 #endif /* HELP_H */
diff --git a/pager.c b/pager.c
index 975955b..e7032de 100644
--- a/pager.c
+++ b/pager.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "run-command.h"
 #include "sigchain.h"
+#include "help.h"
 
 #ifndef DEFAULT_PAGER
 #define DEFAULT_PAGER "less"
@@ -76,6 +77,10 @@ void setup_pager(void)
 	if (!pager)
 		return;
 
+	/* prime the term_columns() cache before it is too
+	 * late and stdout is replaced */
+	(void) term_columns();
+
 	setenv("GIT_PAGER_IN_USE", "true", 1);
 
 	/* spawn the pager */
-- 
1.7.9.263.g4be11.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 3/3] diff --stat: use the real terminal width
  2012-02-10 16:39       ` [PATCH 0/3 v2] " Zbigniew Jędrzejewski-Szmek
  2012-02-10 16:39         ` [PATCH 1/3] Move git_version_string to help.c before diff changes Zbigniew Jędrzejewski-Szmek
  2012-02-10 16:39         ` [PATCH 2/3] help.c: make term_columns() cached and export it Zbigniew Jędrzejewski-Szmek
@ 2012-02-10 16:39         ` Zbigniew Jędrzejewski-Szmek
  2012-02-10 18:24         ` [PATCH 0/3 v2] " Junio C Hamano
  3 siblings, 0 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-10 16:39 UTC (permalink / raw)
  To: git, gitster, pclouds; +Cc: Michael J Gruber, Zbigniew Jędrzejewski-Szmek

Some projects (especially in Java), have long filename paths, with
nested directories or long individual filenames. When files are
renamed, the stat output can be almost useless. If the middle part
between { and } is long (because the file was moved to a completely
different directory), then most of the path would be truncated.

It makes sense to use the full terminal width.

If commits changing a lot of lines are displayed in a wide terminal
window (200 or more columns), and the +- graph uses the full width,
the output looks bad. Messages wrapped to about 80 columns are
interspersed with very long +- lines. It makes sense to limit the
width of the graph to a fixed value, even if more columns are
available. This fixed value is subjectively hard-coded to be 40
columns, but seems to work well for git.git and linux-2.6.git and
other repositories.

Three tests are added: the first one check that --stat output for a
long file name is the same as previously (the test should pass
independently of this patch). The last two check that --stat output
with a massive change uses only 40 columns for +- in graph output.
Those two tests are dependent on this patch.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 diff.c                  |   26 ++++++++++++++------------
 t/t4014-format-patch.sh |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/diff.c b/diff.c
index 84780fd..8176d74 100644
--- a/diff.c
+++ b/diff.c
@@ -7,6 +7,7 @@
 #include "diffcore.h"
 #include "delta.h"
 #include "xdiff-interface.h"
+#include "help.h"
 #include "color.h"
 #include "attr.h"
 #include "run-command.h"
@@ -1376,7 +1377,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	int i, len, add, del, adds = 0, dels = 0;
 	uintmax_t max_change = 0, max_len = 0;
 	int total_files = data->nr;
-	int width, name_width, count;
+	int width, name_width, graph_width, count;
 	const char *reset, *add_c, *del_c;
 	const char *line_prefix = "";
 	int extra_shown = 0;
@@ -1390,8 +1391,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		line_prefix = msg->buf;
 	}
 
-	width = options->stat_width ? options->stat_width : 80;
-	name_width = options->stat_name_width ? options->stat_name_width : 50;
+	width = options->stat_width ? options->stat_width : term_columns();
+	name_width = options->stat_name_width ? options->stat_name_width
+		: width * 5/8; /* this gives 50 if not on tty */
 	count = options->stat_count ? options->stat_count : data->nr;
 
 	/* Sanity: give at least 5 columns to the graph,
@@ -1433,14 +1435,14 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	 * 10 is for one blank at the beginning of the line plus
 	 * " | count " between the name and the graph.
 	 *
-	 * From here on, name_width is the width of the name area,
-	 * and width is the width of the graph area.
+	 * From here name_width is the width of the name area,
+	 * and graph_width is the width of the graph area.
+	 * max_change is used to scale graph properly.
 	 */
 	name_width = (name_width < max_len) ? name_width : max_len;
-	if (width < (name_width + 10) + max_change)
-		width = width - (name_width + 10);
-	else
-		width = max_change;
+	graph_width = max_change < 40 ? max_change : 40;
+	if (width < (name_width + 10) + graph_width)
+		graph_width = width - (name_width + 10);
 
 	for (i = 0; i < count; i++) {
 		const char *prefix = "";
@@ -1497,9 +1499,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		adds += add;
 		dels += del;
 
-		if (width <= max_change) {
-			add = scale_linear(add, width, max_change);
-			del = scale_linear(del, width, max_change);
+		if (graph_width <= max_change) {
+			add = scale_linear(add, graph_width, max_change);
+			del = scale_linear(del, graph_width, max_change);
 		}
 		fprintf(options->file, "%s", line_prefix);
 		show_name(options->file, prefix, name, len);
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 7dfe716..bd3002b 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -894,4 +894,44 @@ test_expect_success 'format patch ignores color.ui' '
 	test_cmp expect actual
 '
 
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |	 1 +
+EOF
+name=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+test_expect_success 'format patch filename width is limited' "
+	> ${name} &&
+	git add ${name} &&
+	git commit -m message &&
+	echo a > ${name} &&
+	git commit -m message ${name} &&
+	git format-patch --stat --stdout -1 |
+		grep -m 1 aaaaa > actual &&
+	test_cmp expect actual
+"
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++
+EOF
+test_expect_success 'format patch graph width is 40 columns' '
+	> abcd &&
+	git add abcd &&
+	git commit -m message &&
+	seq 1000 > abcd &&
+	git commit -m message abcd &&
+	git format-patch --stat --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch ignores COLUMNS' '
+	> abcd &&
+	git add abcd &&
+	git commit -m message &&
+	seq 1000 > abcd &&
+	git commit -m message abcd &&
+	COLUMNS=200 git format-patch --stat --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.7.9.263.g4be11.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/3] Move git_version_string to help.c before diff changes
  2012-02-10 16:39         ` [PATCH 1/3] Move git_version_string to help.c before diff changes Zbigniew Jędrzejewski-Szmek
@ 2012-02-10 17:58           ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-10 17:58 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, pclouds, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> git_version_string lives in git.c. When diff.c starts to use functions
> from help.c, which in turn use git_version_string, linking against
> libgit.a will fail. This is because git_version_string is physically
> located in git.o, and this object file is not part of libgit.a.

But what is wrong about that?

If you are making the termio related code reusable and sharable by turning
the static "term_columns()" in help.o into an external symbol, there is no
reason that termio related function, which is now useful outside the
context of giving help, must stay in help.c where its life happened to
have started.  In fact, "tell me how wide the terminal is" does not belong
to something called "help subsystem", no?

Wouldn't a new file, term.c or something, be a lot more suitable home for
the function you will be reusing from diff and other parts of the system?

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 0/3 v2] diff --stat: use the real terminal width
  2012-02-10 16:39       ` [PATCH 0/3 v2] " Zbigniew Jędrzejewski-Szmek
                           ` (2 preceding siblings ...)
  2012-02-10 16:39         ` [PATCH 3/3] diff --stat: use the real terminal width Zbigniew Jędrzejewski-Szmek
@ 2012-02-10 18:24         ` Junio C Hamano
  2012-02-12 14:30           ` [PATCH v3] diff --stat: use the full " Zbigniew Jędrzejewski-Szmek
  3 siblings, 1 reply; 46+ messages in thread
From: Junio C Hamano @ 2012-02-10 18:24 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, pclouds, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> - style fixes

I think I still saw at least one malformatted multi-line comments in this
round, though (I stopped looking after I saw one, so there may be others).

> - some tests for git-format-patch added
> - patches 3 and 4 squashed together, since they touch the same lines
> - graph width is limited to 40 columns, even if there's more space

Hmm.

This is what we have in the documentation.

        --stat[=<width>[,<name-width>[,<count>]]]::
                Generate a diffstat.  You can override the default
                output width for 80-column terminal by `--stat=<width>`.
                The width of the filename part can be controlled by
                giving another width to it separated by a comma.

Naïvely, one would expect that a "use the real terminal width" series
would be only to learn the width of the terminal and tweak its hardcoded
default "80" to that width, and change nothing else, leaving the default
for name-width to "50", which still can be overridable if needed.

But the reason somebody wants to have a wider width is more often not
because they want to see longer bars, but because they want to see long
names without truncation, so in retrospect, the order the "--stat=" option
takes its values is inconvenient.  Users would more often want to tinker
with name-width than width because the latter can be auto-detected.

Which is a bit unfortunate.

In any case, the above needs to be updated to describe what the updated
logic does.  Do you have documentation updates in the series?

Judging from what you wrote in the above, the updated logic is, instead of
the "naïve" version:

 - auto-detect, if possible, to set the default "width" to COLUMNS instead
   of hardcoded 80; and

 - instead of using hardcoded 50, use width-40 as the default as the
   default "name-width".

But if that is what is going on, shouldn't your "40" be "30" to retain
backward compatibility for people who work on 80-column terminals?

Or is there something more complex going on that you are not describing
here?

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 2/3] help.c: make term_columns() cached and export it
  2012-02-10 16:39         ` [PATCH 2/3] help.c: make term_columns() cached and export it Zbigniew Jędrzejewski-Szmek
@ 2012-02-11  4:36           ` Nguyen Thai Ngoc Duy
  2012-02-11 10:49             ` Zbigniew Jędrzejewski-Szmek
  0 siblings, 1 reply; 46+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2012-02-11  4:36 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber

2012/2/10 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>:
> Since term_columns() will usually fail, when a pager is installed,
> the cache is primed before the pager is installed. If a pager is not
> installed, then the cache will be set on first use.

Conflict alert. term_columns() is also moved out of help.c in
nd/columns series on pu, commit cb0850f (Save terminal width before
setting up pager - 2012-02-04)

>
> Conforms to The Single UNIX Specification, Version 2
> (http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003).
>
> Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
> ---
>  help.c  |   37 +++++++++++++++++++++++++++++--------
>  help.h  |    2 ++
>  pager.c |    5 +++++
>  3 files changed, 36 insertions(+), 8 deletions(-)
>
> diff --git a/help.c b/help.c
> index bc15066..5d1cb1d 100644
> --- a/help.c
> +++ b/help.c
> @@ -5,26 +5,47 @@
>  #include "help.h"
>  #include "common-cmds.h"
>
> -/* most GUI terminals set COLUMNS (although some don't export it) */
> -static int term_columns(void)
> +/*
> + * Cache for term_columns() value. Set on first use or when
> + * installing a pager and replacing stdout.
> + */
> +static int term_columns_cache;
> +
> +/*
> + * Return cached value (if set) or $COLUMNS (if set and positive) or
> + * ioctl(1, TIOCGWINSZ).ws_col (if positive) or 80.
> + *
> + * $COLUMNS even if set, is usually not exported, so
> + * the variable can be used to override autodection.
> + */
> +int term_columns(void)
>  {
> -       char *col_string = getenv("COLUMNS");
> +       char *col_string;
>        int n_cols;
>
> -       if (col_string && (n_cols = atoi(col_string)) > 0)
> -               return n_cols;
> +       if (term_columns_cache)
> +               return term_columns_cache;
> +
> +       col_string = getenv("COLUMNS");
> +       if (col_string && (n_cols = atoi(col_string)) > 0) {
> +               term_columns_cache = n_cols;
> +               return term_columns_cache;
> +       }
>
>  #ifdef TIOCGWINSZ
>        {
>                struct winsize ws;
>                if (!ioctl(1, TIOCGWINSZ, &ws)) {
> -                       if (ws.ws_col)
> -                               return ws.ws_col;
> +                       if (ws.ws_col) {
> +                               term_columns_cache = ws.ws_col;
> +                               return term_columns_cache;
> +                       }
>                }
>        }
>  #endif
>
> -       return 80;
> +       term_columns_cache = 80;
> +       return term_columns_cache;
>  }
>
>  void add_cmdname(struct cmdnames *cmds, const char *name, int len)
> diff --git a/help.h b/help.h
> index b6b12d5..880a4b4 100644
> --- a/help.h
> +++ b/help.h
> @@ -29,4 +29,6 @@ extern void list_commands(const char *title,
>                          struct cmdnames *main_cmds,
>                          struct cmdnames *other_cmds);
>
> +extern int term_columns(void);
> +
>  #endif /* HELP_H */
> diff --git a/pager.c b/pager.c
> index 975955b..e7032de 100644
> --- a/pager.c
> +++ b/pager.c
> @@ -1,6 +1,7 @@
>  #include "cache.h"
>  #include "run-command.h"
>  #include "sigchain.h"
> +#include "help.h"
>
>  #ifndef DEFAULT_PAGER
>  #define DEFAULT_PAGER "less"
> @@ -76,6 +77,10 @@ void setup_pager(void)
>        if (!pager)
>                return;
>
> +       /* prime the term_columns() cache before it is too
> +        * late and stdout is replaced */
> +       (void) term_columns();
> +
>        setenv("GIT_PAGER_IN_USE", "true", 1);
>
>        /* spawn the pager */
> --
> 1.7.9.263.g4be11.dirty
>



-- 
Duy

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 2/3] help.c: make term_columns() cached and export it
  2012-02-11  4:36           ` Nguyen Thai Ngoc Duy
@ 2012-02-11 10:49             ` Zbigniew Jędrzejewski-Szmek
  2012-02-12  9:40               ` Junio C Hamano
  0 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-11 10:49 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy; +Cc: git, gitster, Michael J Gruber, Ramsay Jones

On 02/11/2012 05:36 AM, Nguyen Thai Ngoc Duy wrote:
> 2012/2/10 Zbigniew Jędrzejewski-Szmek<zbyszek@in.waw.pl>:
>> Since term_columns() will usually fail, when a pager is installed,
>> the cache is primed before the pager is installed. If a pager is not
>> installed, then the cache will be set on first use.
>
> Conflict alert. term_columns() is also moved out of help.c in
> nd/columns series on pu, commit cb0850f (Save terminal width before
> setting up pager - 2012-02-04)

Thanks for the heads-up. I think that the two patches should be
merged, especially because there's an error in cb0850f (a variable is
read-only, never written).

Tweaks to cb0850f (Save terminal width before setting up pager - 
2012-02-04):

[This actually was done on top of today's pu, so it will not apply
  cleanly to cb0850f].

- term_columns() lives in pager.c so it should be declared in
   cache.h like other public functions in pager.c. It has nothing to do
   with columns.h.
- simplify logic to use a static variable instead of two global
   variables (cb0850f actually doesn't work at all because
   spawned_pager wasn't ever set).
- check the cache first, then do getenv(COLUMNS) + atoi, then do
   ioctl(). The behaviour is equivalent to checking COLUMNS first, but
   is slightly more efficient.
- document the function
- remove #include "column.h" added in 88c9754c4097 column: Fix some
   compiler and sparse warnings (Wed Feb 8 2012).

Junio suggested that "a new file, term.c or something, be a lot more
suitable home for the function you will be reusing from diff and other
parts of the system". Nevertheless, I think that adding two files (.c
and .h) to hold one function isn't worth it. It can live in pager.c.
Terminal size is logically connected to paging after all.
---
  cache.h  |    1 +
  column.h |    1 -
  pager.c  |   64 +++++++++++++++++++++++-----------------
  3 files changed, 38 insertions(+), 28 deletions(-)

diff --git a/cache.h b/cache.h
index 6c70dbc..b4422d4 100644
--- a/cache.h
+++ b/cache.h
@@ -1196,6 +1196,7 @@ extern void setup_pager(void);
  extern const char *pager_program;
  extern int pager_in_use(void);
  extern int pager_use_color;
+extern int term_columns(void);

  extern const char *editor_program;
  extern const char *askpass_program;
diff --git a/column.h b/column.h
index b9dec64..142299e 100644
--- a/column.h
+++ b/column.h
@@ -17,7 +17,6 @@ struct column_options {
  	const char *nl;
  };

-extern int term_columns(void);
  extern void print_columns(const struct string_list *list,
  			  unsigned int mode,
  			  struct column_options *opts);
diff --git a/pager.c b/pager.c
index fe203a7..d105761 100644
--- a/pager.c
+++ b/pager.c
@@ -7,21 +7,6 @@
  #define DEFAULT_PAGER "less"
  #endif

-static int spawned_pager;
-static int max_columns;
-
-static int retrieve_terminal_width(void)
-{
-#ifdef TIOCGWINSZ
-	struct winsize ws;
-	if (ioctl(1, TIOCGWINSZ, &ws))  /* e.g., ENOSYS */
-		return 0;
-	return ws.ws_col;
-#else
-	return 0;
-#endif
-}
-
  /*
   * This is split up from the rest of git so that we can do
   * something different on Windows.
@@ -88,16 +73,15 @@ const char *git_pager(int stdout_is_tty)
  void setup_pager(void)
  {
  	const char *pager = git_pager(isatty(1));
-	int width;

  	if (!pager || pager_in_use())
  		return;

-	setenv("GIT_PAGER_IN_USE", "true", 1);
+	/* prime the term_columns() cache before it is too
+	 * late and stdout is replaced */
+	(void) term_columns();

-	width = retrieve_terminal_width();
-	if (width)
-		max_columns = width;
+	setenv("GIT_PAGER_IN_USE", "true", 1);

  	/* spawn the pager */
  	pager_argv[0] = pager;
@@ -132,17 +116,43 @@ int pager_in_use(void)
  	return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0;
  }

+/*
+ * Return cached value (if set) or $COLUMNS (if set and positive) or
+ * ioctl(1, TIOCGWINSZ).ws_col (if positive) or 80.
+ *
+ * $COLUMNS even if set, is usually not exported, so
+ * the variable can be used to override autodection.
+ * This behaviour conforms to The Single UNIX Specification, Version 2
+ * 
(http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003).
+ */
  int term_columns(void)
  {
-	char *col_string = getenv("COLUMNS");
+	static int term_columns_cache;
+
+	char *col_string;
  	int n_cols;

-	if (col_string && (n_cols = atoi(col_string)) > 0)
-		return n_cols;
+	if (term_columns_cache)
+		return term_columns_cache;
+
+	col_string = getenv("COLUMNS");
+	if (col_string && (n_cols = atoi(col_string)) > 0) {
+		term_columns_cache = n_cols;
+		return term_columns_cache;
+	}

-	if (spawned_pager && max_columns)
-		return max_columns;
+#ifdef TIOCGWINSZ
+	{
+		struct winsize ws;
+		if (!ioctl(1, TIOCGWINSZ, &ws)) {
+			if (ws.ws_col) {
+				term_columns_cache = ws.ws_col;
+				return term_columns_cache;
+			}
+		}
+	}
+#endif

-	n_cols = retrieve_terminal_width();
-	return n_cols ? n_cols : 80;
+	term_columns_cache = 80;
+	return term_columns_cache;
  }
-- 
1.7.9.310.g883d84c.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 2/3] help.c: make term_columns() cached and export it
  2012-02-11 10:49             ` Zbigniew Jędrzejewski-Szmek
@ 2012-02-12  9:40               ` Junio C Hamano
  2012-02-12 14:12                 ` [PATCH 1/2] Save terminal width before setting up pager and export term_columns() Zbigniew Jędrzejewski-Szmek
  2012-02-12 14:16                 ` [PATCH 2/2] Rename lineno_width to decimal_width and export it Zbigniew Jędrzejewski-Szmek
  0 siblings, 2 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-12  9:40 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek
  Cc: Nguyen Thai Ngoc Duy, git, Michael J Gruber, Ramsay Jones

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> Junio suggested that "a new file, term.c or something, be a lot more
> suitable home for the function you will be reusing from diff and other
> parts of the system". Nevertheless, I think that adding two files (.c
> and .h) to hold one function isn't worth it. It can live in pager.c.
> Terminal size is logically connected to paging after all.

I do not have any objection to the above reasoning.

Given that Nguyen's columns topic hasn't been merged to 'next' and I
expect it will be re-rolled anyway, I would prefer a patch that does the
move from help.c to pager.c that is based directly on v1.7.9, on top of
which your work and the columns topic can both be built independently.

Thanks.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 1/2] Save terminal width before setting up pager and export term_columns()
  2012-02-12  9:40               ` Junio C Hamano
@ 2012-02-12 14:12                 ` Zbigniew Jędrzejewski-Szmek
  2012-02-13 23:00                   ` Junio C Hamano
  2012-02-14 11:44                   ` Nguyen Thai Ngoc Duy
  2012-02-12 14:16                 ` [PATCH 2/2] Rename lineno_width to decimal_width and export it Zbigniew Jędrzejewski-Szmek
  1 sibling, 2 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-12 14:12 UTC (permalink / raw)
  To: git, gitster, pclouds; +Cc: Michael J Gruber, Zbigniew Jędrzejewski-Szmek

term_columns() checks for terminal width via ioctl(2). After
redirecting, stdin is no longer terminal to get terminal width.

Check terminal width and save it before redirecting stdin in
setup_pager() by calling term_columns().

Move term_columns() to pager.c and export it in cache.h.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 cache.h |  1 +
 help.c  | 22 -------------------
 pager.c | 45 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 22 deletions(-)

This replaces cb0850f (Save terminal width before setting up pager -
2012-02-04) from Nguyễn Thái Ngọc Duy and my previous patch to export
term_columns().

This is directly on top of v1.7.9 as requested.

I removed Signed-off-by from Nguyễn and Junio because the patch is
substantially changed.

diff --git a/cache.h b/cache.h
index 10afd71..2f30b3a 100644
--- a/cache.h
+++ b/cache.h
@@ -1175,6 +1175,7 @@ extern void setup_pager(void);
 extern const char *pager_program;
 extern int pager_in_use(void);
 extern int pager_use_color;
+extern int term_columns(void);
 
 extern const char *editor_program;
 extern const char *askpass_program;
diff --git a/help.c b/help.c
index cbbe966..14eefc9 100644
--- a/help.c
+++ b/help.c
@@ -5,28 +5,6 @@
 #include "help.h"
 #include "common-cmds.h"
 
-/* most GUI terminals set COLUMNS (although some don't export it) */
-static int term_columns(void)
-{
-	char *col_string = getenv("COLUMNS");
-	int n_cols;
-
-	if (col_string && (n_cols = atoi(col_string)) > 0)
-		return n_cols;
-
-#ifdef TIOCGWINSZ
-	{
-		struct winsize ws;
-		if (!ioctl(1, TIOCGWINSZ, &ws)) {
-			if (ws.ws_col)
-				return ws.ws_col;
-		}
-	}
-#endif
-
-	return 80;
-}
-
 void add_cmdname(struct cmdnames *cmds, const char *name, int len)
 {
 	struct cmdname *ent = xmalloc(sizeof(*ent) + len + 1);
diff --git a/pager.c b/pager.c
index 975955b..b8049a4 100644
--- a/pager.c
+++ b/pager.c
@@ -76,6 +76,10 @@ void setup_pager(void)
 	if (!pager)
 		return;
 
+	/* prime the term_columns() cache before it is too
+	 * late and stdout is replaced */
+	(void) term_columns();
+
 	setenv("GIT_PAGER_IN_USE", "true", 1);
 
 	/* spawn the pager */
@@ -110,3 +114,44 @@ int pager_in_use(void)
 	env = getenv("GIT_PAGER_IN_USE");
 	return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0;
 }
+
+/*
+ * Return cached value (if set) or $COLUMNS (if set and positive) or
+ * ioctl(1, TIOCGWINSZ).ws_col (if positive) or 80.
+ *
+ * $COLUMNS even if set, is usually not exported, so
+ * the variable can be used to override autodection.
+ * This behaviour conforms to The Single UNIX Specification, Version 2
+ * (http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003).
+ */
+int term_columns(void)
+{
+	static int term_columns_cache;
+
+	char *col_string;
+	int n_cols;
+
+	if (term_columns_cache)
+		return term_columns_cache;
+
+	col_string = getenv("COLUMNS");
+	if (col_string && (n_cols = atoi(col_string)) > 0) {
+		term_columns_cache = n_cols;
+		return term_columns_cache;
+	}
+
+#ifdef TIOCGWINSZ
+	{
+		struct winsize ws;
+		if (!ioctl(1, TIOCGWINSZ, &ws)) {
+			if (ws.ws_col) {
+				term_columns_cache = ws.ws_col;
+				return term_columns_cache;
+			}
+		}
+	}
+#endif
+
+	term_columns_cache = 80;
+	return term_columns_cache;
+}
-- 
1.7.9.3.g2429d.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 2/2] Rename lineno_width to decimal_width and export it
  2012-02-12  9:40               ` Junio C Hamano
  2012-02-12 14:12                 ` [PATCH 1/2] Save terminal width before setting up pager and export term_columns() Zbigniew Jędrzejewski-Szmek
@ 2012-02-12 14:16                 ` Zbigniew Jędrzejewski-Szmek
  2012-02-13 23:29                   ` Junio C Hamano
  1 sibling, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-12 14:16 UTC (permalink / raw)
  To: git, gitster, pclouds; +Cc: Michael J Gruber, Zbigniew Jędrzejewski-Szmek

This function will be used in calculating diff --stat graph width.
The name is changed because the function works for any number.
The function is moved from builtins/blame.c to pager.c because it
will be used not only in builtins/blame.c.
---
 builtin/blame.c | 18 +++---------------
 cache.h         |  1 +
 pager.c         | 12 ++++++++++++
 3 files changed, 16 insertions(+), 15 deletions(-)

This is another function to be exported. I hope it can be exported
together with term_columns(). I'll use it the next version of the diff
--stat patch.

diff --git a/builtin/blame.c b/builtin/blame.c
index 5a67c20..f028e8a 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1829,18 +1829,6 @@ static int read_ancestry(const char *graft_file)
 }
 
 /*
- * How many columns do we need to show line numbers in decimal?
- */
-static int lineno_width(int lines)
-{
-	int i, width;
-
-	for (width = 1, i = 10; i <= lines; width++)
-		i *= 10;
-	return width;
-}
-
-/*
  * How many columns do we need to show line numbers, authors,
  * and filenames?
  */
@@ -1880,9 +1868,9 @@ static void find_alignment(struct scoreboard *sb, int *option)
 		if (largest_score < ent_score(sb, e))
 			largest_score = ent_score(sb, e);
 	}
-	max_orig_digits = lineno_width(longest_src_lines);
-	max_digits = lineno_width(longest_dst_lines);
-	max_score_digits = lineno_width(largest_score);
+	max_orig_digits = decimal_width(longest_src_lines);
+	max_digits = decimal_width(longest_dst_lines);
+	max_score_digits = decimal_width(largest_score);
 }
 
 /*
diff --git a/cache.h b/cache.h
index 2f30b3a..3857dfd 100644
--- a/cache.h
+++ b/cache.h
@@ -1176,6 +1176,7 @@ extern const char *pager_program;
 extern int pager_in_use(void);
 extern int pager_use_color;
 extern int term_columns(void);
+extern int decimal_width(int number);
 
 extern const char *editor_program;
 extern const char *askpass_program;
diff --git a/pager.c b/pager.c
index b8049a4..b6d44ef 100644
--- a/pager.c
+++ b/pager.c
@@ -155,3 +155,15 @@ int term_columns(void)
 	term_columns_cache = 80;
 	return term_columns_cache;
 }
+
+/*
+ * How many columns do we need to show numbers in decimal?
+ */
+int decimal_width(int number)
+{
+	int i, width;
+
+	for (width = 1, i = 10; i <= number; width++)
+		i *= 10;
+	return width;
+}
-- 
1.7.9.3.g2429d.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3] diff --stat: use the full terminal width
  2012-02-10 18:24         ` [PATCH 0/3 v2] " Junio C Hamano
@ 2012-02-12 14:30           ` Zbigniew Jędrzejewski-Szmek
  2012-02-14  1:08             ` Junio C Hamano
  0 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-12 14:30 UTC (permalink / raw)
  To: git, gitster, pclouds; +Cc: Michael J Gruber, Zbigniew Jędrzejewski-Szmek

Use as many columns as necessary for filenames, as few columns as
necessary for change counts, and up to 40 columns for the histogram.

Some projects (especially in Java), have long filename paths, with
nested directories or long individual filenames. When files are
renamed, the stat output can be almost useless. If the middle part
between { and } is long (because the file was moved to a completely
different directory), then most of the path would be truncated.

It makes sense to detect and use the full terminal width and display
full filenames if possible.

If commits changing a lot of lines are displayed in a wide terminal
window (200 or more columns), and the +- graph would use the full
width, the output would look bad. Messages wrapped to about 80
columns would be interspersed with very long +- lines. It makes
sense to limit the width of the histogram to a fixed value, even if more
columns are available. This fixed value is subjectively hard-coded to
be 40 columns, which seems to work well for git.git and linux-2.6.git and
some other repositories.

If there isn't enough columns to print both the filename and the histogram,
at least 5/8 of available space is devoted to filenames. On a standard 80 column
terminal, or if not connected to a terminal and using the default of 80 columns,
this gives the same partition as before.

Number of columns required for change counts is computed based on
the maximum number of changed lines. This means that usually a few more
columns will be available for the filenames and the histogram.

Tests are added for various combinations of long filename and big change
count and ways to specify widths.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
Hi,
this is v3 (reduced to one patch) on top of:
- Save terminal width before setting up pager and export term_columns(),
- Rename lineno_width to decimal_width and export it.

The logic is described in a comment in show_stats() in diff.c. In case
of a column 80 terminal window, the output will not be identical,
because of using decimal_width, but it'll be very close to what was
there previously.

v3:
- use decimal_width(max_change) to calculate number of columns
  required for change counts
- rework the logic to divide columns
- document the logic in comments, update docs
- add more tests

v2:
- style fixes
- some tests for git-format-patch added
- patches 3 and 4 squashed together, since they touch the same lines
- graph width is limited to 40 columns, even if there's more space
- patch descriptions extended and cleared up

 Documentation/diff-options.txt | 14 +++---
 diff.c                         | 93 +++++++++++++++++++++++++------------
 t/t4014-format-patch.sh        | 98 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 168 insertions(+), 37 deletions(-)

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 9f7cba2..35dfdfb 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -53,13 +53,15 @@ endif::git-format-patch[]
 	Generate a diff using the "patience diff" algorithm.
 
 --stat[=<width>[,<name-width>[,<count>]]]::
-	Generate a diffstat.  You can override the default
-	output width for 80-column terminal by `--stat=<width>`.
-	The width of the filename part can be controlled by
-	giving another width to it separated by a comma.
+	Generate a diffstat. By default, as much space as necessary
+	will be used for the filename part, and up to 40 columns for
+	the graph histogram. Maximum width defaults to terminal width,
+	or 80 columns if not connected to a terminal, and can be
+	overriden by `<width>`. The width of the filename part can be
+	limited by giving another width `<name-width>` after a comma.
 	By giving a third parameter `<count>`, you can limit the
-	output to the first `<count>` lines, followed by
-	`...` if there are more.
+	output to the first `<count>` lines, followed by `...` if
+	there are more.
 +
 These parameters can also be set individually with `--stat-width=<width>`,
 `--stat-name-width=<name-width>` and `--stat-count=<count>`.
diff --git a/diff.c b/diff.c
index 7e15426..7abcbe9 100644
--- a/diff.c
+++ b/diff.c
@@ -1327,7 +1327,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	int i, len, add, del, adds = 0, dels = 0;
 	uintmax_t max_change = 0, max_len = 0;
 	int total_files = data->nr;
-	int width, name_width, count;
+	int width, name_width, graph_width, number_width, count;
 	const char *reset, *add_c, *del_c;
 	const char *line_prefix = "";
 	int extra_shown = 0;
@@ -1341,25 +1341,13 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		line_prefix = msg->buf;
 	}
 
-	width = options->stat_width ? options->stat_width : 80;
-	name_width = options->stat_name_width ? options->stat_name_width : 50;
-	count = options->stat_count ? options->stat_count : data->nr;
-
-	/* Sanity: give at least 5 columns to the graph,
-	 * but leave at least 10 columns for the name.
-	 */
-	if (width < 25)
-		width = 25;
-	if (name_width < 10)
-		name_width = 10;
-	else if (width < name_width + 15)
-		name_width = width - 15;
-
 	/* Find the longest filename and max number of changes */
 	reset = diff_get_color_opt(options, DIFF_RESET);
 	add_c = diff_get_color_opt(options, DIFF_FILE_NEW);
 	del_c = diff_get_color_opt(options, DIFF_FILE_OLD);
 
+	count = options->stat_count ? options->stat_count : data->nr;
+
 	for (i = 0; (i < count) && (i < data->nr); i++) {
 		struct diffstat_file *file = data->files[i];
 		uintmax_t change = file->added + file->deleted;
@@ -1380,19 +1368,63 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	}
 	count = i; /* min(count, data->nr) */
 
-	/* Compute the width of the graph part;
-	 * 10 is for one blank at the beginning of the line plus
-	 * " | count " between the name and the graph.
+	/* We have width = stat_width or term_columns() columns total.
+	 * We want a maximum of min(max_len, stat_name_width) for the name part.
+	 * We want a maximum of min(max_change, 40) for the +- part.
+	 * We also need 1 for " " and 4 + decimal_width(max_change)
+	 * for " | NNNN " and one for " " at the end, altogether
+	 * 6 + decimal_width(max_change).
+	 *
+	 * If there's not enough space, we will use stat_name_width
+	 * or 5/8*width for filename, and the rest for constant
+	 * elements + histogram, but no more than 40 for the histogram.
+	 * (5/8 gives 50 for filename and 30 for constant parts and
+	 * histogram for the standard terminal size).
 	 *
-	 * From here on, name_width is the width of the name area,
-	 * and width is the width of the graph area.
+	 * In other words: stat_width limits the maximum width, and
+	 * stat_name_width fixes the maximum width of the filename,
+	 * and is also used to divide available columns if there
+	 * aren't enough.
 	 */
-	name_width = (name_width < max_len) ? name_width : max_len;
-	if (width < (name_width + 10) + max_change)
-		width = width - (name_width + 10);
-	else
-		width = max_change;
+	width = options->stat_width ? options->stat_width : term_columns();
+	number_width = decimal_width(max_change);
+	/* first sizes that are wanted */
+	graph_width = max_change < 40 ? max_change : 40;
+	name_width = (options->stat_name_width > 0 &&
+		      options->stat_name_width < max_len) ?
+		options->stat_name_width : max_len;
+
+	/* sanity: guarantee a minimum and maximum width */
+	if (width < 25)
+		width = 25;
+
+	if (name_width + number_width + 6 + graph_width > width) {
+		if (graph_width > width * 3/8 - number_width - 6)
+			graph_width = width * 3/8 - number_width - 6;
+		if (graph_width > 40)
+			graph_width =  40;
+		if (name_width > width - number_width - 6 - graph_width)
+			name_width = width - number_width - 6 - graph_width;
+		else
+			graph_width = width - number_width - 6 - name_width;
+	}
 
+	/* More sanity: give at least 5 columns to the graph,
+	 * but leave at least 10 columns for the name.
+	 *
+	 * This should already be satisfied, unless max_change is
+	 * really huge. If the window is extemely narrow, this might
+	 * overflow available columns.
+	 */
+	if (name_width < 10 && max_len >= 10)
+		name_width = 10;
+	if (graph_width < 5 && max_change >= 5)
+		graph_width = 5;
+
+	/* From here name_width is the width of the name area,
+	 * and graph_width is the width of the graph area.
+	 * max_change is used to scale graph properly.
+	 */
 	for (i = 0; i < count; i++) {
 		const char *prefix = "";
 		char *name = data->files[i]->print_name;
@@ -1448,14 +1480,15 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		adds += add;
 		dels += del;
 
-		if (width <= max_change) {
-			add = scale_linear(add, width, max_change);
-			del = scale_linear(del, width, max_change);
+		if (graph_width <= max_change) {
+			add = scale_linear(add, graph_width, max_change);
+			del = scale_linear(del, graph_width, max_change);
 		}
 		fprintf(options->file, "%s", line_prefix);
 		show_name(options->file, prefix, name, len);
-		fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,
-				added + deleted ? " " : "");
+		fprintf(options->file, " %*"PRIuMAX"%s",
+			number_width, added + deleted,
+			added + deleted ? " " : "");
 		show_graph(options->file, '+', add, add_c, reset);
 		show_graph(options->file, '-', del, del_c, reset);
 		fprintf(options->file, "\n");
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 6797512..91be989 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -519,7 +519,7 @@ test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 
 cat > expect << EOF
 ---
- file |   16 ++++++++++++++++
+ file | 16 ++++++++++++++++
  1 files changed, 16 insertions(+), 0 deletions(-)
 
 diff --git a/file b/file
@@ -894,4 +894,100 @@ test_expect_success 'format patch ignores color.ui' '
 	test_cmp expect actual
 '
 
+name=aaaaaaaaaa
+name=$name$name$name$name$name$name$name$name$name$name$name$name
+test_expect_success 'preparation' "
+	> ${name} &&
+	git add ${name} &&
+	git commit -m message &&
+	echo a > ${name} &&
+	git commit -m message ${name}
+"
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+test_expect_success 'format patch graph width is 80 columns' '
+	git format-patch --stat --stdout -1 |
+		grep -m 1 aaaaa > actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+test_expect_success 'format patch --stat=width with long name' '
+	git format-patch --stat=40 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-width=width works long name' '
+	git format-patch --stat-width=40 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat=...,name-width with long name' '
+	git format-patch --stat=60,32 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-name-width with long name' '
+	git format-patch --stat-name-width=32 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'preparation' '
+	> abcd &&
+	git add abcd &&
+	git commit -m message &&
+	seq 1000 > abcd &&
+	git commit -m message abcd
+'
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++
+EOF
+test_expect_success 'format patch graph width is 40 columns' '
+	git format-patch --stat --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch ignores COLUMNS' '
+	COLUMNS=200 git format-patch --stat --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++
+EOF
+test_expect_success 'format patch --stat=width with big change' '
+	git format-patch --stat=40 --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-width=width with big change' '
+	git format-patch --stat-width=40 --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
+EOF
+test_expect_success 'format patch --stat=width with big change and long name' '
+	cp abcd aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+	git add aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+	git commit -m message &&
+	git format-patch --stat-width=60 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.7.9.3.g2429d.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/2] Save terminal width before setting up pager and export term_columns()
  2012-02-12 14:12                 ` [PATCH 1/2] Save terminal width before setting up pager and export term_columns() Zbigniew Jędrzejewski-Szmek
@ 2012-02-13 23:00                   ` Junio C Hamano
  2012-02-14 11:44                   ` Nguyen Thai Ngoc Duy
  1 sibling, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-13 23:00 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, pclouds, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> term_columns() checks for terminal width via ioctl(2). After
> redirecting, stdin is no longer terminal to get terminal width.

s/stdin/stdout/

> Check terminal width and save it before redirecting stdin in
> setup_pager() by calling term_columns().
>
> Move term_columns() to pager.c and export it in cache.h.
>
> Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
> ---

Thanks.

It probably is worth mentioning what the end-user visible effect of this
change is somewhere in the log message.

I somehow find "term_columns_cache" a funny name for this variable and
does not describe what it does.  Unlike a real cache, we cannot discard it
and re-read it even if we later wanted to.

I am tempted to rewrite the patch like this to update other minor style
issues.

-- >8 --
From: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Date: Sun, 12 Feb 2012 15:12:32 +0100
Subject: [PATCH] pager: find out the terminal width before spawning the pager

term_columns() checks for terminal width via ioctl(2) on the standard
output, but we spawn the pager too early for this check to be useful.

The effect of this buglet can be observed by opening a wide terminal and
running "git -p help --all", which still shows 80-column output, while
"git help --all" uses the full terminal width. Run the check before we
spawn the pager to fix this.

While at it, move term_columns() to pager.c and export it from cache.h so
that callers other than the help subsystem can use it.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 cache.h |    1 +
 help.c  |   22 ----------------------
 pager.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/cache.h b/cache.h
index 79c612f..c7e3b4d 100644
--- a/cache.h
+++ b/cache.h
@@ -1172,6 +1172,7 @@ extern void setup_pager(void);
 extern const char *pager_program;
 extern int pager_in_use(void);
 extern int pager_use_color;
+extern int term_columns(void);
 
 extern const char *editor_program;
 extern const char *askpass_program;
diff --git a/help.c b/help.c
index cbbe966..14eefc9 100644
--- a/help.c
+++ b/help.c
@@ -5,28 +5,6 @@
 #include "help.h"
 #include "common-cmds.h"
 
-/* most GUI terminals set COLUMNS (although some don't export it) */
-static int term_columns(void)
-{
-	char *col_string = getenv("COLUMNS");
-	int n_cols;
-
-	if (col_string && (n_cols = atoi(col_string)) > 0)
-		return n_cols;
-
-#ifdef TIOCGWINSZ
-	{
-		struct winsize ws;
-		if (!ioctl(1, TIOCGWINSZ, &ws)) {
-			if (ws.ws_col)
-				return ws.ws_col;
-		}
-	}
-#endif
-
-	return 80;
-}
-
 void add_cmdname(struct cmdnames *cmds, const char *name, int len)
 {
 	struct cmdname *ent = xmalloc(sizeof(*ent) + len + 1);
diff --git a/pager.c b/pager.c
index 975955b..e06cfa0 100644
--- a/pager.c
+++ b/pager.c
@@ -76,6 +76,12 @@ void setup_pager(void)
 	if (!pager)
 		return;
 
+	/*
+	 * force computing the width of the terminal before we redirect
+	 * the standard output to the pager.
+	 */
+	(void) term_columns();
+
 	setenv("GIT_PAGER_IN_USE", "true", 1);
 
 	/* spawn the pager */
@@ -110,3 +116,40 @@ int pager_in_use(void)
 	env = getenv("GIT_PAGER_IN_USE");
 	return env ? git_config_bool("GIT_PAGER_IN_USE", env) : 0;
 }
+
+/*
+ * Return cached value (if set) or $COLUMNS (if set and positive) or
+ * ioctl(1, TIOCGWINSZ).ws_col (if positive) or 80.
+ *
+ * $COLUMNS even if set, is usually not exported, so
+ * the variable can be used to override autodection.
+ * This behaviour conforms to The Single UNIX Specification, Version 2
+ * (http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html#tag_002_003).
+ */
+int term_columns(void)
+{
+	static int term_columns_at_startup;
+
+	char *col_string;
+	int n_cols;
+
+	if (term_columns_at_startup)
+		return term_columns_at_startup;
+
+	term_columns_at_startup = 80;
+
+	col_string = getenv("COLUMNS");
+	if (col_string && (n_cols = atoi(col_string)) > 0)
+		term_columns_at_startup = n_cols;
+#ifdef TIOCGWINSZ
+	else {
+		struct winsize ws;
+		if (!ioctl(1, TIOCGWINSZ, &ws)) {
+			if (ws.ws_col) {
+				term_columns_at_startup = ws.ws_col;
+			}
+		}
+	}
+#endif
+	return term_columns_at_startup;
+}
-- 
1.7.9.300.gd47e4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 2/2] Rename lineno_width to decimal_width and export it
  2012-02-12 14:16                 ` [PATCH 2/2] Rename lineno_width to decimal_width and export it Zbigniew Jędrzejewski-Szmek
@ 2012-02-13 23:29                   ` Junio C Hamano
  2012-02-14 12:24                     ` [PATCH v2] make lineno_width() from blame reusable for others Zbigniew Jędrzejewski-Szmek
  0 siblings, 1 reply; 46+ messages in thread
From: Junio C Hamano @ 2012-02-13 23:29 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, pclouds, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> This function will be used in calculating diff --stat graph width.
> The name is changed because the function works for any number.
> The function is moved from builtins/blame.c to pager.c because it
> will be used not only in builtins/blame.c.

I'd prefer to see description of preliminary changes phrased without
depending too heavily on things that hasn't happened when possible.
Making a generic helper function to count digits necessary to print a
cardinal number available to future callers is a good thing by itself,
even if the "dynamic --stat width computation" turned out to be a bad
idea for whatever reason (I am not saying it is a bad idea here).

Perhaps like this.

	Subject: make lineno_width() from blame reusable for others

	builtin/blame.c has a helper function to compute how many columns
	we need to show a line-number, whose implementation is reusable as
	a more generic helper function to count the number of columns
	necessary to show any cardinal number.

	Rename it to decimal_width(), move it to pager.c and export it for
        use by future callers.

And you can say something like "I'll be using this in 'diff --stat' in
later patches" after the three-dash line.

> ---

Sign-off before the three-dash line?

> +/*
> + * How many columns do we need to show numbers in decimal?

s/numbers/this number/;

> + */
> +int decimal_width(int number)

Don't we want to make the argument "unsigned number" instead?

> +{
> +	int i, width;
> +
> +	for (width = 1, i = 10; i <= number; width++)
> +		i *= 10;
> +	return width;
> +}

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3] diff --stat: use the full terminal width
  2012-02-12 14:30           ` [PATCH v3] diff --stat: use the full " Zbigniew Jędrzejewski-Szmek
@ 2012-02-14  1:08             ` Junio C Hamano
  2012-02-14 23:45               ` [PATCH 1/3 v4] " Zbigniew Jędrzejewski-Szmek
  0 siblings, 1 reply; 46+ messages in thread
From: Junio C Hamano @ 2012-02-14  1:08 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, pclouds, Michael J Gruber

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> Use as many columns as necessary for filenames, as few columns as
> necessary for change counts, and up to 40 columns for the histogram.
>
> Some projects (especially in Java), have long filename paths, with
> nested directories or long individual filenames. When files are
> renamed, the stat output can be almost useless. If the middle part

s/the stat output/the name part in &/;

> between { and } is long (because the file was moved to a completely
> different directory), then most of the path would be truncated.
>
> It makes sense to detect and use the full terminal width and display
> full filenames if possible.
>
> If commits changing a lot of lines are displayed in a wide terminal
> window (200 or more columns), and the +- graph would use the full
> width, the output would look bad. Messages wrapped to about 80
> columns would be interspersed with very long +- lines. It makes
> sense to limit the width of the histogram to a fixed value, even if more

I do not think the graph ++++++--- part is "histogram", which is a name
for a specific type of graph that depicts a distribution of data.

We show the number of lines changed in a graph.  Unless people come up
with a better name, I would suggest calling it just "the graph part", or
simply "the graph", throughout the patch.

> columns are available. This fixed value is subjectively hard-coded to
> be 40 columns, which seems to work well for git.git and linux-2.6.git and
> some other repositories.
>
> If there isn't enough columns to print both the filename and the histogram,
> at least 5/8 of available space is devoted to filenames. On a standard 80 column
> terminal, or if not connected to a terminal and using the default of 80 columns,
> this gives the same partition as before.
>
> Number of columns required for change counts is computed based on
> the maximum number of changed lines. This means that usually a few more
> columns will be available for the filenames and the histogram.
>
> Tests are added for various combinations of long filename and big change
> count and ways to specify widths.
>
> Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
> ---
> ...
> diff --git a/diff.c b/diff.c
> index 7e15426..7abcbe9 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -1327,7 +1327,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>  	int i, len, add, del, adds = 0, dels = 0;
>  	uintmax_t max_change = 0, max_len = 0;
>  	int total_files = data->nr;
> -	int width, name_width, count;
> +	int width, name_width, graph_width, number_width, count;
>  	const char *reset, *add_c, *del_c;
>  	const char *line_prefix = "";
>  	int extra_shown = 0;
> @@ -1341,25 +1341,13 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>  		line_prefix = msg->buf;
>  	}
>  
> -	width = options->stat_width ? options->stat_width : 80;
> -	name_width = options->stat_name_width ? options->stat_name_width : 50;
> -	count = options->stat_count ? options->stat_count : data->nr;

It was somewhat distracting that you moved this "count =" below, which I
do not think was necessary.

> -	/* Sanity: give at least 5 columns to the graph,
> -	 * but leave at least 10 columns for the name.
> -	 */
> -	if (width < 25)
> -		width = 25;
> -	if (name_width < 10)
> -		name_width = 10;
> -	else if (width < name_width + 15)
> -		name_width = width - 15;

Removal of this sanity check is fine as long as sanity is kept by the new
code in the later part. This was primarily so that people won't specify
impossible values (e.g. what happens when name_width that is wider than
the total width is given).

> ...
> +	count = options->stat_count ? options->stat_count : data->nr;
> +
> @@ -1380,19 +1368,63 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
>  	}
>  	count = i; /* min(count, data->nr) */
>  
> -	/* Compute the width of the graph part;
> -	 * 10 is for one blank at the beginning of the line plus
> -	 * " | count " between the name and the graph.


> +	/* We have width = stat_width or term_columns() columns total.

Just a style, but in the more recent part of the codebase,

	/*
         * We have width = ....

is preferred.

> +	 * We want a maximum of min(max_len, stat_name_width) for the name part.
> +	 * We want a maximum of min(max_change, 40) for the +- part.
> +	 * We also need 1 for " " and 4 + decimal_width(max_change)
> +	 * for " | NNNN " and one for " " at the end, altogether
> +	 * 6 + decimal_width(max_change).

The math looks correct but 'one for " " at the end' sounds as if you are
printing a SP, but I think we simply avoid printing anything, so perhaps
rewrite it to "we leave one column at the end" or something.

> +	 * If there's not enough space, we will use stat_name_width
> +	 * or 5/8*width for filename, and the rest for constant

"A or B for filename"---unclear how it picks between A or B.

"A or B, whichever is shorter, for filename", perhaps?

> +	 * elements + histogram, but no more than 40 for the histogram.
> +	 * (5/8 gives 50 for filename and 30 for constant parts and
> +	 * histogram for the standard terminal size).
>  	 *
> -	 * From here on, name_width is the width of the name area,
> -	 * and width is the width of the graph area.
> +	 * In other words: stat_width limits the maximum width, and
> +	 * stat_name_width fixes the maximum width of the filename,
> +	 * and is also used to divide available columns if there
> +	 * aren't enough.
>  	 */
> -	name_width = (name_width < max_len) ? name_width : max_len;
> -	if (width < (name_width + 10) + max_change)
> -		width = width - (name_width + 10);
> -	else
> -		width = max_change;
> +	width = options->stat_width ? options->stat_width : term_columns();
> +	number_width = decimal_width(max_change);
> +	/* first sizes that are wanted */

Missing verb; "first, compute sizes that are ..."?

> +	graph_width = max_change < 40 ? max_change : 40;
> +	name_width = (options->stat_name_width > 0 &&
> +		      options->stat_name_width < max_len) ?
> +		options->stat_name_width : max_len;

mental note: name_width can be limited to max_len, and graph_width may be
quite small when max_change is small.  The total graph may be much smaller
than the terminal width in such a case (and it is not a wasted space on
the right hand side of the terminal).

> +	/* sanity: guarantee a minimum and maximum width */
> +	if (width < 25)
> +		width = 25;
> +
> +	if (name_width + number_width + 6 + graph_width > width) {
> +		if (graph_width > width * 3/8 - number_width - 6)
> +			graph_width = width * 3/8 - number_width - 6;
> +		if (graph_width > 40)
> +			graph_width =  40;
> +		if (name_width > width - number_width - 6 - graph_width)
> +			name_width = width - number_width - 6 - graph_width;
> +		else
> +			graph_width = width - number_width - 6 - name_width;
> +	}
>  
> +	/* More sanity: give at least 5 columns to the graph,

Hrm, having to have a separate "More sanity" is ugly, and you seem to
already know it "This should already be satisfied...".

Can the logic above be tightened to make this "mopping up" unnecessary?

> +	 * but leave at least 10 columns for the name.
> +	 *
> +	 * This should already be satisfied, unless max_change is
> +	 * really huge. If the window is extemely narrow, this might
> +	 * overflow available columns.
> +	 */
> +	if (name_width < 10 && max_len >= 10)
> +		name_width = 10;

The logic up to this point uses the same "25 <= width, 10 <= name_width"
as the original to ensure that graph and the fixed part can use at least
15 columns.  And then you do this:

> +	if (graph_width < 5 && max_change >= 5)
> +		graph_width = 5;

which means you are allocating 10 columns for fixed part.  In the
original, it was OK to give fixed number of columns for fixed part like
this, as it always gave fixed 5 columns to show the number.  Don't you
need to adjust that 10 depending on the decimal_width(max_change), now
your number_width flexes?

This patch also breaks many existing tests that need to be adjusted for
the change to use decimal_width(max_change), which I do not care to fix up
for you.  Perhaps that part of the change needs to be split out into a
separate patch.

Among the tests it breaks is t1200-tutorial.sh, which means that the
tutorial document that has illustration of the sample output also needs to
be updated before the final round.

Thanks.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/2] Save terminal width before setting up pager and export term_columns()
  2012-02-12 14:12                 ` [PATCH 1/2] Save terminal width before setting up pager and export term_columns() Zbigniew Jędrzejewski-Szmek
  2012-02-13 23:00                   ` Junio C Hamano
@ 2012-02-14 11:44                   ` Nguyen Thai Ngoc Duy
  2012-02-14 11:53                     ` Zbigniew Jędrzejewski-Szmek
  1 sibling, 1 reply; 46+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2012-02-14 11:44 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber

2012/2/12 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>:
> This replaces cb0850f (Save terminal width before setting up pager -
> 2012-02-04) from Nguyễn Thái Ngọc Duy and my previous patch to export
> term_columns().
>
> This is directly on top of v1.7.9 as requested.
>
> I removed Signed-off-by from Nguyễn and Junio because the patch is
> substantially changed.

No problems. I will rebase my series on top of this patch (its final
version, that is).
-- 
Duy

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/2] Save terminal width before setting up pager and export term_columns()
  2012-02-14 11:44                   ` Nguyen Thai Ngoc Duy
@ 2012-02-14 11:53                     ` Zbigniew Jędrzejewski-Szmek
  0 siblings, 0 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-14 11:53 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy; +Cc: git, gitster, Michael J Gruber

On 02/14/2012 12:44 PM, Nguyen Thai Ngoc Duy wrote:
> 2012/2/12 Zbigniew Jędrzejewski-Szmek<zbyszek@in.waw.pl>:
>> This replaces cb0850f (Save terminal width before setting up pager -
>> 2012-02-04) from Nguyễn Thái Ngọc Duy and my previous patch to export
>> term_columns().
>>
>> This is directly on top of v1.7.9 as requested.
>>
>> I removed Signed-off-by from Nguyễn and Junio because the patch is
>> substantially changed.
>
> No problems. I will rebase my series on top of this patch (its final
> version, that is).
Hi, I think that Junio's will be the final version. I have no objections 
to it.

Zbyszek

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v2] make lineno_width() from blame reusable for others
  2012-02-13 23:29                   ` Junio C Hamano
@ 2012-02-14 12:24                     ` Zbigniew Jędrzejewski-Szmek
  0 siblings, 0 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-14 12:24 UTC (permalink / raw)
  To: git, gitster, pclouds; +Cc: Michael J Gruber, Zbigniew Jędrzejewski-Szmek

builtin/blame.c has a helper function to compute how many columns we
need to show a line-number, whose implementation is reusable as a more
generic helper function to count the number of columns necessary to
show any cardinal number.

Rename it to decimal_width(), move it to pager.c and export it for use
by future callers. The argument type is changed to unsigned to underline
the fact that the function supports only non-negative numbers.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
I'll be using this in the 'diff --stat: use the full terminal width'
patch.

v2: - change arg type to unsigned
    - corrected commit message

 builtin/blame.c | 18 +++---------------
 cache.h         |  1 +
 pager.c         | 12 ++++++++++++
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 5a67c20..f028e8a 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1829,18 +1829,6 @@ static int read_ancestry(const char *graft_file)
 }
 
 /*
- * How many columns do we need to show line numbers in decimal?
- */
-static int lineno_width(int lines)
-{
-	int i, width;
-
-	for (width = 1, i = 10; i <= lines; width++)
-		i *= 10;
-	return width;
-}
-
-/*
  * How many columns do we need to show line numbers, authors,
  * and filenames?
  */
@@ -1880,9 +1868,9 @@ static void find_alignment(struct scoreboard *sb, int *option)
 		if (largest_score < ent_score(sb, e))
 			largest_score = ent_score(sb, e);
 	}
-	max_orig_digits = lineno_width(longest_src_lines);
-	max_digits = lineno_width(longest_dst_lines);
-	max_score_digits = lineno_width(largest_score);
+	max_orig_digits = decimal_width(longest_src_lines);
+	max_digits = decimal_width(longest_dst_lines);
+	max_score_digits = decimal_width(largest_score);
 }
 
 /*
diff --git a/cache.h b/cache.h
index 2f30b3a..3504bcc 100644
--- a/cache.h
+++ b/cache.h
@@ -1176,6 +1176,7 @@ extern const char *pager_program;
 extern int pager_in_use(void);
 extern int pager_use_color;
 extern int term_columns(void);
+extern int decimal_width(unsigned number);
 
 extern const char *editor_program;
 extern const char *askpass_program;
diff --git a/pager.c b/pager.c
index e06cfa0..2e16a9c 100644
--- a/pager.c
+++ b/pager.c
@@ -153,3 +153,15 @@ int term_columns(void)
 #endif
 	return term_columns_at_startup;
 }
+
+/*
+ * How many columns do we need to show this number in decimal?
+ */
+int decimal_width(unsigned number)
+{
+	int i, width;
+
+	for (width = 1, i = 10; i <= number; width++)
+		i *= 10;
+	return width;
+}
-- 
1.7.9.3.g2429d.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 1/3 v4] diff --stat: use the full terminal width
  2012-02-14  1:08             ` Junio C Hamano
@ 2012-02-14 23:45               ` Zbigniew Jędrzejewski-Szmek
  2012-02-14 23:45                 ` [PATCH 2/3 v4] diff --stat: better alignment for binary files Zbigniew Jędrzejewski-Szmek
                                   ` (4 more replies)
  0 siblings, 5 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-14 23:45 UTC (permalink / raw)
  To: git, gitster; +Cc: Michael J Gruber, pclouds, Zbigniew Jędrzejewski-Szmek

Use as many columns as necessary for filenames, as few columns as
necessary for change counts, and up to 40 columns for the graph.

Some projects (especially in Java), have long filename paths, with
nested directories or long individual filenames. When files are
renamed, the filename part in stat output can be almost useless. If
the middle part between { and } is long (because the file was moved to
a completely different directory), then most of the path would be
truncated.

It makes sense to detect and use the full terminal width and display
full filenames if possible.

If commits changing a lot of lines are displayed in a wide terminal
window (200 or more columns), and the +- graph would use the full
width, the output would look bad. Messages wrapped to about 80 columns
would be interspersed with very long +- lines. It makes sense to limit
the width of the graph part to a fixed value, even if more columns are
available. This fixed value is subjectively hard-coded to be 40
columns, which seems to work well for git.git and linux-2.6.git and
some other repositories.

If there isn't enough columns to print both the filename and the
graph, at least 5/8 of available space is devoted to filenames. On a
standard 80 column terminal, or if not connected to a terminal and
using the default of 80 columns, this gives the same partition as
before.

Number of columns required for change counts is computed based on the
maximum number of changed lines. This means that usually a few more
columns will be available for the filenames and the graph.

Eleven tests are added for various combinations of long filename and
big change count and ways to specify widths.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
Hi,

thank you for the review and comments. I think that they are all taken
into account.

While working on the tests, I noticed that it would be nice to align
the output for binary files ("Bin XXX -> YYY bytes") -- that change
is the subject of patch 2/3.

Tutorial is updated along with tests in 3/3.

I've added 'v4' to the other two patches in this series like to this
one, despite them beeing new. I hope that this is proper form.

v4:
- comments are updated and the word "histogram" is banished
- "mopping up" is removed (but the minimum width are guaranteed)

v3:
- use decimal_width(max_change) to calculate number of columns
  required for change counts
- rework the logic to divide columns
- document the logic in comments, update docs
- add more tests

v2:
- style fixes
- some tests for git-format-patch added
- patches 3 and 4 squashed together, since they touch the same lines
- graph width is limited to 40 columns, even if there's more space
- patch descriptions extended and cleared up


 Documentation/diff-options.txt | 14 +++---
 diff.c                         | 94 +++++++++++++++++++++++++++------------
 t/t4014-format-patch.sh        | 96 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 169 insertions(+), 35 deletions(-)

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 9f7cba2..36e4ee3 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -53,13 +53,15 @@ endif::git-format-patch[]
 	Generate a diff using the "patience diff" algorithm.
 
 --stat[=<width>[,<name-width>[,<count>]]]::
-	Generate a diffstat.  You can override the default
-	output width for 80-column terminal by `--stat=<width>`.
-	The width of the filename part can be controlled by
-	giving another width to it separated by a comma.
+	Generate a diffstat. By default, as much space as necessary
+	will be used for the filename part, and up to 40 columns for
+	the graph part. Maximum width defaults to terminal width,
+	or 80 columns if not connected to a terminal, and can be
+	overriden by `<width>`. The width of the filename part can be
+	limited by giving another width `<name-width>` after a comma.
 	By giving a third parameter `<count>`, you can limit the
-	output to the first `<count>` lines, followed by
-	`...` if there are more.
+	output to the first `<count>` lines, followed by `...` if
+	there are more.
 +
 These parameters can also be set individually with `--stat-width=<width>`,
 `--stat-name-width=<name-width>` and `--stat-count=<count>`.
diff --git a/diff.c b/diff.c
index 7e15426..4dc2b5c 100644
--- a/diff.c
+++ b/diff.c
@@ -1327,7 +1327,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	int i, len, add, del, adds = 0, dels = 0;
 	uintmax_t max_change = 0, max_len = 0;
 	int total_files = data->nr;
-	int width, name_width, count;
+	int width, name_width, graph_width, number_width, count;
 	const char *reset, *add_c, *del_c;
 	const char *line_prefix = "";
 	int extra_shown = 0;
@@ -1341,25 +1341,15 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		line_prefix = msg->buf;
 	}
 
-	width = options->stat_width ? options->stat_width : 80;
-	name_width = options->stat_name_width ? options->stat_name_width : 50;
 	count = options->stat_count ? options->stat_count : data->nr;
 
-	/* Sanity: give at least 5 columns to the graph,
-	 * but leave at least 10 columns for the name.
-	 */
-	if (width < 25)
-		width = 25;
-	if (name_width < 10)
-		name_width = 10;
-	else if (width < name_width + 15)
-		name_width = width - 15;
-
-	/* Find the longest filename and max number of changes */
 	reset = diff_get_color_opt(options, DIFF_RESET);
 	add_c = diff_get_color_opt(options, DIFF_FILE_NEW);
 	del_c = diff_get_color_opt(options, DIFF_FILE_OLD);
 
+	/*
+	 * Find the longest filename and max number of changes
+	 */
 	for (i = 0; (i < count) && (i < data->nr); i++) {
 		struct diffstat_file *file = data->files[i];
 		uintmax_t change = file->added + file->deleted;
@@ -1380,19 +1370,64 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	}
 	count = i; /* min(count, data->nr) */
 
-	/* Compute the width of the graph part;
-	 * 10 is for one blank at the beginning of the line plus
-	 * " | count " between the name and the graph.
+	/*
+	 * We have width = stat_width or term_columns() columns total.
+	 * We want a maximum of min(max_len, stat_name_width) for the name part.
+	 * We want a maximum of min(max_change, 40) for the +- part.
+	 * We also need 1 for " " and 4 + decimal_width(max_change)
+	 * for " | NNNN " and one the empty column at the end, altogether
+	 * 6 + decimal_width(max_change).
+	 *
+	 * If there's not enough space, we will use the smaller of
+	 * stat_name_width (if set) and 5/8*width for the filename,
+	 * and the rest for constant elements + histogram, but no more
+	 * than 40 for the histogram.
+	 * (5/8 gives 50 for filename and 30 for constant parts +
+	 * histogram for the standard terminal size).
 	 *
-	 * From here on, name_width is the width of the name area,
-	 * and width is the width of the graph area.
+	 * In other words: stat_width limits the maximum width, and
+	 * stat_name_width fixes the maximum width of the filename,
+	 * and is also used to divide available columns if there
+	 * aren't enough.
 	 */
-	name_width = (name_width < max_len) ? name_width : max_len;
-	if (width < (name_width + 10) + max_change)
-		width = width - (name_width + 10);
-	else
-		width = max_change;
 
+	width = options->stat_width ? options->stat_width : term_columns();
+	number_width = decimal_width(max_change);
+
+	/*
+	 * Guarantee 3/8*16==6 for the graph part
+	 * and 5/8*16==10 for the filename part
+	 */
+	if (width < 16 + 6 + number_width)
+		width = 16 + 6 + number_width;
+
+	/*
+	 * First assign sizes that are wanted, ignoring available width.
+	 */
+	graph_width = max_change < 40 ? max_change : 40;
+	name_width = (options->stat_name_width > 0 &&
+		      options->stat_name_width < max_len) ?
+		options->stat_name_width : max_len;
+
+	/*
+	 * Adjust adjustable widths not to exceed maximum width
+	 */
+	if (name_width + number_width + 6 + graph_width > width) {
+		if (graph_width > width * 3/8 - number_width - 6)
+			graph_width = width * 3/8 - number_width - 6;
+		if (graph_width > 40)
+			graph_width =  40;
+		if (name_width > width - number_width - 6 - graph_width)
+			name_width = width - number_width - 6 - graph_width;
+		else
+			graph_width = width - number_width - 6 - name_width;
+	}
+
+	/*
+	 * From here name_width is the width of the name area,
+	 * and graph_width is the width of the graph area.
+	 * max_change is used to scale graph properly.
+	 */
 	for (i = 0; i < count; i++) {
 		const char *prefix = "";
 		char *name = data->files[i]->print_name;
@@ -1448,14 +1483,15 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		adds += add;
 		dels += del;
 
-		if (width <= max_change) {
-			add = scale_linear(add, width, max_change);
-			del = scale_linear(del, width, max_change);
+		if (graph_width <= max_change) {
+			add = scale_linear(add, graph_width, max_change);
+			del = scale_linear(del, graph_width, max_change);
 		}
 		fprintf(options->file, "%s", line_prefix);
 		show_name(options->file, prefix, name, len);
-		fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,
-				added + deleted ? " " : "");
+		fprintf(options->file, " %*"PRIuMAX"%s",
+			number_width, added + deleted,
+			added + deleted ? " " : "");
 		show_graph(options->file, '+', add, add_c, reset);
 		show_graph(options->file, '-', del, del_c, reset);
 		fprintf(options->file, "\n");
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 6797512..a65ade4 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -894,4 +894,100 @@ test_expect_success 'format patch ignores color.ui' '
 	test_cmp expect actual
 '
 
+name=aaaaaaaaaa
+name=$name$name$name$name$name$name$name$name$name$name$name$name
+test_expect_success 'preparation' "
+	> ${name} &&
+	git add ${name} &&
+	git commit -m message &&
+	echo a > ${name} &&
+	git commit -m message ${name}
+"
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+test_expect_success 'format patch graph width is 80 columns' '
+	git format-patch --stat --stdout -1 |
+		grep -m 1 aaaaa > actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+test_expect_success 'format patch --stat=width with long name' '
+	git format-patch --stat=40 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-width=width works long name' '
+	git format-patch --stat-width=40 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat=...,name-width with long name' '
+	git format-patch --stat=60,32 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-name-width with long name' '
+	git format-patch --stat-name-width=32 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'preparation' '
+	> abcd &&
+	git add abcd &&
+	git commit -m message &&
+	seq 1000 > abcd &&
+	git commit -m message abcd
+'
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++
+EOF
+test_expect_success 'format patch graph width is 40 columns' '
+	git format-patch --stat --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch ignores COLUMNS' '
+	COLUMNS=200 git format-patch --stat --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++
+EOF
+test_expect_success 'format patch --stat=width with big change' '
+	git format-patch --stat=40 --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-width=width with big change' '
+	git format-patch --stat-width=40 --stdout -1 |
+		grep -m 1 abcd > actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
+EOF
+test_expect_success 'format patch --stat=width with big change and long name' '
+	cp abcd aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+	git add aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+	git commit -m message &&
+	git format-patch --stat-width=60 --stdout -1 |
+		grep -m 1 aaaa > actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.7.9.6.ga1838.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 2/3 v4] diff --stat: better alignment for binary files
  2012-02-14 23:45               ` [PATCH 1/3 v4] " Zbigniew Jędrzejewski-Szmek
@ 2012-02-14 23:45                 ` Zbigniew Jędrzejewski-Szmek
  2012-02-14 23:45                 ` [PATCH 3/3 v4] Update diff --stat output in tests and tutorial Zbigniew Jędrzejewski-Szmek
                                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-14 23:45 UTC (permalink / raw)
  To: git, gitster; +Cc: Michael J Gruber, pclouds, Zbigniew Jędrzejewski-Szmek

The output for binary and unmerged files was not updated in
'diff --stat': use the full terminal width'. This fixes this
omission and modifies the graph width logic to include enough
space for "Bin XXX -> YYY bytes".

If changes to binary files are mixed with changes to text files,
change counts are padded to take at least three columns. And the other
way around, if change counts require more than three columns, then
"Bin"s is padded to align with the change count. This way, the +- part
starts in the same column as "XXX -> YYY" part for binary files. This
makes the graph easier to parse visually thanks to the empty column.
This mimics the old layout of diff --stat.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
 diff.c                 | 39 ++++++++++++++++++++++++++++++++-------
 t/t4012-diff-binary.sh | 17 +++++++++++++++++
 2 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/diff.c b/diff.c
index 4dc2b5c..0732623 100644
--- a/diff.c
+++ b/diff.c
@@ -1326,8 +1326,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 {
 	int i, len, add, del, adds = 0, dels = 0;
 	uintmax_t max_change = 0, max_len = 0;
-	int total_files = data->nr;
-	int width, name_width, graph_width, number_width, count;
+	int total_files = data->nr, count;
+	int width, name_width, graph_width, number_width = 0, bin_width = 0;
 	const char *reset, *add_c, *del_c;
 	const char *line_prefix = "";
 	int extra_shown = 0;
@@ -1363,8 +1363,21 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		if (max_len < len)
 			max_len = len;
 
-		if (file->is_binary || file->is_unmerged)
+		if (file->is_unmerged) {
+			/* "Unmerged" is 8 characters */
+			bin_width = bin_width < 8 ? 8 : bin_width;
 			continue;
+		}
+		if (file->is_binary) {
+			/* "Bin XXX -> YYY bytes" */
+			int w = 14 + decimal_width(file->added)
+				+ decimal_width(file->deleted);
+			bin_width = bin_width < w ? w : bin_width;
+			/* Display change counts aligned with "Bin" */
+			number_width = 3;
+			continue;
+		}
+
 		if (max_change < change)
 			max_change = change;
 	}
@@ -1389,10 +1402,19 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	 * stat_name_width fixes the maximum width of the filename,
 	 * and is also used to divide available columns if there
 	 * aren't enough.
+	 *
+	 * Binary files are displayed with "Bin XXX -> YYY bytes"
+	 * instead of the change count and graph. This part is treated
+	 * similarly to the graph part, except that it is not
+	 * "scaled". If total width is too small to accomodate the
+	 * guaranteed minimum width of the filename part and the
+	 * separators and this message, this message will "overflow"
+	 * making the line longer than the maximum width.
 	 */
 
 	width = options->stat_width ? options->stat_width : term_columns();
-	number_width = decimal_width(max_change);
+	number_width = decimal_width(max_change) > number_width ?
+		decimal_width(max_change) : number_width;
 
 	/*
 	 * Guarantee 3/8*16==6 for the graph part
@@ -1403,8 +1425,11 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 
 	/*
 	 * First assign sizes that are wanted, ignoring available width.
+	 * (strlen("Bin XXX -> YYY bytes") is bin_width + 4)
 	 */
-	graph_width = max_change < 40 ? max_change : 40;
+	graph_width = max_change + 4 > bin_width ? max_change : bin_width - 4;
+	if (graph_width > 40)
+		graph_width = 40;
 	name_width = (options->stat_name_width > 0 &&
 		      options->stat_name_width < max_len) ?
 		options->stat_name_width : max_len;
@@ -1458,7 +1483,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		if (data->files[i]->is_binary) {
 			fprintf(options->file, "%s", line_prefix);
 			show_name(options->file, prefix, name, len);
-			fprintf(options->file, "  Bin ");
+			fprintf(options->file, " %*s ", number_width, "Bin");
 			fprintf(options->file, "%s%"PRIuMAX"%s",
 				del_c, deleted, reset);
 			fprintf(options->file, " -> ");
@@ -1471,7 +1496,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		else if (data->files[i]->is_unmerged) {
 			fprintf(options->file, "%s", line_prefix);
 			show_name(options->file, prefix, name, len);
-			fprintf(options->file, "  Unmerged\n");
+			fprintf(options->file, " Unmerged\n");
 			continue;
 		}
 
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index 2d9f9a0..ea0b376 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -90,4 +90,21 @@ test_expect_success 'diff --no-index with binary creation' '
 	test_cmp expected actual
 '
 
+cat >expect <<EOF
+ binfile  |   Bin 0 -> 1026 bytes
+ textfile | 10000 ++++++++++++++++++++++++++++++++++++++++
+EOF
+
+test_expect_success 'diff with binary files and big change count
+
+	Verify that "Bin" and the change count are properly aligned when
+	change count is big' '
+	echo X | dd of=binfile bs=1k seek=1 &&
+	git add binfile &&
+	seq 10000 > textfile &&
+	git add textfile &&
+	git diff --cached --stat binfile textfile | grep " | " > actual
+	test_cmp expect actual
+'
+
 test_done
-- 
1.7.9.6.ga1838.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 3/3 v4] Update diff --stat output in tests and tutorial
  2012-02-14 23:45               ` [PATCH 1/3 v4] " Zbigniew Jędrzejewski-Szmek
  2012-02-14 23:45                 ` [PATCH 2/3 v4] diff --stat: better alignment for binary files Zbigniew Jędrzejewski-Szmek
@ 2012-02-14 23:45                 ` Zbigniew Jędrzejewski-Szmek
  2012-02-15  1:21                   ` Junio C Hamano
  2012-02-15  0:07                 ` [PATCH 1/3 v4] diff --stat: use the full terminal width Junio C Hamano
                                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-14 23:45 UTC (permalink / raw)
  To: git, gitster; +Cc: Michael J Gruber, pclouds, Zbigniew Jędrzejewski-Szmek

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
All tests pass for me after this change.

git grep -l -E '^\s+[-a-z A-Z0-9/{}=>.]+ +\|  +[0-9]+ +[-+]+' t/ |
  grep -v apply |
  xargs sed -i -r 's/^(\s+[-a-zA-Z0-9/ {}=>.]+ +\| ) +([0-9]+ +[-+]+)/\1\2/; s/^(\s+[-a-zA-Z0-9/{}=>.]+ +\| ) +(Bin.*)/\1\2/'
+ manual fixes.

 Documentation/gitcore-tutorial.txt                 |  4 +-
 t/t0023-crlf-am.sh                                 |  2 +-
 t/t1200-tutorial.sh                                |  4 +-
 t/t3404-rebase-interactive.sh                      |  2 +-
 t/t3903-stash.sh                                   |  4 +-
 ...ff-tree_--cc_--patch-with-stat_--summary_master |  4 +-
 ...diff-tree_--cc_--patch-with-stat_--summary_side |  6 +-
 .../diff.diff-tree_--cc_--patch-with-stat_master   |  4 +-
 .../diff.diff-tree_--cc_--stat_--summary_master    |  4 +-
 t/t4013/diff.diff-tree_--cc_--stat_--summary_side  |  6 +-
 t/t4013/diff.diff-tree_--cc_--stat_master          |  4 +-
 ...pretty=oneline_--root_--patch-with-stat_initial |  6 +-
 .../diff.diff-tree_--pretty_--patch-with-stat_side |  6 +-
 ...-tree_--pretty_--root_--patch-with-stat_initial |  6 +-
 ...f-tree_--pretty_--root_--stat_--summary_initial |  6 +-
 .../diff.diff-tree_--pretty_--root_--stat_initial  |  6 +-
 ...diff.diff-tree_--root_--patch-with-stat_initial |  6 +-
 t/t4013/diff.diff-tree_-c_--stat_--summary_master  |  4 +-
 t/t4013/diff.diff-tree_-c_--stat_--summary_side    |  6 +-
 t/t4013/diff.diff-tree_-c_--stat_master            |  4 +-
 .../diff.diff_--patch-with-stat_-r_initial..side   |  6 +-
 t/t4013/diff.diff_--patch-with-stat_initial..side  |  6 +-
 t/t4013/diff.diff_--stat_initial..side             |  6 +-
 t/t4013/diff.diff_-r_--stat_initial..side          |  6 +-
 ..._--attach_--stdout_--suffix=.diff_initial..side |  6 +-
 ....format-patch_--attach_--stdout_initial..master | 16 +++---
 ...format-patch_--attach_--stdout_initial..master^ | 10 ++--
 ...ff.format-patch_--attach_--stdout_initial..side |  6 +-
 ...nline_--stdout_--numbered-files_initial..master | 16 +++---
 ...tdout_--subject-prefix=TESTCASE_initial..master | 16 +++---
 ....format-patch_--inline_--stdout_initial..master | 16 +++---
 ...format-patch_--inline_--stdout_initial..master^ | 10 ++--
 ...ormat-patch_--inline_--stdout_initial..master^^ |  6 +-
 ...ff.format-patch_--inline_--stdout_initial..side |  6 +-
 ...tch_--stdout_--cover-letter_-n_initial..master^ | 18 ++++----
 ...at-patch_--stdout_--no-numbered_initial..master | 16 +++---
 ...ormat-patch_--stdout_--numbered_initial..master | 16 +++---
 t/t4013/diff.format-patch_--stdout_initial..master | 16 +++---
 .../diff.format-patch_--stdout_initial..master^    | 10 ++--
 t/t4013/diff.format-patch_--stdout_initial..side   |  6 +-
 ....log_--patch-with-stat_--summary_master_--_dir_ |  6 +-
 t/t4013/diff.log_--patch-with-stat_master          | 16 +++---
 t/t4013/diff.log_--patch-with-stat_master_--_dir_  |  6 +-
 ..._--root_--cc_--patch-with-stat_--summary_master | 26 +++++-----
 ...f.log_--root_--patch-with-stat_--summary_master | 22 ++++----
 t/t4013/diff.log_--root_--patch-with-stat_master   | 22 ++++----
 ...og_--root_-c_--patch-with-stat_--summary_master | 26 +++++-----
 t/t4013/diff.show_--patch-with-stat_--summary_side |  6 +-
 t/t4013/diff.show_--patch-with-stat_side           |  6 +-
 t/t4013/diff.show_--stat_--summary_side            |  6 +-
 t/t4013/diff.show_--stat_side                      |  6 +-
 ...nged_--patch-with-stat_--summary_master_--_dir_ |  6 +-
 t/t4013/diff.whatchanged_--patch-with-stat_master  | 16 +++---
 ...ff.whatchanged_--patch-with-stat_master_--_dir_ |  6 +-
 ..._--root_--cc_--patch-with-stat_--summary_master | 26 +++++-----
 ...anged_--root_--patch-with-stat_--summary_master | 22 ++++----
 ...iff.whatchanged_--root_--patch-with-stat_master | 22 ++++----
 ...ed_--root_-c_--patch-with-stat_--summary_master | 26 +++++-----
 t/t4014-format-patch.sh                            |  2 +-
 t/t4016-diff-quote.sh                              | 14 +++---
 t/t4030-diff-textconv.sh                           |  2 +-
 t/t4043-diff-rename-binary.sh                      |  4 +-
 t/t4045-diff-relative.sh                           |  2 +-
 t/t4047-diff-dirstat.sh                            | 54 +++++++++++-----------
 t/t4049-diff-stat-count.sh                         |  4 +-
 t/t5100/patch0001                                  |  2 +-
 t/t5100/patch0002                                  |  2 +-
 t/t5100/patch0003                                  |  2 +-
 t/t5100/patch0005                                  |  4 +-
 t/t5100/patch0006                                  |  2 +-
 t/t5100/patch0010                                  |  2 +-
 t/t5100/patch0011                                  |  2 +-
 t/t5100/patch0014                                  |  2 +-
 t/t5100/patch0014--scissors                        |  2 +-
 t/t5100/sample.mbox                                | 18 ++++----
 t/t7602-merge-octopus-many.sh                      | 12 ++--
 76 files changed, 356 insertions(+), 356 deletions(-)

diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt
index c27d086..b781bbf 100644
--- a/Documentation/gitcore-tutorial.txt
+++ b/Documentation/gitcore-tutorial.txt
@@ -1002,8 +1002,8 @@ would be different)
 ----------------
 Updating from ae3a2da... to a80b4aa....
 Fast-forward (no commit created; -m option ignored)
- example |    1 +
- hello   |    1 +
+ example | 1 +
+ hello   | 1 +
  2 files changed, 2 insertions(+), 0 deletions(-)
 ----------------
 
diff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh
index aaed725..f9bbb91 100755
--- a/t/t0023-crlf-am.sh
+++ b/t/t0023-crlf-am.sh
@@ -11,7 +11,7 @@ Date: Thu, 23 Aug 2007 13:00:00 +0200
 Subject: test1
 
 ---
- foo |    1 +
+ foo | 1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
  create mode 100644 foo
 
diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh
index 5e29e13..77ff21c 100755
--- a/t/t1200-tutorial.sh
+++ b/t/t1200-tutorial.sh
@@ -154,8 +154,8 @@ test_expect_success 'git show-branch' '
 cat > resolve.expect << EOF
 Updating VARIABLE..VARIABLE
 FASTFORWARD (no commit created; -m option ignored)
- example |    1 +
- hello   |    1 +
+ example | 1 +
+ hello   | 1 +
  2 files changed, 2 insertions(+), 0 deletions(-)
 EOF
 
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index b981572..c8fe1a9 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -323,7 +323,7 @@ test_expect_success 'verbose flag is heeded, even after --continue' '
 	echo resolved > file1 &&
 	git add file1 &&
 	git rebase --continue > output &&
-	grep "^ file1 |    2 +-$" output
+	grep "^ file1 | 2 +-$" output
 '
 
 test_expect_success 'multi-squash only fires up editor once' '
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index dbe2ac1..fbf064e 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -443,7 +443,7 @@ test_expect_success 'stash show - stashes on stack, stash-like argument' '
 	STASH_ID=$(git stash create) &&
 	git reset --hard &&
 	cat >expected <<-EOF &&
-	 file |    1 +
+	 file | 1 +
 	 1 files changed, 1 insertions(+), 0 deletions(-)
 	EOF
 	git stash show ${STASH_ID} >actual &&
@@ -481,7 +481,7 @@ test_expect_success 'stash show - no stashes on stack, stash-like argument' '
 	STASH_ID=$(git stash create) &&
 	git reset --hard &&
 	cat >expected <<-EOF &&
-	 file |    1 +
+	 file | 1 +
 	 1 files changed, 1 insertions(+), 0 deletions(-)
 	EOF
 	git stash show ${STASH_ID} >actual &&
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
index 3a9f78a..b87f758 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
@@ -1,7 +1,7 @@
 $ git diff-tree --cc --patch-with-stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --cc dir/sub
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
index a61ad8c..47665f9 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
@@ -1,8 +1,8 @@
 $ git diff-tree --cc --patch-with-stat --summary side
 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
index 49f23b9..efe6dcc 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
@@ -1,7 +1,7 @@
 $ git diff-tree --cc --patch-with-stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --cc dir/sub
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
index cc6eb3b..1b465f0 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
@@ -1,6 +1,6 @@
 $ git diff-tree --cc --stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
index 50362be..44fcf4e 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
@@ -1,8 +1,8 @@
 $ git diff-tree --cc --stat --summary side
 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 $
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_master b/t/t4013/diff.diff-tree_--cc_--stat_master
index fae7f33..6dffb7f 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_master
@@ -1,6 +1,6 @@
 $ git diff-tree --cc --stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
index d5c333a..a7d91c9 100644
--- a/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
@@ -1,8 +1,8 @@
 $ git diff-tree --pretty=oneline --root --patch-with-stat initial
 444ac553ac7612cc88969031b02b3767fb8a353a Initial
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
index 4d30e7e..2061f37 100644
--- a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
+++ b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
index 7dfa6af..71d912e 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
index 43bfce2..b80dbcc 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
index 9154aa4..88cb5c9 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
@@ -5,8 +5,8 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
index 1562b62..748ba93 100644
--- a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
@@ -1,8 +1,8 @@
 $ git diff-tree --root --patch-with-stat initial
 444ac553ac7612cc88969031b02b3767fb8a353a
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_master b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
index ac9f641..700c386 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
@@ -1,6 +1,6 @@
 $ git diff-tree -c --stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_side b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
index 2afcca1..520aa4f 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
@@ -1,8 +1,8 @@
 $ git diff-tree -c --stat --summary side
 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 $
diff --git a/t/t4013/diff.diff-tree_-c_--stat_master b/t/t4013/diff.diff-tree_-c_--stat_master
index c2fe6a9..cdc7c40 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_master
@@ -1,6 +1,6 @@
 $ git diff-tree -c --stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
index 9ed317a..abf43a9 100644
--- a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
@@ -1,7 +1,7 @@
 $ git diff --patch-with-stat -r initial..side
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff_--patch-with-stat_initial..side b/t/t4013/diff.diff_--patch-with-stat_initial..side
index 8b50629..f88262e 100644
--- a/t/t4013/diff.diff_--patch-with-stat_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_initial..side
@@ -1,7 +1,7 @@
 $ git diff --patch-with-stat initial..side
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff_--stat_initial..side b/t/t4013/diff.diff_--stat_initial..side
index 0517b5d..17a07be 100644
--- a/t/t4013/diff.diff_--stat_initial..side
+++ b/t/t4013/diff.diff_--stat_initial..side
@@ -1,6 +1,6 @@
 $ git diff --stat initial..side
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff_-r_--stat_initial..side b/t/t4013/diff.diff_-r_--stat_initial..side
index 245220d..54507eb 100644
--- a/t/t4013/diff.diff_-r_--stat_initial..side
+++ b/t/t4013/diff.diff_-r_--stat_initial..side
@@ -1,6 +1,6 @@
 $ git diff -r --stat initial..side
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side b/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
index 52116d3..6996877 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
index ce49bd6..d56a1a3 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
index 5f1b238..b76e61f 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..side b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
index 4a2364a..769cf32 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
index 43b81eb..0ee7338 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
index ca3f60b..fbf3bd4 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
index 08f2301..d68e3ee 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
index 07f1230..668e38f 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
index 29e00ab..caec553 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..side b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
index 67633d4..6b84b1b 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
index 3b4e113..d8cba57 100644
--- a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
@@ -10,10 +10,10 @@ A U Thor (2):
   Second
   Third
 
- dir/sub |    4 ++++
- file0   |    3 +++
- file1   |    3 +++
- file2   |    3 ---
+ dir/sub | 4 ++++
+ file0   | 3 +++
+ file1   | 3 +++
+ file2   | 3 ---
  4 files changed, 10 insertions(+), 3 deletions(-)
  create mode 100644 file1
  delete mode 100644 file2
@@ -28,9 +28,9 @@ Subject: [DIFFERENT_PREFIX 1/2] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [DIFFERENT_PREFIX 2/2] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
diff --git a/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master b/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
index f7752eb..a2a4726 100644
--- a/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [PATCH] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
 Subject: [PATCH] Side
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
index 8e67dbf..602f4b0 100644
--- a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH 1/3] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [PATCH 2/3] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
 Subject: [PATCH 3/3] Side
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master b/t/t4013/diff.format-patch_--stdout_initial..master
index 7b89978..bcf739e 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH 1/3] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [PATCH 2/3] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
 Subject: [PATCH 3/3] Side
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master^ b/t/t4013/diff.format-patch_--stdout_initial..master^
index b7f9725..7d5ba0f 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_initial..master^
@@ -6,9 +6,9 @@ Subject: [PATCH 1/2] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [PATCH 2/2] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
diff --git a/t/t4013/diff.format-patch_--stdout_initial..side b/t/t4013/diff.format-patch_--stdout_initial..side
index e765088..9ed0ea2 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--stdout_initial..side
@@ -5,9 +5,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
 Subject: [PATCH] Side
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
index bd7f5c0..e2954d3 100644
--- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
@@ -12,7 +12,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -31,7 +31,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -53,7 +53,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master
index 14595a6..e417873 100644
--- a/t/t4013/diff.log_--patch-with-stat_master
+++ b/t/t4013/diff.log_--patch-with-stat_master
@@ -12,9 +12,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -54,8 +54,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -86,9 +86,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
index 5a4e727..cebec52 100644
--- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
@@ -12,7 +12,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -31,7 +31,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -53,7 +53,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
index df0aaa9..540633f 100644
--- a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
@@ -6,8 +6,8 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
     Merge branch 'side'
 
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --cc dir/sub
@@ -44,9 +44,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -87,8 +87,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -162,9 +162,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
index c11b5f2c..fb289d8 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
@@ -12,9 +12,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -55,8 +55,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -88,9 +88,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -130,9 +130,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master
index 5f0c98f..84f535d 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_master
@@ -12,9 +12,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -54,8 +54,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -86,9 +86,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -127,9 +127,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
index e62c368..3e89ace 100644
--- a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
@@ -6,8 +6,8 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
     Merge branch 'side'
 
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --combined dir/sub
@@ -44,9 +44,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -87,8 +87,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -162,9 +162,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.show_--patch-with-stat_--summary_side b/t/t4013/diff.show_--patch-with-stat_--summary_side
index 377f2b7..38c1841 100644
--- a/t/t4013/diff.show_--patch-with-stat_--summary_side
+++ b/t/t4013/diff.show_--patch-with-stat_--summary_side
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.show_--patch-with-stat_side b/t/t4013/diff.show_--patch-with-stat_side
index fb14c53..38f6be2 100644
--- a/t/t4013/diff.show_--patch-with-stat_side
+++ b/t/t4013/diff.show_--patch-with-stat_side
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.show_--stat_--summary_side b/t/t4013/diff.show_--stat_--summary_side
index 5bd5977..e6f30a4 100644
--- a/t/t4013/diff.show_--stat_--summary_side
+++ b/t/t4013/diff.show_--stat_--summary_side
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 $
diff --git a/t/t4013/diff.show_--stat_side b/t/t4013/diff.show_--stat_side
index 3b22327..58ee49a 100644
--- a/t/t4013/diff.show_--stat_side
+++ b/t/t4013/diff.show_--stat_side
@@ -5,8 +5,8 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
index 6a467cc..ee340b8 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
@@ -5,7 +5,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -24,7 +24,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -46,7 +46,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master b/t/t4013/diff.whatchanged_--patch-with-stat_master
index 1e1bbe1..4adeab7 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -47,8 +47,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -79,9 +79,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
index 13789f1..63a3043 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
@@ -5,7 +5,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -24,7 +24,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -46,7 +46,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
index e96ff1f..60f3788 100644
--- a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
@@ -6,8 +6,8 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
     Merge branch 'side'
 
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --cc dir/sub
@@ -44,9 +44,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -87,8 +87,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -162,9 +162,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
index 0291153..9b7f63f 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -48,8 +48,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -81,9 +81,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -123,9 +123,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
index 9b0349c..cba8f3c 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -47,8 +47,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -79,9 +79,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
index c0aff68..8e24293 100644
--- a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
@@ -6,8 +6,8 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
     Merge branch 'side'
 
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --combined dir/sub
@@ -44,9 +44,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -87,8 +87,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -162,9 +162,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index a65ade4..91be989 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -519,7 +519,7 @@ test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 
 cat > expect << EOF
 ---
- file |   16 ++++++++++++++++
+ file | 16 ++++++++++++++++
  1 files changed, 16 insertions(+), 0 deletions(-)
 
 diff --git a/file b/file
diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh
index ab0c2f0..e451f2a 100755
--- a/t/t4016-diff-quote.sh
+++ b/t/t4016-diff-quote.sh
@@ -59,13 +59,13 @@ test_expect_success TABS_IN_FILENAMES 'git diff --summary -M HEAD' '
 
 test_expect_success TABS_IN_FILENAMES 'setup expected files' '
 cat >expect <<\EOF
- pathname.1 => "Rpathname\twith HT.0"            |    0
- pathname.3 => "Rpathname\nwith LF.0"            |    0
- "pathname\twith HT.3" => "Rpathname\nwith LF.1" |    0
- pathname.2 => Rpathname with SP.0               |    0
- "pathname\twith HT.2" => Rpathname with SP.1    |    0
- pathname.0 => Rpathname.0                       |    0
- "pathname\twith HT.0" => Rpathname.1            |    0
+ pathname.1 => "Rpathname\twith HT.0"            | 0
+ pathname.3 => "Rpathname\nwith LF.0"            | 0
+ "pathname\twith HT.3" => "Rpathname\nwith LF.1" | 0
+ pathname.2 => Rpathname with SP.0               | 0
+ "pathname\twith HT.2" => Rpathname with SP.1    | 0
+ pathname.0 => Rpathname.0                       | 0
+ "pathname\twith HT.0" => Rpathname.1            | 0
  7 files changed, 0 insertions(+), 0 deletions(-)
 EOF
 '
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index 88c5619..6a6344c 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -85,7 +85,7 @@ test_expect_success 'status -v produces text' '
 '
 
 cat >expect.stat <<'EOF'
- file |  Bin 2 -> 4 bytes
+ file | Bin 2 -> 4 bytes
  1 files changed, 0 insertions(+), 0 deletions(-)
 EOF
 test_expect_success 'diffstat does not run textconv' '
diff --git a/t/t4043-diff-rename-binary.sh b/t/t4043-diff-rename-binary.sh
index 0601281..ad0b2da 100755
--- a/t/t4043-diff-rename-binary.sh
+++ b/t/t4043-diff-rename-binary.sh
@@ -23,8 +23,8 @@ test_expect_success 'move the files into a "sub" directory' '
 '
 
 cat > expected <<\EOF
- bar => sub/bar |  Bin 5 -> 5 bytes
- foo => sub/foo |    0
+ bar => sub/bar | Bin 5 -> 5 bytes
+ foo => sub/foo |   0
  2 files changed, 0 insertions(+), 0 deletions(-)
 
 diff --git a/bar b/sub/bar
diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh
index 8a3c63b..336df82 100755
--- a/t/t4045-diff-relative.sh
+++ b/t/t4045-diff-relative.sh
@@ -32,7 +32,7 @@ test_expect_success "-p $*" "
 check_stat() {
 expect=$1; shift
 cat >expected <<EOF
- $expect |    1 +
+ $expect | 1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
 EOF
 test_expect_success "--stat $*" "
diff --git a/t/t4047-diff-dirstat.sh b/t/t4047-diff-dirstat.sh
index 29e80a5..75eaf16 100755
--- a/t/t4047-diff-dirstat.sh
+++ b/t/t4047-diff-dirstat.sh
@@ -252,41 +252,41 @@ EOF
 '
 
 cat <<EOF >expect_diff_stat
- changed/text             |    2 +-
- dst/copy/changed/text    |   10 ++++++++++
- dst/copy/rearranged/text |   10 ++++++++++
- dst/copy/unchanged/text  |   10 ++++++++++
- dst/move/changed/text    |   10 ++++++++++
- dst/move/rearranged/text |   10 ++++++++++
- dst/move/unchanged/text  |   10 ++++++++++
- rearranged/text          |    2 +-
- src/move/changed/text    |   10 ----------
- src/move/rearranged/text |   10 ----------
- src/move/unchanged/text  |   10 ----------
+ changed/text             |  2 +-
+ dst/copy/changed/text    | 10 ++++++++++
+ dst/copy/rearranged/text | 10 ++++++++++
+ dst/copy/unchanged/text  | 10 ++++++++++
+ dst/move/changed/text    | 10 ++++++++++
+ dst/move/rearranged/text | 10 ++++++++++
+ dst/move/unchanged/text  | 10 ++++++++++
+ rearranged/text          |  2 +-
+ src/move/changed/text    | 10 ----------
+ src/move/rearranged/text | 10 ----------
+ src/move/unchanged/text  | 10 ----------
  11 files changed, 62 insertions(+), 32 deletions(-)
 EOF
 
 cat <<EOF >expect_diff_stat_M
- changed/text                      |    2 +-
- dst/copy/changed/text             |   10 ++++++++++
- dst/copy/rearranged/text          |   10 ++++++++++
- dst/copy/unchanged/text           |   10 ++++++++++
- {src => dst}/move/changed/text    |    2 +-
- {src => dst}/move/rearranged/text |    2 +-
- {src => dst}/move/unchanged/text  |    0
- rearranged/text                   |    2 +-
+ changed/text                      |  2 +-
+ dst/copy/changed/text             | 10 ++++++++++
+ dst/copy/rearranged/text          | 10 ++++++++++
+ dst/copy/unchanged/text           | 10 ++++++++++
+ {src => dst}/move/changed/text    |  2 +-
+ {src => dst}/move/rearranged/text |  2 +-
+ {src => dst}/move/unchanged/text  |  0
+ rearranged/text                   |  2 +-
  8 files changed, 34 insertions(+), 4 deletions(-)
 EOF
 
 cat <<EOF >expect_diff_stat_CC
- changed/text                      |    2 +-
- {src => dst}/copy/changed/text    |    2 +-
- {src => dst}/copy/rearranged/text |    2 +-
- {src => dst}/copy/unchanged/text  |    0
- {src => dst}/move/changed/text    |    2 +-
- {src => dst}/move/rearranged/text |    2 +-
- {src => dst}/move/unchanged/text  |    0
- rearranged/text                   |    2 +-
+ changed/text                      | 2 +-
+ {src => dst}/copy/changed/text    | 2 +-
+ {src => dst}/copy/rearranged/text | 2 +-
+ {src => dst}/copy/unchanged/text  | 0
+ {src => dst}/move/changed/text    | 2 +-
+ {src => dst}/move/rearranged/text | 2 +-
+ {src => dst}/move/unchanged/text  | 0
+ rearranged/text                   | 2 +-
  8 files changed, 6 insertions(+), 6 deletions(-)
 EOF
 
diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh
index 641e70d..5edac4e 100755
--- a/t/t4049-diff-stat-count.sh
+++ b/t/t4049-diff-stat-count.sh
@@ -14,8 +14,8 @@ test_expect_success setup '
 	echo a >a &&
 	echo b >b &&
 	cat >expect <<-\EOF
-	 a |    1 +
-	 b |    1 +
+	 a | 1 +
+	 b | 1 +
 	 2 files changed, 2 insertions(+), 0 deletions(-)
 	EOF
 	git diff --stat --stat-count=2 >actual &&
diff --git a/t/t5100/patch0001 b/t/t5100/patch0001
index 8ce1551..02c9774 100644
--- a/t/t5100/patch0001
+++ b/t/t5100/patch0001
@@ -1,5 +1,5 @@
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
diff --git a/t/t5100/patch0002 b/t/t5100/patch0002
index 8ce1551..02c9774 100644
--- a/t/t5100/patch0002
+++ b/t/t5100/patch0002
@@ -1,5 +1,5 @@
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
diff --git a/t/t5100/patch0003 b/t/t5100/patch0003
index 8ce1551..02c9774 100644
--- a/t/t5100/patch0003
+++ b/t/t5100/patch0003
@@ -1,5 +1,5 @@
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
diff --git a/t/t5100/patch0005 b/t/t5100/patch0005
index 7d24b24..ab7a383 100644
--- a/t/t5100/patch0005
+++ b/t/t5100/patch0005
@@ -1,7 +1,7 @@
 ---
 
- Documentation/git-cvsimport-script.txt |    9 ++++++++-
- git-cvsimport-script                   |    4 ++--
+ Documentation/git-cvsimport-script.txt | 9 ++++++++-
+ git-cvsimport-script                   | 4 ++--
  2 files changed, 10 insertions(+), 3 deletions(-)
 
 50452f9c0c2df1f04d83a26266ba704b13861632
diff --git a/t/t5100/patch0006 b/t/t5100/patch0006
index 8ce1551..02c9774 100644
--- a/t/t5100/patch0006
+++ b/t/t5100/patch0006
@@ -1,5 +1,5 @@
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
diff --git a/t/t5100/patch0010 b/t/t5100/patch0010
index f055481..436821c 100644
--- a/t/t5100/patch0010
+++ b/t/t5100/patch0010
@@ -1,5 +1,5 @@
 ---
- builtin-mailinfo.c |    2 +-
+ builtin-mailinfo.c | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/patch0011 b/t/t5100/patch0011
index 8841d3c..0988713 100644
--- a/t/t5100/patch0011
+++ b/t/t5100/patch0011
@@ -1,5 +1,5 @@
 ---
- builtin-mailinfo.c  |    4 ++--
+ builtin-mailinfo.c  | 4 ++--
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
 index 3e5fe51..aabfe5c 100644
diff --git a/t/t5100/patch0014 b/t/t5100/patch0014
index 124efd2..3f3825f 100644
--- a/t/t5100/patch0014
+++ b/t/t5100/patch0014
@@ -1,5 +1,5 @@
 ---
- builtin-mailinfo.c |   37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
  1 files changed, 36 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/patch0014--scissors b/t/t5100/patch0014--scissors
index 124efd2..3f3825f 100644
--- a/t/t5100/patch0014--scissors
+++ b/t/t5100/patch0014--scissors
@@ -1,5 +1,5 @@
 ---
- builtin-mailinfo.c |   37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
  1 files changed, 36 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/sample.mbox b/t/t5100/sample.mbox
index de10312..34a09a0 100644
--- a/t/t5100/sample.mbox
+++ b/t/t5100/sample.mbox
@@ -12,7 +12,7 @@ Subject: [PATCH] a commit.
 Here is a patch from A U Thor.
 
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
@@ -52,7 +52,7 @@ two truly blank and another full of spaces in between.
 Hope this helps.
 
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
@@ -83,7 +83,7 @@ Message-Id: <nitpicker.12121212@example.net>
 Hopefully this would fix the problem stated there.
 
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
@@ -249,8 +249,8 @@ actual flags.
 Signed-off-by: David K=E5gedal <davidk@lysator.liu.se>
 ---
 
- Documentation/git-cvsimport-script.txt |    9 ++++++++-
- git-cvsimport-script                   |    4 ++--
+ Documentation/git-cvsimport-script.txt | 9 ++++++++-
+ git-cvsimport-script                   | 4 ++--
  2 files changed, 10 insertions(+), 3 deletions(-)
 
 50452f9c0c2df1f04d83a26266ba704b13861632
@@ -379,7 +379,7 @@ Subject: [PATCH] a commit.
 Here is a patch from A U Thor.
 
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
@@ -449,7 +449,7 @@ memcmp("Subject: ", header[i], 7) will never match.
 Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
 Signed-off-by: Junio C Hamano <gitster@pobox.com>
 ---
- builtin-mailinfo.c |    2 +-
+ builtin-mailinfo.c | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
@@ -482,7 +482,7 @@ Content-Transfer-Encoding: quoted-printable
 Here comes a commit log message, and
 its second line is here.
 ---
- builtin-mailinfo.c  |    4 ++--
+ builtin-mailinfo.c  | 4 ++--
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
 index 3e5fe51..aabfe5c 100644
@@ -587,7 +587,7 @@ everything before it in the message body.
 
 Signed-off-by: Junio C Hamano <gitster@pobox.com>
 ---
- builtin-mailinfo.c |   37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
  1 files changed, 36 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh
index 61f36ba..5a86e24 100755
--- a/t/t7602-merge-octopus-many.sh
+++ b/t/t7602-merge-octopus-many.sh
@@ -54,9 +54,9 @@ Trying simple merge with c2
 Trying simple merge with c3
 Trying simple merge with c4
 Merge made by the 'octopus' strategy.
- c2.c |    1 +
- c3.c |    1 +
- c4.c |    1 +
+ c2.c | 1 +
+ c3.c | 1 +
+ c4.c | 1 +
  3 files changed, 3 insertions(+), 0 deletions(-)
  create mode 100644 c2.c
  create mode 100644 c3.c
@@ -73,7 +73,7 @@ cat >expected <<\EOF
 Already up-to-date with c4
 Trying simple merge with c5
 Merge made by the 'octopus' strategy.
- c5.c |    1 +
+ c5.c | 1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
  create mode 100644 c5.c
 EOF
@@ -87,8 +87,8 @@ cat >expected <<\EOF
 Fast-forwarding to: c1
 Trying simple merge with c2
 Merge made by the 'octopus' strategy.
- c1.c |    1 +
- c2.c |    1 +
+ c1.c | 1 +
+ c2.c | 1 +
  2 files changed, 2 insertions(+), 0 deletions(-)
  create mode 100644 c1.c
  create mode 100644 c2.c
-- 
1.7.9.6.ga1838.dirty

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/3 v4] diff --stat: use the full terminal width
  2012-02-14 23:45               ` [PATCH 1/3 v4] " Zbigniew Jędrzejewski-Szmek
  2012-02-14 23:45                 ` [PATCH 2/3 v4] diff --stat: better alignment for binary files Zbigniew Jędrzejewski-Szmek
  2012-02-14 23:45                 ` [PATCH 3/3 v4] Update diff --stat output in tests and tutorial Zbigniew Jędrzejewski-Szmek
@ 2012-02-15  0:07                 ` Junio C Hamano
  2012-02-15  1:18                 ` Junio C Hamano
  2012-02-15  7:39                 ` Johannes Sixt
  4 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-15  0:07 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, Michael J Gruber, pclouds

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> I've added 'v4' to the other two patches in this series like to this
> one, despite them beeing new. I hope that this is proper form.

Yeah, we usually say [PATCH v4 1/3] to mean that this is the fourth
incarnation of the whole series (it is an instruction to reviewers to
discard anything labeled without v$N and $N smaller than 4, and read only
the ones marked with "v4") and it often happens that the earlier round did
not have three patches, so that is perfectly fine.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/3 v4] diff --stat: use the full terminal width
  2012-02-14 23:45               ` [PATCH 1/3 v4] " Zbigniew Jędrzejewski-Szmek
                                   ` (2 preceding siblings ...)
  2012-02-15  0:07                 ` [PATCH 1/3 v4] diff --stat: use the full terminal width Junio C Hamano
@ 2012-02-15  1:18                 ` Junio C Hamano
  2012-02-15  7:39                 ` Johannes Sixt
  4 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-15  1:18 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, Michael J Gruber, pclouds

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> - comments are updated and the word "histogram" is banished

Heh, I still see at least three instances of them in this patch.

> - use decimal_width(max_change) to calculate number of columns

Please see comments for 3/3 I'll send separately.

> diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
> index 6797512..a65ade4 100755
> --- a/t/t4014-format-patch.sh
> +++ b/t/t4014-format-patch.sh
> @@ -894,4 +894,100 @@ test_expect_success 'format patch ignores color.ui' '
>  	test_cmp expect actual
>  '
>  
> +name=aaaaaaaaaa
> +name=$name$name$name$name$name$name$name$name$name$name$name$name

How long is this name?  120 columns?  I think that should be fine for any
filesystem we care about.

> +test_expect_success 'preparation' "
> +	> ${name} &&
> +	git add ${name} &&
> +	git commit -m message &&
> +	echo a > ${name} &&
> +	git commit -m message ${name}
> +"

Please write these (exactly -- paying close attention to SP) like this:

	>"$name" &&
	git add "$name" &&
        git commit -m message &&
        echo a >"$name" &&
        git commit -m message "$name"

Points to note:

 - Even though you (and the reader) may know that "$name" does not contain
   word-breaking spaces, writing double-quotes around it reduces the
   mental burden from the readers;

 - Strictly speaking, the target of I/O redirection (e.g. >"$name") does
   not have to have quotes around it, but some versions of bash are known
   to give misguided warnings against it;

 - We do not write SP between the redirection and filename, but we do have
   one SP before the redirection; and

 - Unless you want to express concatenation with string that can appear
   later in words (e.g. "${name}1"), avoid ${name} to lessen the mental
   burden to readers, as "${" often signals there is some magic coming
   (e.g. "${name#strip}").

> +cat >expect <<'EOF'
> + ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
> +EOF
> +test_expect_success 'format patch graph width is 80 columns' '

Please make sure this test (and all the other new tests) pass with or
without your the patch that updates diff.c, as we need to ensure that
COLUMNS=80 or vanilla format-patch produces result that is identical to
the old output without regression (again, see comments to [PATCH 3/3]).

> +	git format-patch --stat --stdout -1 |
> +		grep -m 1 aaaaa > actual &&

Do not use "grep -m $count"; it is not portable.

Literal translation of the above would be:

	sed -n -e "/aaaaa/{
        	p
                q
	}"

but you can perhaps rely on the fact that there is only one path and '|'
does not ppear in the payload or log message, and use this instead:

	grep "|" >actual

Also to catch errors in format-patch that unexpectedly dies (after all,
you are touching diff machinery with your patch), avoid using pipes, and
write it perhaps like this:

	git format-patch --stat --stdout -1 >output &&
        grep "|" >actual &&

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 3/3 v4] Update diff --stat output in tests and tutorial
  2012-02-14 23:45                 ` [PATCH 3/3 v4] Update diff --stat output in tests and tutorial Zbigniew Jędrzejewski-Szmek
@ 2012-02-15  1:21                   ` Junio C Hamano
  2012-02-15 11:03                     ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts Zbigniew Jędrzejewski-Szmek
  0 siblings, 1 reply; 46+ messages in thread
From: Junio C Hamano @ 2012-02-15  1:21 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, Michael J Gruber, pclouds

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
> ---
> All tests pass for me after this change.

Err, this is not what I meant when I said "split that part to a different
patch".

If you didn't have this bit in [PATCH 1/3]

        -               fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,
        -                               added + deleted ? " " : "");
        +               fprintf(options->file, " %*"PRIuMAX"%s",
        +                       number_width, added + deleted,

then I think most of the changes in [PATCH 3/3] is unnecessary when using
the default 80-column output, which is how the test is run.

In other words, ideally, the [PATCH 1/3] should improve the diffstat
generation code in such a way that it produces output that is identical to
the existing test vectors when COLUMNS is set to 80 but takes advantage of
wider terminal when available.  So either the above change should not be
part of [PATCH 1/3] at all, or you still chnage this fprintf(), but use
number_width that is hardcoded to 4 instead of using the value computed
with decimal_width(max_change).  As to the test part, when a wider COLUMNS
is given, the code would obviously take advantage of it, so it may:

 - contain a change to the test suite somewhere, probably t/test-lib.sh,
   to set COLUMNS=80 and export it, to make sure that the existing test
   won't be broken when the number of columns learned from ioctl(1) is
   different from 80; and

 - add a new test that explicitly sets wider COLUMNS and makes sure you
   get a wider diffstat graph.

and almost no other changes to the expected output.

If you do not arrange [PATCH 1/3] that way, we cannot verify that it does
not introduce any regression to existing users.  Just applying [1/3] would
start failing tests, and we cannot tell which failure is a false alarm due
to this change, and which ones is a real regression that you are producing
wrong output when COLUMNS is set to 80.

And then as a separate patch [PATCH 3/3] at the very end of the series,
you would either introduce the above change to fprintf(), or if you
changed fprintf() in [PATCH 1/3] but used hardcoded number_width, then
change it to use decimal_width().

That change in turn makes the bulk of this patch to update the expected
output necessary.

If your series is organized that way, we can weigh pros-and-cons of the
change to use decimal_width() a lot more easily.

Thanks.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/3 v4] diff --stat: use the full terminal width
  2012-02-14 23:45               ` [PATCH 1/3 v4] " Zbigniew Jędrzejewski-Szmek
                                   ` (3 preceding siblings ...)
  2012-02-15  1:18                 ` Junio C Hamano
@ 2012-02-15  7:39                 ` Johannes Sixt
  4 siblings, 0 replies; 46+ messages in thread
From: Johannes Sixt @ 2012-02-15  7:39 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber, pclouds

Am 2/15/2012 0:45, schrieb Zbigniew Jędrzejewski-Szmek:
> +test_expect_success 'preparation' '
> +	> abcd &&
> +	git add abcd &&
> +	git commit -m message &&
> +	seq 1000 > abcd &&
> +	git commit -m message abcd

Please don't use seq (here and in some more places in this series); we
don't have it on Windows. You can write it explicitly:

	i=0 &&
	while test $i -lt 1000
	do
		i=$(($i + 1))
		echo $i &&
	done >abcd &&
	...

-- Hannes

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts
  2012-02-15  1:21                   ` Junio C Hamano
@ 2012-02-15 11:03                     ` Zbigniew Jędrzejewski-Szmek
  2012-02-15 11:03                       ` [PATCH 2/3 v5] diff --stat: use the full terminal width Zbigniew Jędrzejewski-Szmek
                                         ` (2 more replies)
  0 siblings, 3 replies; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-15 11:03 UTC (permalink / raw)
  To: git, gitster; +Cc: Michael J Gruber, pclouds, Zbigniew Jędrzejewski-Szmek

Eleven tests for various combinations of a long filename and/or big
change count and ways to specify widths for diff --stat.
---
Tests added in previous version of 'diff --stat: use full terminal width'
are extracted into a separate patch. The tests are usefull independently
of that patch anyway.

changes to tests since v4:
- seq is replaced with a while loop for windows compatibility
- grep -m 1 is replaced with grep " | "
- redirects are made portable
- piped output is split into two commands to verify that the first command
  sucessfully runs to completion

 t/t4014-format-patch.sh | 101 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 6797512..f6ebb51 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -894,4 +894,105 @@ test_expect_success 'format patch ignores color.ui' '
 	test_cmp expect actual
 '
 
+# 120 character name
+name=aaaaaaaaaa
+name=$name$name$name$name$name$name$name$name$name$name$name$name
+test_expect_success 'preparation' "
+	>\"$name\" &&
+	git add \"$name\" &&
+	git commit -m message &&
+	echo a >\"$name\" &&
+	git commit -m message \"$name\"
+"
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
+EOF
+test_expect_success 'format patch graph width defaults to 80 columns' '
+	git format-patch --stat --stdout -1 >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
+EOF
+test_expect_success 'format patch --stat=width with long name' '
+	git format-patch --stat=40 --stdout -1 >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-width=width works with long name' '
+	git format-patch --stat-width=40 --stdout -1 >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat=...,name-width with long name' '
+	git format-patch --stat=60,29 --stdout -1 >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-name-width with long name' '
+	git format-patch --stat-name-width=29 --stdout -1 >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'preparation' '
+	>abcd &&
+	git add abcd &&
+	git commit -m message &&
+	i=0 &&
+	while test $i -lt 1000; do
+		echo $i &&
+		i=$(($i + 1))
+	done >abcd &&
+	git commit -m message abcd
+'
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++
+EOF
+test_expect_success 'format patch graph part width is 40 columns' '
+	git format-patch --stat --stdout -1 >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch ignores COLUMNS' '
+	COLUMNS=200 git format-patch --stat --stdout -1 >output
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++
+EOF
+test_expect_success 'format patch --stat=width with big change' '
+	git format-patch --stat=40 --stdout -1 >output
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'format patch --stat-width=width with big change' '
+	git format-patch --stat-width=40 --stdout -1 >output
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
+EOF
+test_expect_success 'format patch --stat=width with big change and long name' '
+	cp abcd aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+	git add aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
+	git commit -m message &&
+	git format-patch --stat-width=60 --stdout -1 >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.7.9.5.g91d5

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 2/3 v5] diff --stat: use the full terminal width
  2012-02-15 11:03                     ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts Zbigniew Jędrzejewski-Szmek
@ 2012-02-15 11:03                       ` Zbigniew Jędrzejewski-Szmek
  2012-02-15 18:07                         ` Junio C Hamano
  2012-02-15 11:03                       ` [PATCH 3/3 v5] diff --stat: use less columns for change counts Zbigniew Jędrzejewski-Szmek
  2012-02-15 17:12                       ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big " Junio C Hamano
  2 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-15 11:03 UTC (permalink / raw)
  To: git, gitster; +Cc: Michael J Gruber, pclouds, Zbigniew Jędrzejewski-Szmek

Use as many columns as necessary for the filenames and up to 40
columns for the graph.

Some projects (especially in Java), have long filename paths, with
nested directories or long individual filenames. When files are
renamed, the filename part in stat output can be almost useless. If
the middle part between { and } is long (because the file was moved to
a completely different directory), then most of the path would be
truncated.

It makes sense to detect and use the full terminal width and display
full filenames if possible.

If commits changing a lot of lines are displayed in a wide terminal
window (200 or more columns), and the +- graph would use the full
width, the output would look bad. Messages wrapped to about 80 columns
would be interspersed with very long +- lines. It makes sense to limit
the width of the graph part to a fixed value, even if more columns are
available. This fixed value is subjectively hard-coded to be 40
columns, which seems to work well for git.git and linux-2.6.git and
some other repositories.

If there isn't enough columns to print both the filename and the
graph, at least 5/8 of available space is devoted to filenames. On a
standard 80 column terminal, or if not connected to a terminal and
using the default of 80 columns, this gives the same partition as
before.

The --stat output in tests is not affected.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
This is the main patch. Presented with the two options (either
hardcode number_width=4 or remove fprintf(options->file, "
%*"PRIuMAX"%s", number_width, ...)), I've taken the middle way:
number_width=4 is hardcoded, but the fprintf is reverted to the previous
version. I think that this way the code is most readable, independently
if later changes.

Junio suggested to:
 - contain a change to the test suite somewhere, probably t/test-lib.sh,
   to set COLUMNS=80 and export it, to make sure that the existing test
   won't be broken when the number of columns learned from ioctl(1) is
   different from 80; and

 - add a new test that explicitly sets wider COLUMNS and makes sure you
   get a wider diffstat graph.

I haven't done this, because $COLUMNS and the actual terminal width is always
ignored in tests. There's even a test to verify that COLUMNS=200 doesn't
mess up git format-patch output.

A test to check that diff --stat responds to terminal size would be
nice, but I don't know how to force git-diff to use the real terminal
size in tests.

v5:
- tests are moved to an earlier patch
- using decimal_width(change count) is moved to a later patch
- "histogram" is really not used

v4:
- comments are updated and the word "histogram" is banished
- "mopping up" is removed (but the minimum width are guaranteed)

v3:
- use decimal_width(max_change) to calculate number of columns
  required for change counts
- rework the logic to divide columns
- document the logic in comments, update docs
- add more tests

v2:
- style fixes
- some tests for git-format-patch added
- patches 3 and 4 squashed together, since they touch the same lines
- graph width is limited to 40 columns, even if there's more space
- patch descriptions extended and cleared up


 Documentation/diff-options.txt | 14 ++++---
 diff.c                         | 88 +++++++++++++++++++++++++++------------
 2 files changed, 69 insertions(+), 33 deletions(-)

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 9f7cba2..36e4ee3 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -53,13 +53,15 @@ endif::git-format-patch[]
 	Generate a diff using the "patience diff" algorithm.
 
 --stat[=<width>[,<name-width>[,<count>]]]::
-	Generate a diffstat.  You can override the default
-	output width for 80-column terminal by `--stat=<width>`.
-	The width of the filename part can be controlled by
-	giving another width to it separated by a comma.
+	Generate a diffstat. By default, as much space as necessary
+	will be used for the filename part, and up to 40 columns for
+	the graph part. Maximum width defaults to terminal width,
+	or 80 columns if not connected to a terminal, and can be
+	overriden by `<width>`. The width of the filename part can be
+	limited by giving another width `<name-width>` after a comma.
 	By giving a third parameter `<count>`, you can limit the
-	output to the first `<count>` lines, followed by
-	`...` if there are more.
+	output to the first `<count>` lines, followed by `...` if
+	there are more.
 +
 These parameters can also be set individually with `--stat-width=<width>`,
 `--stat-name-width=<name-width>` and `--stat-count=<count>`.
diff --git a/diff.c b/diff.c
index 7e15426..be6d40b 100644
--- a/diff.c
+++ b/diff.c
@@ -1327,7 +1327,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	int i, len, add, del, adds = 0, dels = 0;
 	uintmax_t max_change = 0, max_len = 0;
 	int total_files = data->nr;
-	int width, name_width, count;
+	int width, name_width, graph_width, number_width = 4, count;
 	const char *reset, *add_c, *del_c;
 	const char *line_prefix = "";
 	int extra_shown = 0;
@@ -1341,25 +1341,15 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		line_prefix = msg->buf;
 	}
 
-	width = options->stat_width ? options->stat_width : 80;
-	name_width = options->stat_name_width ? options->stat_name_width : 50;
 	count = options->stat_count ? options->stat_count : data->nr;
 
-	/* Sanity: give at least 5 columns to the graph,
-	 * but leave at least 10 columns for the name.
-	 */
-	if (width < 25)
-		width = 25;
-	if (name_width < 10)
-		name_width = 10;
-	else if (width < name_width + 15)
-		name_width = width - 15;
-
-	/* Find the longest filename and max number of changes */
 	reset = diff_get_color_opt(options, DIFF_RESET);
 	add_c = diff_get_color_opt(options, DIFF_FILE_NEW);
 	del_c = diff_get_color_opt(options, DIFF_FILE_OLD);
 
+	/*
+	 * Find the longest filename and max number of changes
+	 */
 	for (i = 0; (i < count) && (i < data->nr); i++) {
 		struct diffstat_file *file = data->files[i];
 		uintmax_t change = file->added + file->deleted;
@@ -1380,19 +1370,63 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	}
 	count = i; /* min(count, data->nr) */
 
-	/* Compute the width of the graph part;
-	 * 10 is for one blank at the beginning of the line plus
-	 * " | count " between the name and the graph.
+	/*
+	 * We have width = stat_width or term_columns() columns total.
+	 * We want a maximum of min(max_len, stat_name_width) for the name part.
+	 * We want a maximum of min(max_change, 40) for the +- part.
+	 * We also need 1 for " " and 4 + decimal_width(max_change)
+	 * for " | NNNN " and one the empty column at the end, altogether
+	 * 6 + decimal_width(max_change).
+	 *
+	 * If there's not enough space, we will use the smaller of
+	 * stat_name_width (if set) and 5/8*width for the filename,
+	 * and the rest for constant elements + graph part, but no more
+	 * than 40 for the graph part.
+	 * (5/8 gives 50 for filename and 30 for the constant parts + graph
+	 * for the standard terminal size).
 	 *
-	 * From here on, name_width is the width of the name area,
-	 * and width is the width of the graph area.
+	 * In other words: stat_width limits the maximum width, and
+	 * stat_name_width fixes the maximum width of the filename,
+	 * and is also used to divide available columns if there
+	 * aren't enough.
 	 */
-	name_width = (name_width < max_len) ? name_width : max_len;
-	if (width < (name_width + 10) + max_change)
-		width = width - (name_width + 10);
-	else
-		width = max_change;
 
+	width = options->stat_width ? options->stat_width : term_columns();
+
+	/*
+	 * Guarantee 3/8*16==6 for the graph part
+	 * and 5/8*16==10 for the filename part
+	 */
+	if (width < 16 + 6 + number_width)
+		width = 16 + 6 + number_width;
+
+	/*
+	 * First assign sizes that are wanted, ignoring available width.
+	 */
+	graph_width = max_change < 40 ? max_change : 40;
+	name_width = (options->stat_name_width > 0 &&
+		      options->stat_name_width < max_len) ?
+		options->stat_name_width : max_len;
+
+	/*
+	 * Adjust adjustable widths not to exceed maximum width
+	 */
+	if (name_width + number_width + 6 + graph_width > width) {
+		if (graph_width > width * 3/8 - number_width - 6)
+			graph_width = width * 3/8 - number_width - 6;
+		if (graph_width > 40)
+			graph_width =  40;
+		if (name_width > width - number_width - 6 - graph_width)
+			name_width = width - number_width - 6 - graph_width;
+		else
+			graph_width = width - number_width - 6 - name_width;
+	}
+
+	/*
+	 * From here name_width is the width of the name area,
+	 * and graph_width is the width of the graph area.
+	 * max_change is used to scale graph properly.
+	 */
 	for (i = 0; i < count; i++) {
 		const char *prefix = "";
 		char *name = data->files[i]->print_name;
@@ -1448,9 +1482,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		adds += add;
 		dels += del;
 
-		if (width <= max_change) {
-			add = scale_linear(add, width, max_change);
-			del = scale_linear(del, width, max_change);
+		if (graph_width <= max_change) {
+			add = scale_linear(add, graph_width, max_change);
+			del = scale_linear(del, graph_width, max_change);
 		}
 		fprintf(options->file, "%s", line_prefix);
 		show_name(options->file, prefix, name, len);
-- 
1.7.9.5.g91d5

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 3/3 v5] diff --stat: use less columns for change counts
  2012-02-15 11:03                     ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts Zbigniew Jędrzejewski-Szmek
  2012-02-15 11:03                       ` [PATCH 2/3 v5] diff --stat: use the full terminal width Zbigniew Jędrzejewski-Szmek
@ 2012-02-15 11:03                       ` Zbigniew Jędrzejewski-Szmek
  2012-02-15 12:12                         ` Nguyen Thai Ngoc Duy
  2012-02-15 17:12                       ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big " Junio C Hamano
  2 siblings, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-15 11:03 UTC (permalink / raw)
  To: git, gitster; +Cc: Michael J Gruber, pclouds, Zbigniew Jędrzejewski-Szmek

Number of columns required for change counts is computed based on the
maximum number of changed lines. This means that usually a few more
columns will be available for the filenames and the graph.

The graph width logic is also modified to include enough space for
"Bin XXX -> YYY bytes".

If changes to binary files are mixed with changes to text files,
change counts are padded to take at least three columns. And the other
way around, if change counts require more than three columns, then
"Bin"s are padded to align with the change count. This way, the +-
part starts in the same column as "XXX -> YYY" part for binary files.
This makes the graph easier to parse visually thanks to the empty
column. This mimics the layout of diff --stat before this change.

Tests and the tutorial are updated to reflect the new --stat output.
One test for the graph alignment with a binary file change and text
file change of more than 999 lines is added.

Signed-off-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
---
This is the small patch which causes big changes in output.
In previous version this was part of patch 1 (use the full terminal
width) and whole of patches 2 (better aligment for binary files) and 3
(update diff --stat output).

 Documentation/gitcore-tutorial.txt                 |  4 +-
 diff.c                                             | 44 ++++++++++++++---
 t/t0023-crlf-am.sh                                 |  2 +-
 t/t1200-tutorial.sh                                |  4 +-
 t/t3404-rebase-interactive.sh                      |  2 +-
 t/t3903-stash.sh                                   |  4 +-
 t/t4012-diff-binary.sh                             | 19 ++++++++
 ...ff-tree_--cc_--patch-with-stat_--summary_master |  4 +-
 ...diff-tree_--cc_--patch-with-stat_--summary_side |  6 +-
 .../diff.diff-tree_--cc_--patch-with-stat_master   |  4 +-
 .../diff.diff-tree_--cc_--stat_--summary_master    |  4 +-
 t/t4013/diff.diff-tree_--cc_--stat_--summary_side  |  6 +-
 t/t4013/diff.diff-tree_--cc_--stat_master          |  4 +-
 ...pretty=oneline_--root_--patch-with-stat_initial |  6 +-
 .../diff.diff-tree_--pretty_--patch-with-stat_side |  6 +-
 ...-tree_--pretty_--root_--patch-with-stat_initial |  6 +-
 ...f-tree_--pretty_--root_--stat_--summary_initial |  6 +-
 .../diff.diff-tree_--pretty_--root_--stat_initial  |  6 +-
 ...diff.diff-tree_--root_--patch-with-stat_initial |  6 +-
 t/t4013/diff.diff-tree_-c_--stat_--summary_master  |  4 +-
 t/t4013/diff.diff-tree_-c_--stat_--summary_side    |  6 +-
 t/t4013/diff.diff-tree_-c_--stat_master            |  4 +-
 .../diff.diff_--patch-with-stat_-r_initial..side   |  6 +-
 t/t4013/diff.diff_--patch-with-stat_initial..side  |  6 +-
 t/t4013/diff.diff_--stat_initial..side             |  6 +-
 t/t4013/diff.diff_-r_--stat_initial..side          |  6 +-
 ..._--attach_--stdout_--suffix=.diff_initial..side |  6 +-
 ....format-patch_--attach_--stdout_initial..master | 16 +++---
 ...format-patch_--attach_--stdout_initial..master^ | 10 ++--
 ...ff.format-patch_--attach_--stdout_initial..side |  6 +-
 ...nline_--stdout_--numbered-files_initial..master | 16 +++---
 ...tdout_--subject-prefix=TESTCASE_initial..master | 16 +++---
 ....format-patch_--inline_--stdout_initial..master | 16 +++---
 ...format-patch_--inline_--stdout_initial..master^ | 10 ++--
 ...ormat-patch_--inline_--stdout_initial..master^^ |  6 +-
 ...ff.format-patch_--inline_--stdout_initial..side |  6 +-
 ...tch_--stdout_--cover-letter_-n_initial..master^ | 18 ++++----
 ...at-patch_--stdout_--no-numbered_initial..master | 16 +++---
 ...ormat-patch_--stdout_--numbered_initial..master | 16 +++---
 t/t4013/diff.format-patch_--stdout_initial..master | 16 +++---
 .../diff.format-patch_--stdout_initial..master^    | 10 ++--
 t/t4013/diff.format-patch_--stdout_initial..side   |  6 +-
 ....log_--patch-with-stat_--summary_master_--_dir_ |  6 +-
 t/t4013/diff.log_--patch-with-stat_master          | 16 +++---
 t/t4013/diff.log_--patch-with-stat_master_--_dir_  |  6 +-
 ..._--root_--cc_--patch-with-stat_--summary_master | 26 +++++-----
 ...f.log_--root_--patch-with-stat_--summary_master | 22 ++++----
 t/t4013/diff.log_--root_--patch-with-stat_master   | 22 ++++----
 ...og_--root_-c_--patch-with-stat_--summary_master | 26 +++++-----
 t/t4013/diff.show_--patch-with-stat_--summary_side |  6 +-
 t/t4013/diff.show_--patch-with-stat_side           |  6 +-
 t/t4013/diff.show_--stat_--summary_side            |  6 +-
 t/t4013/diff.show_--stat_side                      |  6 +-
 ...nged_--patch-with-stat_--summary_master_--_dir_ |  6 +-
 t/t4013/diff.whatchanged_--patch-with-stat_master  | 16 +++---
 ...ff.whatchanged_--patch-with-stat_master_--_dir_ |  6 +-
 ..._--root_--cc_--patch-with-stat_--summary_master | 26 +++++-----
 ...anged_--root_--patch-with-stat_--summary_master | 22 ++++----
 ...iff.whatchanged_--root_--patch-with-stat_master | 22 ++++----
 ...ed_--root_-c_--patch-with-stat_--summary_master | 26 +++++-----
 t/t4014-format-patch.sh                            | 10 ++--
 t/t4016-diff-quote.sh                              | 14 +++---
 t/t4030-diff-textconv.sh                           |  2 +-
 t/t4043-diff-rename-binary.sh                      |  4 +-
 t/t4045-diff-relative.sh                           |  2 +-
 t/t4047-diff-dirstat.sh                            | 54 +++++++++++-----------
 t/t4049-diff-stat-count.sh                         |  4 +-
 t/t5100/patch0001                                  |  2 +-
 t/t5100/patch0002                                  |  2 +-
 t/t5100/patch0003                                  |  2 +-
 t/t5100/patch0005                                  |  4 +-
 t/t5100/patch0006                                  |  2 +-
 t/t5100/patch0010                                  |  2 +-
 t/t5100/patch0011                                  |  2 +-
 t/t5100/patch0014                                  |  2 +-
 t/t5100/patch0014--scissors                        |  2 +-
 t/t5100/sample.mbox                                | 18 ++++----
 t/t7602-merge-octopus-many.sh                      | 12 ++--
 78 files changed, 415 insertions(+), 368 deletions(-)

diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt
index c27d086..b781bbf 100644
--- a/Documentation/gitcore-tutorial.txt
+++ b/Documentation/gitcore-tutorial.txt
@@ -1002,8 +1002,8 @@ would be different)
 ----------------
 Updating from ae3a2da... to a80b4aa....
 Fast-forward (no commit created; -m option ignored)
- example |    1 +
- hello   |    1 +
+ example | 1 +
+ hello   | 1 +
  2 files changed, 2 insertions(+), 0 deletions(-)
 ----------------
 
diff --git a/diff.c b/diff.c
index be6d40b..dd72d35 100644
--- a/diff.c
+++ b/diff.c
@@ -1326,8 +1326,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 {
 	int i, len, add, del, adds = 0, dels = 0;
 	uintmax_t max_change = 0, max_len = 0;
-	int total_files = data->nr;
-	int width, name_width, graph_width, number_width = 4, count;
+	int total_files = data->nr, count;
+	int width, name_width, graph_width, number_width = 0, bin_width = 0;
 	const char *reset, *add_c, *del_c;
 	const char *line_prefix = "";
 	int extra_shown = 0;
@@ -1363,8 +1363,21 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		if (max_len < len)
 			max_len = len;
 
-		if (file->is_binary || file->is_unmerged)
+		if (file->is_unmerged) {
+			/* "Unmerged" is 8 characters */
+			bin_width = bin_width < 8 ? 8 : bin_width;
 			continue;
+		}
+		if (file->is_binary) {
+			/* "Bin XXX -> YYY bytes" */
+			int w = 14 + decimal_width(file->added)
+				+ decimal_width(file->deleted);
+			bin_width = bin_width < w ? w : bin_width;
+			/* Display change counts aligned with "Bin" */
+			number_width = 3;
+			continue;
+		}
+
 		if (max_change < change)
 			max_change = change;
 	}
@@ -1389,9 +1402,19 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 	 * stat_name_width fixes the maximum width of the filename,
 	 * and is also used to divide available columns if there
 	 * aren't enough.
+	 *
+	 * Binary files are displayed with "Bin XXX -> YYY bytes"
+	 * instead of the change count and graph. This part is treated
+	 * similarly to the graph part, except that it is not
+	 * "scaled". If total width is too small to accomodate the
+	 * guaranteed minimum width of the filename part and the
+	 * separators and this message, this message will "overflow"
+	 * making the line longer than the maximum width.
 	 */
 
 	width = options->stat_width ? options->stat_width : term_columns();
+	number_width = decimal_width(max_change) > number_width ?
+		decimal_width(max_change) : number_width;
 
 	/*
 	 * Guarantee 3/8*16==6 for the graph part
@@ -1402,8 +1425,12 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 
 	/*
 	 * First assign sizes that are wanted, ignoring available width.
+	 * strlen("Bin XXX -> YYY bytes") == bin_width, and the part
+	 * starting from "XXX" should fit in graph_width.
 	 */
-	graph_width = max_change < 40 ? max_change : 40;
+	graph_width = max_change + 4 > bin_width ? max_change : bin_width - 4;
+	if (graph_width > 40)
+		graph_width = 40;
 	name_width = (options->stat_name_width > 0 &&
 		      options->stat_name_width < max_len) ?
 		options->stat_name_width : max_len;
@@ -1457,7 +1484,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		if (data->files[i]->is_binary) {
 			fprintf(options->file, "%s", line_prefix);
 			show_name(options->file, prefix, name, len);
-			fprintf(options->file, "  Bin ");
+			fprintf(options->file, " %*s ", number_width, "Bin");
 			fprintf(options->file, "%s%"PRIuMAX"%s",
 				del_c, deleted, reset);
 			fprintf(options->file, " -> ");
@@ -1470,7 +1497,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		else if (data->files[i]->is_unmerged) {
 			fprintf(options->file, "%s", line_prefix);
 			show_name(options->file, prefix, name, len);
-			fprintf(options->file, "  Unmerged\n");
+			fprintf(options->file, " Unmerged\n");
 			continue;
 		}
 
@@ -1488,8 +1515,9 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		}
 		fprintf(options->file, "%s", line_prefix);
 		show_name(options->file, prefix, name, len);
-		fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,
-				added + deleted ? " " : "");
+		fprintf(options->file, " %*"PRIuMAX"%s",
+			number_width, added + deleted,
+			added + deleted ? " " : "");
 		show_graph(options->file, '+', add, add_c, reset);
 		show_graph(options->file, '-', del, del_c, reset);
 		fprintf(options->file, "\n");
diff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh
index aaed725..f9bbb91 100755
--- a/t/t0023-crlf-am.sh
+++ b/t/t0023-crlf-am.sh
@@ -11,7 +11,7 @@ Date: Thu, 23 Aug 2007 13:00:00 +0200
 Subject: test1
 
 ---
- foo |    1 +
+ foo | 1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
  create mode 100644 foo
 
diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh
index 5e29e13..77ff21c 100755
--- a/t/t1200-tutorial.sh
+++ b/t/t1200-tutorial.sh
@@ -154,8 +154,8 @@ test_expect_success 'git show-branch' '
 cat > resolve.expect << EOF
 Updating VARIABLE..VARIABLE
 FASTFORWARD (no commit created; -m option ignored)
- example |    1 +
- hello   |    1 +
+ example | 1 +
+ hello   | 1 +
  2 files changed, 2 insertions(+), 0 deletions(-)
 EOF
 
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index b981572..c8fe1a9 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -323,7 +323,7 @@ test_expect_success 'verbose flag is heeded, even after --continue' '
 	echo resolved > file1 &&
 	git add file1 &&
 	git rebase --continue > output &&
-	grep "^ file1 |    2 +-$" output
+	grep "^ file1 | 2 +-$" output
 '
 
 test_expect_success 'multi-squash only fires up editor once' '
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index dbe2ac1..fbf064e 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -443,7 +443,7 @@ test_expect_success 'stash show - stashes on stack, stash-like argument' '
 	STASH_ID=$(git stash create) &&
 	git reset --hard &&
 	cat >expected <<-EOF &&
-	 file |    1 +
+	 file | 1 +
 	 1 files changed, 1 insertions(+), 0 deletions(-)
 	EOF
 	git stash show ${STASH_ID} >actual &&
@@ -481,7 +481,7 @@ test_expect_success 'stash show - no stashes on stack, stash-like argument' '
 	STASH_ID=$(git stash create) &&
 	git reset --hard &&
 	cat >expected <<-EOF &&
-	 file |    1 +
+	 file | 1 +
 	 1 files changed, 1 insertions(+), 0 deletions(-)
 	EOF
 	git stash show ${STASH_ID} >actual &&
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index 2d9f9a0..9dd48bb 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -90,4 +90,23 @@ test_expect_success 'diff --no-index with binary creation' '
 	test_cmp expected actual
 '
 
+cat >expect <<EOF
+ binfile  |   Bin 0 -> 1026 bytes
+ textfile | 10000 ++++++++++++++++++++++++++++++++++++++++
+EOF
+
+test_expect_success 'diff --stat with binary files and big change count' '
+	echo X | dd of=binfile bs=1k seek=1 &&
+	git add binfile &&
+	i=0 &&
+	while test $i -lt 10000; do
+		echo $i &&
+		i=$(($i + 1))
+	done >textfile &&
+	git add textfile &&
+	git diff --cached --stat binfile textfile >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
index 3a9f78a..b87f758 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_master
@@ -1,7 +1,7 @@
 $ git diff-tree --cc --patch-with-stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --cc dir/sub
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
index a61ad8c..47665f9 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_side
@@ -1,8 +1,8 @@
 $ git diff-tree --cc --patch-with-stat --summary side
 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
index 49f23b9..efe6dcc 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
@@ -1,7 +1,7 @@
 $ git diff-tree --cc --patch-with-stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --cc dir/sub
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
index cc6eb3b..1b465f0 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
@@ -1,6 +1,6 @@
 $ git diff-tree --cc --stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
index 50362be..44fcf4e 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
@@ -1,8 +1,8 @@
 $ git diff-tree --cc --stat --summary side
 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 $
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_master b/t/t4013/diff.diff-tree_--cc_--stat_master
index fae7f33..6dffb7f 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_master
@@ -1,6 +1,6 @@
 $ git diff-tree --cc --stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
index d5c333a..a7d91c9 100644
--- a/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty=oneline_--root_--patch-with-stat_initial
@@ -1,8 +1,8 @@
 $ git diff-tree --pretty=oneline --root --patch-with-stat initial
 444ac553ac7612cc88969031b02b3767fb8a353a Initial
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
index 4d30e7e..2061f37 100644
--- a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
+++ b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
index 7dfa6af..71d912e 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--patch-with-stat_initial
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
index 43bfce2..b80dbcc 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
index 9154aa4..88cb5c9 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
@@ -5,8 +5,8 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
index 1562b62..748ba93 100644
--- a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
@@ -1,8 +1,8 @@
 $ git diff-tree --root --patch-with-stat initial
 444ac553ac7612cc88969031b02b3767fb8a353a
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_master b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
index ac9f641..700c386 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
@@ -1,6 +1,6 @@
 $ git diff-tree -c --stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_side b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
index 2afcca1..520aa4f 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
@@ -1,8 +1,8 @@
 $ git diff-tree -c --stat --summary side
 c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 $
diff --git a/t/t4013/diff.diff-tree_-c_--stat_master b/t/t4013/diff.diff-tree_-c_--stat_master
index c2fe6a9..cdc7c40 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_master
@@ -1,6 +1,6 @@
 $ git diff-tree -c --stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
index 9ed317a..abf43a9 100644
--- a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
@@ -1,7 +1,7 @@
 $ git diff --patch-with-stat -r initial..side
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff_--patch-with-stat_initial..side b/t/t4013/diff.diff_--patch-with-stat_initial..side
index 8b50629..f88262e 100644
--- a/t/t4013/diff.diff_--patch-with-stat_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_initial..side
@@ -1,7 +1,7 @@
 $ git diff --patch-with-stat initial..side
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.diff_--stat_initial..side b/t/t4013/diff.diff_--stat_initial..side
index 0517b5d..17a07be 100644
--- a/t/t4013/diff.diff_--stat_initial..side
+++ b/t/t4013/diff.diff_--stat_initial..side
@@ -1,6 +1,6 @@
 $ git diff --stat initial..side
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.diff_-r_--stat_initial..side b/t/t4013/diff.diff_-r_--stat_initial..side
index 245220d..54507eb 100644
--- a/t/t4013/diff.diff_-r_--stat_initial..side
+++ b/t/t4013/diff.diff_-r_--stat_initial..side
@@ -1,6 +1,6 @@
 $ git diff -r --stat initial..side
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side b/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
index 52116d3..6996877 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_--suffix=.diff_initial..side
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
index ce49bd6..d56a1a3 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
index 5f1b238..b76e61f 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
diff --git a/t/t4013/diff.format-patch_--attach_--stdout_initial..side b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
index 4a2364a..769cf32 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
index 43b81eb..0ee7338 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
index ca3f60b..fbf3bd4 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
index 08f2301..d68e3ee 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -121,9 +121,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
index 07f1230..668e38f 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
index 29e00ab..caec553 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^^
@@ -14,9 +14,9 @@ Content-Transfer-Encoding: 8bit
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..side b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
index 67633d4..6b84b1b 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
@@ -12,9 +12,9 @@ Content-Type: text/plain; charset=UTF-8; format=fixed
 Content-Transfer-Encoding: 8bit
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
index 3b4e113..d8cba57 100644
--- a/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..master^
@@ -10,10 +10,10 @@ A U Thor (2):
   Second
   Third
 
- dir/sub |    4 ++++
- file0   |    3 +++
- file1   |    3 +++
- file2   |    3 ---
+ dir/sub | 4 ++++
+ file0   | 3 +++
+ file1   | 3 +++
+ file2   | 3 ---
  4 files changed, 10 insertions(+), 3 deletions(-)
  create mode 100644 file1
  delete mode 100644 file2
@@ -28,9 +28,9 @@ Subject: [DIFFERENT_PREFIX 1/2] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -73,8 +73,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [DIFFERENT_PREFIX 2/2] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
diff --git a/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master b/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
index f7752eb..a2a4726 100644
--- a/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [PATCH] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
 Subject: [PATCH] Side
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
index 8e67dbf..602f4b0 100644
--- a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH 1/3] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [PATCH 2/3] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
 Subject: [PATCH 3/3] Side
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master b/t/t4013/diff.format-patch_--stdout_initial..master
index 7b89978..bcf739e 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_initial..master
@@ -6,9 +6,9 @@ Subject: [PATCH 1/3] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [PATCH 2/3] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -85,9 +85,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
 Subject: [PATCH 3/3] Side
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master^ b/t/t4013/diff.format-patch_--stdout_initial..master^
index b7f9725..7d5ba0f 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_initial..master^
@@ -6,9 +6,9 @@ Subject: [PATCH 1/2] Second
 
 This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -51,8 +51,8 @@ Date: Mon, 26 Jun 2006 00:02:00 +0000
 Subject: [PATCH 2/2] Third
 
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
diff --git a/t/t4013/diff.format-patch_--stdout_initial..side b/t/t4013/diff.format-patch_--stdout_initial..side
index e765088..9ed0ea2 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--stdout_initial..side
@@ -5,9 +5,9 @@ Date: Mon, 26 Jun 2006 00:03:00 +0000
 Subject: [PATCH] Side
 
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
index bd7f5c0..e2954d3 100644
--- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
@@ -12,7 +12,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -31,7 +31,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -53,7 +53,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master
index 14595a6..e417873 100644
--- a/t/t4013/diff.log_--patch-with-stat_master
+++ b/t/t4013/diff.log_--patch-with-stat_master
@@ -12,9 +12,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -54,8 +54,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -86,9 +86,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
index 5a4e727..cebec52 100644
--- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
@@ -12,7 +12,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -31,7 +31,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -53,7 +53,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
index df0aaa9..540633f 100644
--- a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
@@ -6,8 +6,8 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
     Merge branch 'side'
 
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --cc dir/sub
@@ -44,9 +44,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -87,8 +87,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -162,9 +162,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
index c11b5f2c..fb289d8 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
@@ -12,9 +12,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -55,8 +55,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -88,9 +88,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -130,9 +130,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master
index 5f0c98f..84f535d 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_master
@@ -12,9 +12,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -54,8 +54,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -86,9 +86,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -127,9 +127,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
index e62c368..3e89ace 100644
--- a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
@@ -6,8 +6,8 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
     Merge branch 'side'
 
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --combined dir/sub
@@ -44,9 +44,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -87,8 +87,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -162,9 +162,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.show_--patch-with-stat_--summary_side b/t/t4013/diff.show_--patch-with-stat_--summary_side
index 377f2b7..38c1841 100644
--- a/t/t4013/diff.show_--patch-with-stat_--summary_side
+++ b/t/t4013/diff.show_--patch-with-stat_--summary_side
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
diff --git a/t/t4013/diff.show_--patch-with-stat_side b/t/t4013/diff.show_--patch-with-stat_side
index fb14c53..38f6be2 100644
--- a/t/t4013/diff.show_--patch-with-stat_side
+++ b/t/t4013/diff.show_--patch-with-stat_side
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.show_--stat_--summary_side b/t/t4013/diff.show_--stat_--summary_side
index 5bd5977..e6f30a4 100644
--- a/t/t4013/diff.show_--stat_--summary_side
+++ b/t/t4013/diff.show_--stat_--summary_side
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 $
diff --git a/t/t4013/diff.show_--stat_side b/t/t4013/diff.show_--stat_side
index 3b22327..58ee49a 100644
--- a/t/t4013/diff.show_--stat_side
+++ b/t/t4013/diff.show_--stat_side
@@ -5,8 +5,8 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 $
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
index 6a467cc..ee340b8 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
@@ -5,7 +5,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -24,7 +24,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -46,7 +46,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master b/t/t4013/diff.whatchanged_--patch-with-stat_master
index 1e1bbe1..4adeab7 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -47,8 +47,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -79,9 +79,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
index 13789f1..63a3043 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
@@ -5,7 +5,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -24,7 +24,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -46,7 +46,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
+ dir/sub | 2 ++
  1 files changed, 2 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
index e96ff1f..60f3788 100644
--- a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
@@ -6,8 +6,8 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
     Merge branch 'side'
 
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --cc dir/sub
@@ -44,9 +44,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -87,8 +87,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -162,9 +162,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
index 0291153..9b7f63f 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -48,8 +48,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -81,9 +81,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -123,9 +123,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
index 9b0349c..cba8f3c 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
@@ -5,9 +5,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -47,8 +47,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -79,9 +79,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
index c0aff68..8e24293 100644
--- a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
@@ -6,8 +6,8 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
     Merge branch 'side'
 
- dir/sub |    2 ++
- file0   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
 
 diff --combined dir/sub
@@ -44,9 +44,9 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
 
     Side
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file3   |    4 ++++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file3   | 4 ++++
  3 files changed, 9 insertions(+), 0 deletions(-)
  create mode 100644 file3
 
@@ -87,8 +87,8 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 
     Third
 ---
- dir/sub |    2 ++
- file1   |    3 +++
+ dir/sub | 2 ++
+ file1   | 3 +++
  2 files changed, 5 insertions(+), 0 deletions(-)
  create mode 100644 file1
 
@@ -120,9 +120,9 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     
     This is the second commit.
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 ---
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 ---
  3 files changed, 5 insertions(+), 3 deletions(-)
  delete mode 100644 file2
 
@@ -162,9 +162,9 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
 
     Initial
 ---
- dir/sub |    2 ++
- file0   |    3 +++
- file2   |    3 +++
+ dir/sub | 2 ++
+ file0   | 3 +++
+ file2   | 3 +++
  3 files changed, 8 insertions(+), 0 deletions(-)
  create mode 100644 dir/sub
  create mode 100644 file0
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index f6ebb51..bb430ac 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -519,7 +519,7 @@ test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 
 cat > expect << EOF
 ---
- file |   16 ++++++++++++++++
+ file | 16 ++++++++++++++++
  1 files changed, 16 insertions(+), 0 deletions(-)
 
 diff --git a/file b/file
@@ -906,7 +906,7 @@ test_expect_success 'preparation' "
 "
 
 cat >expect <<'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
 EOF
 test_expect_success 'format patch graph width defaults to 80 columns' '
 	git format-patch --stat --stdout -1 >output &&
@@ -915,7 +915,7 @@ test_expect_success 'format patch graph width defaults to 80 columns' '
 '
 
 cat >expect <<'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
 EOF
 test_expect_success 'format patch --stat=width with long name' '
 	git format-patch --stat=40 --stdout -1 >output &&
@@ -930,13 +930,13 @@ test_expect_success 'format patch --stat-width=width works with long name' '
 '
 
 test_expect_success 'format patch --stat=...,name-width with long name' '
-	git format-patch --stat=60,29 --stdout -1 >output &&
+	git format-patch --stat=60,32 --stdout -1 >output &&
 	grep " | " output >actual &&
 	test_cmp expect actual
 '
 
 test_expect_success 'format patch --stat-name-width with long name' '
-	git format-patch --stat-name-width=29 --stdout -1 >output &&
+	git format-patch --stat-name-width=32 --stdout -1 >output &&
 	grep " | " output >actual &&
 	test_cmp expect actual
 '
diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh
index ab0c2f0..e451f2a 100755
--- a/t/t4016-diff-quote.sh
+++ b/t/t4016-diff-quote.sh
@@ -59,13 +59,13 @@ test_expect_success TABS_IN_FILENAMES 'git diff --summary -M HEAD' '
 
 test_expect_success TABS_IN_FILENAMES 'setup expected files' '
 cat >expect <<\EOF
- pathname.1 => "Rpathname\twith HT.0"            |    0
- pathname.3 => "Rpathname\nwith LF.0"            |    0
- "pathname\twith HT.3" => "Rpathname\nwith LF.1" |    0
- pathname.2 => Rpathname with SP.0               |    0
- "pathname\twith HT.2" => Rpathname with SP.1    |    0
- pathname.0 => Rpathname.0                       |    0
- "pathname\twith HT.0" => Rpathname.1            |    0
+ pathname.1 => "Rpathname\twith HT.0"            | 0
+ pathname.3 => "Rpathname\nwith LF.0"            | 0
+ "pathname\twith HT.3" => "Rpathname\nwith LF.1" | 0
+ pathname.2 => Rpathname with SP.0               | 0
+ "pathname\twith HT.2" => Rpathname with SP.1    | 0
+ pathname.0 => Rpathname.0                       | 0
+ "pathname\twith HT.0" => Rpathname.1            | 0
  7 files changed, 0 insertions(+), 0 deletions(-)
 EOF
 '
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index 88c5619..6a6344c 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -85,7 +85,7 @@ test_expect_success 'status -v produces text' '
 '
 
 cat >expect.stat <<'EOF'
- file |  Bin 2 -> 4 bytes
+ file | Bin 2 -> 4 bytes
  1 files changed, 0 insertions(+), 0 deletions(-)
 EOF
 test_expect_success 'diffstat does not run textconv' '
diff --git a/t/t4043-diff-rename-binary.sh b/t/t4043-diff-rename-binary.sh
index 0601281..ad0b2da 100755
--- a/t/t4043-diff-rename-binary.sh
+++ b/t/t4043-diff-rename-binary.sh
@@ -23,8 +23,8 @@ test_expect_success 'move the files into a "sub" directory' '
 '
 
 cat > expected <<\EOF
- bar => sub/bar |  Bin 5 -> 5 bytes
- foo => sub/foo |    0
+ bar => sub/bar | Bin 5 -> 5 bytes
+ foo => sub/foo |   0
  2 files changed, 0 insertions(+), 0 deletions(-)
 
 diff --git a/bar b/sub/bar
diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh
index 8a3c63b..336df82 100755
--- a/t/t4045-diff-relative.sh
+++ b/t/t4045-diff-relative.sh
@@ -32,7 +32,7 @@ test_expect_success "-p $*" "
 check_stat() {
 expect=$1; shift
 cat >expected <<EOF
- $expect |    1 +
+ $expect | 1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
 EOF
 test_expect_success "--stat $*" "
diff --git a/t/t4047-diff-dirstat.sh b/t/t4047-diff-dirstat.sh
index 29e80a5..75eaf16 100755
--- a/t/t4047-diff-dirstat.sh
+++ b/t/t4047-diff-dirstat.sh
@@ -252,41 +252,41 @@ EOF
 '
 
 cat <<EOF >expect_diff_stat
- changed/text             |    2 +-
- dst/copy/changed/text    |   10 ++++++++++
- dst/copy/rearranged/text |   10 ++++++++++
- dst/copy/unchanged/text  |   10 ++++++++++
- dst/move/changed/text    |   10 ++++++++++
- dst/move/rearranged/text |   10 ++++++++++
- dst/move/unchanged/text  |   10 ++++++++++
- rearranged/text          |    2 +-
- src/move/changed/text    |   10 ----------
- src/move/rearranged/text |   10 ----------
- src/move/unchanged/text  |   10 ----------
+ changed/text             |  2 +-
+ dst/copy/changed/text    | 10 ++++++++++
+ dst/copy/rearranged/text | 10 ++++++++++
+ dst/copy/unchanged/text  | 10 ++++++++++
+ dst/move/changed/text    | 10 ++++++++++
+ dst/move/rearranged/text | 10 ++++++++++
+ dst/move/unchanged/text  | 10 ++++++++++
+ rearranged/text          |  2 +-
+ src/move/changed/text    | 10 ----------
+ src/move/rearranged/text | 10 ----------
+ src/move/unchanged/text  | 10 ----------
  11 files changed, 62 insertions(+), 32 deletions(-)
 EOF
 
 cat <<EOF >expect_diff_stat_M
- changed/text                      |    2 +-
- dst/copy/changed/text             |   10 ++++++++++
- dst/copy/rearranged/text          |   10 ++++++++++
- dst/copy/unchanged/text           |   10 ++++++++++
- {src => dst}/move/changed/text    |    2 +-
- {src => dst}/move/rearranged/text |    2 +-
- {src => dst}/move/unchanged/text  |    0
- rearranged/text                   |    2 +-
+ changed/text                      |  2 +-
+ dst/copy/changed/text             | 10 ++++++++++
+ dst/copy/rearranged/text          | 10 ++++++++++
+ dst/copy/unchanged/text           | 10 ++++++++++
+ {src => dst}/move/changed/text    |  2 +-
+ {src => dst}/move/rearranged/text |  2 +-
+ {src => dst}/move/unchanged/text  |  0
+ rearranged/text                   |  2 +-
  8 files changed, 34 insertions(+), 4 deletions(-)
 EOF
 
 cat <<EOF >expect_diff_stat_CC
- changed/text                      |    2 +-
- {src => dst}/copy/changed/text    |    2 +-
- {src => dst}/copy/rearranged/text |    2 +-
- {src => dst}/copy/unchanged/text  |    0
- {src => dst}/move/changed/text    |    2 +-
- {src => dst}/move/rearranged/text |    2 +-
- {src => dst}/move/unchanged/text  |    0
- rearranged/text                   |    2 +-
+ changed/text                      | 2 +-
+ {src => dst}/copy/changed/text    | 2 +-
+ {src => dst}/copy/rearranged/text | 2 +-
+ {src => dst}/copy/unchanged/text  | 0
+ {src => dst}/move/changed/text    | 2 +-
+ {src => dst}/move/rearranged/text | 2 +-
+ {src => dst}/move/unchanged/text  | 0
+ rearranged/text                   | 2 +-
  8 files changed, 6 insertions(+), 6 deletions(-)
 EOF
 
diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh
index 641e70d..5edac4e 100755
--- a/t/t4049-diff-stat-count.sh
+++ b/t/t4049-diff-stat-count.sh
@@ -14,8 +14,8 @@ test_expect_success setup '
 	echo a >a &&
 	echo b >b &&
 	cat >expect <<-\EOF
-	 a |    1 +
-	 b |    1 +
+	 a | 1 +
+	 b | 1 +
 	 2 files changed, 2 insertions(+), 0 deletions(-)
 	EOF
 	git diff --stat --stat-count=2 >actual &&
diff --git a/t/t5100/patch0001 b/t/t5100/patch0001
index 8ce1551..02c9774 100644
--- a/t/t5100/patch0001
+++ b/t/t5100/patch0001
@@ -1,5 +1,5 @@
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
diff --git a/t/t5100/patch0002 b/t/t5100/patch0002
index 8ce1551..02c9774 100644
--- a/t/t5100/patch0002
+++ b/t/t5100/patch0002
@@ -1,5 +1,5 @@
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
diff --git a/t/t5100/patch0003 b/t/t5100/patch0003
index 8ce1551..02c9774 100644
--- a/t/t5100/patch0003
+++ b/t/t5100/patch0003
@@ -1,5 +1,5 @@
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
diff --git a/t/t5100/patch0005 b/t/t5100/patch0005
index 7d24b24..ab7a383 100644
--- a/t/t5100/patch0005
+++ b/t/t5100/patch0005
@@ -1,7 +1,7 @@
 ---
 
- Documentation/git-cvsimport-script.txt |    9 ++++++++-
- git-cvsimport-script                   |    4 ++--
+ Documentation/git-cvsimport-script.txt | 9 ++++++++-
+ git-cvsimport-script                   | 4 ++--
  2 files changed, 10 insertions(+), 3 deletions(-)
 
 50452f9c0c2df1f04d83a26266ba704b13861632
diff --git a/t/t5100/patch0006 b/t/t5100/patch0006
index 8ce1551..02c9774 100644
--- a/t/t5100/patch0006
+++ b/t/t5100/patch0006
@@ -1,5 +1,5 @@
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
diff --git a/t/t5100/patch0010 b/t/t5100/patch0010
index f055481..436821c 100644
--- a/t/t5100/patch0010
+++ b/t/t5100/patch0010
@@ -1,5 +1,5 @@
 ---
- builtin-mailinfo.c |    2 +-
+ builtin-mailinfo.c | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/patch0011 b/t/t5100/patch0011
index 8841d3c..0988713 100644
--- a/t/t5100/patch0011
+++ b/t/t5100/patch0011
@@ -1,5 +1,5 @@
 ---
- builtin-mailinfo.c  |    4 ++--
+ builtin-mailinfo.c  | 4 ++--
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
 index 3e5fe51..aabfe5c 100644
diff --git a/t/t5100/patch0014 b/t/t5100/patch0014
index 124efd2..3f3825f 100644
--- a/t/t5100/patch0014
+++ b/t/t5100/patch0014
@@ -1,5 +1,5 @@
 ---
- builtin-mailinfo.c |   37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
  1 files changed, 36 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/patch0014--scissors b/t/t5100/patch0014--scissors
index 124efd2..3f3825f 100644
--- a/t/t5100/patch0014--scissors
+++ b/t/t5100/patch0014--scissors
@@ -1,5 +1,5 @@
 ---
- builtin-mailinfo.c |   37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
  1 files changed, 36 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t5100/sample.mbox b/t/t5100/sample.mbox
index de10312..34a09a0 100644
--- a/t/t5100/sample.mbox
+++ b/t/t5100/sample.mbox
@@ -12,7 +12,7 @@ Subject: [PATCH] a commit.
 Here is a patch from A U Thor.
 
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
@@ -52,7 +52,7 @@ two truly blank and another full of spaces in between.
 Hope this helps.
 
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
@@ -83,7 +83,7 @@ Message-Id: <nitpicker.12121212@example.net>
 Hopefully this would fix the problem stated there.
 
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
@@ -249,8 +249,8 @@ actual flags.
 Signed-off-by: David K=E5gedal <davidk@lysator.liu.se>
 ---
 
- Documentation/git-cvsimport-script.txt |    9 ++++++++-
- git-cvsimport-script                   |    4 ++--
+ Documentation/git-cvsimport-script.txt | 9 ++++++++-
+ git-cvsimport-script                   | 4 ++--
  2 files changed, 10 insertions(+), 3 deletions(-)
 
 50452f9c0c2df1f04d83a26266ba704b13861632
@@ -379,7 +379,7 @@ Subject: [PATCH] a commit.
 Here is a patch from A U Thor.
 
 ---
- foo |    2 +-
+ foo | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/foo b/foo
@@ -449,7 +449,7 @@ memcmp("Subject: ", header[i], 7) will never match.
 Signed-off-by: Lukas Sandström <lukass@etek.chalmers.se>
 Signed-off-by: Junio C Hamano <gitster@pobox.com>
 ---
- builtin-mailinfo.c |    2 +-
+ builtin-mailinfo.c | 2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
@@ -482,7 +482,7 @@ Content-Transfer-Encoding: quoted-printable
 Here comes a commit log message, and
 its second line is here.
 ---
- builtin-mailinfo.c  |    4 ++--
+ builtin-mailinfo.c  | 4 ++--
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
 index 3e5fe51..aabfe5c 100644
@@ -587,7 +587,7 @@ everything before it in the message body.
 
 Signed-off-by: Junio C Hamano <gitster@pobox.com>
 ---
- builtin-mailinfo.c |   37 ++++++++++++++++++++++++++++++++++++-
+ builtin-mailinfo.c | 37 ++++++++++++++++++++++++++++++++++++-
  1 files changed, 36 insertions(+), 1 deletions(-)
 
 diff --git a/builtin-mailinfo.c b/builtin-mailinfo.c
diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh
index 61f36ba..5a86e24 100755
--- a/t/t7602-merge-octopus-many.sh
+++ b/t/t7602-merge-octopus-many.sh
@@ -54,9 +54,9 @@ Trying simple merge with c2
 Trying simple merge with c3
 Trying simple merge with c4
 Merge made by the 'octopus' strategy.
- c2.c |    1 +
- c3.c |    1 +
- c4.c |    1 +
+ c2.c | 1 +
+ c3.c | 1 +
+ c4.c | 1 +
  3 files changed, 3 insertions(+), 0 deletions(-)
  create mode 100644 c2.c
  create mode 100644 c3.c
@@ -73,7 +73,7 @@ cat >expected <<\EOF
 Already up-to-date with c4
 Trying simple merge with c5
 Merge made by the 'octopus' strategy.
- c5.c |    1 +
+ c5.c | 1 +
  1 files changed, 1 insertions(+), 0 deletions(-)
  create mode 100644 c5.c
 EOF
@@ -87,8 +87,8 @@ cat >expected <<\EOF
 Fast-forwarding to: c1
 Trying simple merge with c2
 Merge made by the 'octopus' strategy.
- c1.c |    1 +
- c2.c |    1 +
+ c1.c | 1 +
+ c2.c | 1 +
  2 files changed, 2 insertions(+), 0 deletions(-)
  create mode 100644 c1.c
  create mode 100644 c2.c
-- 
1.7.9.5.g91d5

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 3/3 v5] diff --stat: use less columns for change counts
  2012-02-15 11:03                       ` [PATCH 3/3 v5] diff --stat: use less columns for change counts Zbigniew Jędrzejewski-Szmek
@ 2012-02-15 12:12                         ` Nguyen Thai Ngoc Duy
  0 siblings, 0 replies; 46+ messages in thread
From: Nguyen Thai Ngoc Duy @ 2012-02-15 12:12 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, gitster, Michael J Gruber

2012/2/15 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>:
> Number of columns required for change counts is computed based on the
> maximum number of changed lines. This means that usually a few more
> columns will be available for the filenames and the graph.

If the required number of columns is less than 80 (or even lower), can
we maintain current spacing strategy? I just want to avoid mass
updates in the test suite. More or less space does not make much
different for narrow diffstats anyway.
-- 
Duy

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts
  2012-02-15 11:03                     ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts Zbigniew Jędrzejewski-Szmek
  2012-02-15 11:03                       ` [PATCH 2/3 v5] diff --stat: use the full terminal width Zbigniew Jędrzejewski-Szmek
  2012-02-15 11:03                       ` [PATCH 3/3 v5] diff --stat: use less columns for change counts Zbigniew Jędrzejewski-Szmek
@ 2012-02-15 17:12                       ` Junio C Hamano
  2012-02-15 17:33                         ` Junio C Hamano
  2012-02-16  9:57                         ` Zbigniew Jędrzejewski-Szmek
  2 siblings, 2 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-15 17:12 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, Michael J Gruber, pclouds

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> Eleven tests for various combinations of a long filename and/or big
> change count and ways to specify widths for diff --stat.
> ---

Sign-off? 

> Tests added in previous version of 'diff --stat: use full terminal width'
> are extracted into a separate patch. The tests are usefull independently
> of that patch anyway.

Thanks.

> +# 120 character name
> +name=aaaaaaaaaa
> +name=$name$name$name$name$name$name$name$name$name$name$name$name
> +test_expect_success 'preparation' "
> +	>\"$name\" &&
> +	git add \"$name\" &&
> +	git commit -m message &&
> +	echo a >\"$name\" &&
> +	git commit -m message \"$name\"
> +"

Just for future reference.

The last parameter to test_expect_success shell function is `eval`ed by
the shell and $name is visible inside it; you do not have to use double
quote around it and then use backquote to quote the inner double quote.

> +cat >expect <<'EOF'
> + ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
> +EOF
> +test_expect_success 'format patch graph width defaults to 80 columns' '
> +	git format-patch --stat --stdout -1 >output &&
> +	grep " | " output >actual &&
> +	test_cmp expect actual
> +'

Hrm, this does not seem to pass, making the result of applying [1/3] fail;
I see that the elided name is shown much shorter than the above expects.

Perhaps this test found a bug in a "very long name, small changes" corner
case?  If that is the case, we'd mark it as test_expect_failure, and
explain the tests that expect failure demonstrates a buggy behaviour, e.g.

	When a pathname is so long that it cannot fit on the column, the
	current code truncates it to make sure that the graph part has at
	least N columns (enough room to show a meaningful graph).  If the
	actual change is small (e.g. only one line changed), this results
	in the final output that is shorter than the width we aim for.  A
	couple of new tests marked with test_expect_failure demonstrate
	this bug.

in the log message (note that I am not sure if that is the nature of the
bug, or what the actual value of N is).

And then a later patch [2/3] that updates the allocation between name and
graph will turn test_expect_failure to test_expect_success; that will make
it clear that your update fixed the bug.

> +cat >expect <<'EOF'
> + ...aaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
> +EOF
> +test_expect_success 'format patch --stat=width with long name' '
> +	git format-patch --stat=40 --stdout -1 >output &&
> +	grep " | " output >actual &&
> +	test_cmp expect actual
> +'

Likewise.

> +test_expect_success 'format patch --stat-width=width works with long name' '
> +	git format-patch --stat-width=40 --stdout -1 >output &&
> +	grep " | " output >actual &&
> +	test_cmp expect actual
> +'

Likewise.

> +test_expect_success 'format patch --stat=...,name-width with long name' '
> +	git format-patch --stat=60,29 --stdout -1 >output &&
> +	grep " | " output >actual &&
> +	test_cmp expect actual
> +'
> +
> +test_expect_success 'format patch --stat-name-width with long name' '
> +	git format-patch --stat-name-width=29 --stdout -1 >output &&
> +	grep " | " output >actual &&
> +	test_cmp expect actual
> +'

Likewise.

> +test_expect_success 'preparation' '

There was another "preparation" in this script already, which originally
threw me off while chasing which part of the test is failing. Can you
reword/retitle this one?

> +cat >expect <<'EOF'
> + abcd | 1000 ++++++++++++++++++++++++++++++++++++++++
> +EOF
> +test_expect_success 'format patch graph part width is 40 columns' '
> +	git format-patch --stat --stdout -1 >output &&
> +	grep " | " output >actual &&
> +	test_cmp expect actual
> +'

This test shouldn't be added in [1/3] because "cap the graph to 40-col" is
a new feature that is introduced in the later step.

> +test_expect_success 'format patch ignores COLUMNS' '
> +	COLUMNS=200 git format-patch --stat --stdout -1 >output
> +	grep " | " output >actual &&
> +	test_cmp expect actual
> +'

This is a good test to have in [1/3], but the expectation should not cap the
graph part to 40 columns.  The patch that updates diff.c to implement the
cap in [2/3] should have an update to the expectation, whose diff hunk may
look liks this:

@@ 
 cat >expect <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- abcd | 1000 ++++++++++++++++++++++++++++++++++++++++ 
 EOF

That would make the effect of the patch clearer.

> +cat >expect <<'EOF'
> + ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
> +EOF
> +test_expect_success 'format patch --stat=width with big change and long name' '
> +	cp abcd aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
> +	git add aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
> +	git commit -m message &&
> +	git format-patch --stat-width=60 --stdout -1 >output &&
> +	grep " | " output >actual &&
> +	test_cmp expect actual
> +'
> +
>  test_done

The same comment as the previous one.  Because you change the allocation
to the graph part in your patch to diff.c, which hasn't happened in [1/3]
yet, this should expect the existing behaviour (narrower graph) in this
step, and then be updated to expect the output shown above in the [2/3]
patch that changes the implementation in diff.c.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts
  2012-02-15 17:12                       ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big " Junio C Hamano
@ 2012-02-15 17:33                         ` Junio C Hamano
  2012-02-16  9:57                         ` Zbigniew Jędrzejewski-Szmek
  1 sibling, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-15 17:33 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, Michael J Gruber, pclouds

Junio C Hamano <gitster@pobox.com> writes:

> Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:
>
>> Eleven tests for various combinations of a long filename and/or big
>> change count and ways to specify widths for diff --stat.
>> ---
>
> Sign-off? 
> ...
> The same comment as the previous one.  Because you change the allocation
> to the graph part in your patch to diff.c, which hasn't happened in [1/3]
> yet, this should expect the existing behaviour (narrower graph) in this
> step, and then be updated to expect the output shown above in the [2/3]
> patch that changes the implementation in diff.c.

The previous review message in a patch form that can be squashed on top of
this patch.

-- >8 --
Subject: [PATCH] (squash to the previous -- replace the log message with this)

diff --stat: tests for long filenames and big change counts

In preparation for updates to the "diff --stat" that updates the logic
to split the allotted columns into the name part and the graph part to
make the output more readable, add a handful of tests to document the
corner case behaviour in which long filenames and big changes are shown.

When a pathname is so long that it cannot fit on the column, the current
code truncates it to make sure that the graph part has enough room to show
a meaningful graph.  If the actual change is small (e.g. only one line
changed), this results in the final output that is shorter than the width
we aim for.  A couple of new tests marked with test_expect_failure
demonstrate this bug.

---
 t/t4014-format-patch.sh |   35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index f6ebb51..0376186 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -897,18 +897,18 @@ test_expect_success 'format patch ignores color.ui' '
 # 120 character name
 name=aaaaaaaaaa
 name=$name$name$name$name$name$name$name$name$name$name$name$name
-test_expect_success 'preparation' "
-	>\"$name\" &&
-	git add \"$name\" &&
+test_expect_success 'preparation' '
+	>"$name" &&
+	git add "$name" &&
 	git commit -m message &&
-	echo a >\"$name\" &&
-	git commit -m message \"$name\"
-"
+	echo a >"$name" &&
+	git commit -m message "$name"
+'
 
 cat >expect <<'EOF'
  ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
 EOF
-test_expect_success 'format patch graph width defaults to 80 columns' '
+test_expect_failure 'format patch graph width defaults to 80 columns' '
 	git format-patch --stat --stdout -1 >output &&
 	grep " | " output >actual &&
 	test_cmp expect actual
@@ -917,13 +917,13 @@ test_expect_success 'format patch graph width defaults to 80 columns' '
 cat >expect <<'EOF'
  ...aaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
 EOF
-test_expect_success 'format patch --stat=width with long name' '
+test_expect_failure 'format patch --stat=width with long name' '
 	git format-patch --stat=40 --stdout -1 >output &&
 	grep " | " output >actual &&
 	test_cmp expect actual
 '
 
-test_expect_success 'format patch --stat-width=width works with long name' '
+test_expect_failure 'format patch --stat-width=width works with long name' '
 	git format-patch --stat-width=40 --stdout -1 >output &&
 	grep " | " output >actual &&
 	test_cmp expect actual
@@ -941,26 +941,21 @@ test_expect_success 'format patch --stat-name-width with long name' '
 	test_cmp expect actual
 '
 
-test_expect_success 'preparation' '
+test_expect_success 'preparation for big change tests' '
 	>abcd &&
 	git add abcd &&
 	git commit -m message &&
 	i=0 &&
-	while test $i -lt 1000; do
-		echo $i &&
-		i=$(($i + 1))
+	while test $i -lt 1000
+	do
+		echo $i && i=$(($i + 1))
 	done >abcd &&
 	git commit -m message abcd
 '
 
 cat >expect <<'EOF'
- abcd | 1000 ++++++++++++++++++++++++++++++++++++++++
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 EOF
-test_expect_success 'format patch graph part width is 40 columns' '
-	git format-patch --stat --stdout -1 >output &&
-	grep " | " output >actual &&
-	test_cmp expect actual
-'
 
 test_expect_success 'format patch ignores COLUMNS' '
 	COLUMNS=200 git format-patch --stat --stdout -1 >output
@@ -984,7 +979,7 @@ test_expect_success 'format patch --stat-width=width with big change' '
 '
 
 cat >expect <<'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 +++++
 EOF
 test_expect_success 'format patch --stat=width with big change and long name' '
 	cp abcd aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
-- 
1.7.9.1.237.g00b59

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 2/3 v5] diff --stat: use the full terminal width
  2012-02-15 11:03                       ` [PATCH 2/3 v5] diff --stat: use the full terminal width Zbigniew Jędrzejewski-Szmek
@ 2012-02-15 18:07                         ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-15 18:07 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, Michael J Gruber, pclouds

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> Use as many columns as necessary for the filenames and up to 40
> columns for the graph.

I started to wonder if it is a good idea to split this step further into
at least two patches:

 - using term_columns() to set the default 'stat-width' instead of
   hardcoded 80, and do nothing else.  As you discovered, this step will
   not have to touch any test expectations.

 - update the logic to split the stat-width into name part and graph
   part. I think as a side-effect this will fix the corner case bugs the
   new tests in your [1/3] seem to have discovered, and the fix will be
   visible to the part that will update t/t4014 in this step.

> ... I've taken the middle way:
> number_width=4 is hardcoded, but the fprintf is reverted to the previous
> version. I think that this way the code is most readable, independently
> if later changes.

Sensible.

> I haven't done this, because $COLUMNS and the actual terminal width is always
> ignored in tests.

As long as the tests are not affected by ioctl(1) that is OK. I am not
expecting us to be automating the test of that codepath (unless somebody
has clever ideas perhaps using pty, but I suspect that would be a separate
patch anyway).

After writing the attached patch that goes on top of this patch to be
squashed, I am starting to think that "maximum 40 columns for the graph"
may be a mild regression for a project with a shallow hierarchy, namely,
this part.

 cat >expect <<'EOF'
- abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++
 EOF

A bug used to waste space by allocating more than necessary as the minimum
number of columns given for the graph part, even when the change turns out
to be just one line, requiring only one '+' in the graph.  The bug was fixed
by this patch not to waste space that way.  But now with this "maximum 40"
limit, we can see that it wastes the space even when the stat-width is 80.

Perhaps the maximum for garph_width should be raised to something like
"min(80, stat_width) - name_width"?

-- >8 --
Subject: [PATCH] (squash to the previous -- replace the last line of the
 log with the following)

The effect of this change is visible in the patch to t4014 that fixes a
few tests marked with test_expect_failure, and the change to shorten the
maximum graph width to 40 columns.
---
 t/t4014-format-patch.sh |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 0376186..88ccc5a 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -908,7 +908,7 @@ test_expect_success 'preparation' '
 cat >expect <<'EOF'
  ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
 EOF
-test_expect_failure 'format patch graph width defaults to 80 columns' '
+test_expect_success 'format patch graph width defaults to 80 columns' '
 	git format-patch --stat --stdout -1 >output &&
 	grep " | " output >actual &&
 	test_cmp expect actual
@@ -917,13 +917,13 @@ test_expect_failure 'format patch graph width defaults to 80 columns' '
 cat >expect <<'EOF'
  ...aaaaaaaaaaaaaaaaaaaaaaaaaa |    1 +
 EOF
-test_expect_failure 'format patch --stat=width with long name' '
+test_expect_success 'format patch --stat=width with long name' '
 	git format-patch --stat=40 --stdout -1 >output &&
 	grep " | " output >actual &&
 	test_cmp expect actual
 '
 
-test_expect_failure 'format patch --stat-width=width works with long name' '
+test_expect_success 'format patch --stat-width=width works with long name' '
 	git format-patch --stat-width=40 --stdout -1 >output &&
 	grep " | " output >actual &&
 	test_cmp expect actual
@@ -954,8 +954,13 @@ test_expect_success 'preparation for big change tests' '
 '
 
 cat >expect <<'EOF'
- abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++
 EOF
+test_expect_success 'format patch graph part width is 40 columns' '
+	git format-patch --stat --stdout -1 >output &&
+	grep " | " output >actual &&
+	test_cmp expect actual
+'
 
 test_expect_success 'format patch ignores COLUMNS' '
 	COLUMNS=200 git format-patch --stat --stdout -1 >output
@@ -979,7 +984,7 @@ test_expect_success 'format patch --stat-width=width with big change' '
 '
 
 cat >expect <<'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 +++++
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
 EOF
 test_expect_success 'format patch --stat=width with big change and long name' '
 	cp abcd aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa &&
-- 
1.7.9.1.237.g00b59

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts
  2012-02-15 17:12                       ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big " Junio C Hamano
  2012-02-15 17:33                         ` Junio C Hamano
@ 2012-02-16  9:57                         ` Zbigniew Jędrzejewski-Szmek
  2012-02-16 20:01                           ` Junio C Hamano
  1 sibling, 1 reply; 46+ messages in thread
From: Zbigniew Jędrzejewski-Szmek @ 2012-02-16  9:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Michael J Gruber, pclouds

On 02/15/2012 06:12 PM, Junio C Hamano wrote:
> Zbigniew Jędrzejewski-Szmek<zbyszek@in.waw.pl>  writes:
>
>> Eleven tests for various combinations of a long filename and/or big
>> change count and ways to specify widths for diff --stat.
>> ---
>
> Sign-off?

> Hrm, this does not seem to pass, making the result of applying [1/3] fail;
> I see that the elided name is shown much shorter than the above expects.

Hi,

I'm sorry for not properly testing the patch with tests. I somehow 
convinced myself that the tests pass. This whole series needs more work, 
even after squashing in your two patches. I'll send a new series, but 
probably not today. (I'll try to remember the sign-off too, next time).
--
Zbyszek

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts
  2012-02-16  9:57                         ` Zbigniew Jędrzejewski-Szmek
@ 2012-02-16 20:01                           ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2012-02-16 20:01 UTC (permalink / raw)
  To: Zbigniew Jędrzejewski-Szmek; +Cc: git, Michael J Gruber, pclouds

Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> writes:

> On 02/15/2012 06:12 PM, Junio C Hamano wrote:
>> Zbigniew Jędrzejewski-Szmek<zbyszek@in.waw.pl>  writes:
>>
>>> Eleven tests for various combinations of a long filename and/or big
>>> change count and ways to specify widths for diff --stat.
>>> ---
>>
>> Sign-off?
>
>> Hrm, this does not seem to pass, making the result of applying [1/3] fail;
>> I see that the elided name is shown much shorter than the above expects.
>
> Hi,
>
> I'm sorry for not properly testing the patch with tests. I somehow
> convinced myself that the tests pass. This whole series needs more
> work, even after squashing in your two patches.

It is nothing to be sorry about if a series needs more polishing; that is
what the review discussions are for.

I've queued the series after restructuring it, and merged except for [3/3]
to 'pu', which conflicts too heavily with the nd/diffstat-gramnum topic
that is already in 'master'.  I'd say we should concentrate on your first
two patches without the "num-width" stuff and get them in first, and then
later consider if rerolling the [3/3] patch is worth it after the dust
settles.

Thanks.

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2012-02-16 20:01 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-09 23:58 (unknown), Zbigniew Jędrzejewski-Szmek
2012-02-09 23:58 ` [PATCH 1/4] Move git_version_string to help.c in preparation for diff changes Zbigniew Jędrzejewski-Szmek
2012-02-10  0:46   ` Junio C Hamano
2012-02-09 23:58 ` [PATCH 2/4] help.c: make term_columns() cached and export it Zbigniew Jędrzejewski-Szmek
2012-02-10  0:50   ` Junio C Hamano
2012-02-09 23:58 ` [PATCH 3/4] diff --stat: use the real terminal width Zbigniew Jędrzejewski-Szmek
2012-02-10  0:54   ` Junio C Hamano
2012-02-10  6:15   ` Nguyen Thai Ngoc Duy
2012-02-10 11:25     ` Zbigniew Jędrzejewski-Szmek
2012-02-10 13:00       ` Nguyen Thai Ngoc Duy
2012-02-10 16:39       ` [PATCH 0/3 v2] " Zbigniew Jędrzejewski-Szmek
2012-02-10 16:39         ` [PATCH 1/3] Move git_version_string to help.c before diff changes Zbigniew Jędrzejewski-Szmek
2012-02-10 17:58           ` Junio C Hamano
2012-02-10 16:39         ` [PATCH 2/3] help.c: make term_columns() cached and export it Zbigniew Jędrzejewski-Szmek
2012-02-11  4:36           ` Nguyen Thai Ngoc Duy
2012-02-11 10:49             ` Zbigniew Jędrzejewski-Szmek
2012-02-12  9:40               ` Junio C Hamano
2012-02-12 14:12                 ` [PATCH 1/2] Save terminal width before setting up pager and export term_columns() Zbigniew Jędrzejewski-Szmek
2012-02-13 23:00                   ` Junio C Hamano
2012-02-14 11:44                   ` Nguyen Thai Ngoc Duy
2012-02-14 11:53                     ` Zbigniew Jędrzejewski-Szmek
2012-02-12 14:16                 ` [PATCH 2/2] Rename lineno_width to decimal_width and export it Zbigniew Jędrzejewski-Szmek
2012-02-13 23:29                   ` Junio C Hamano
2012-02-14 12:24                     ` [PATCH v2] make lineno_width() from blame reusable for others Zbigniew Jędrzejewski-Szmek
2012-02-10 16:39         ` [PATCH 3/3] diff --stat: use the real terminal width Zbigniew Jędrzejewski-Szmek
2012-02-10 18:24         ` [PATCH 0/3 v2] " Junio C Hamano
2012-02-12 14:30           ` [PATCH v3] diff --stat: use the full " Zbigniew Jędrzejewski-Szmek
2012-02-14  1:08             ` Junio C Hamano
2012-02-14 23:45               ` [PATCH 1/3 v4] " Zbigniew Jędrzejewski-Szmek
2012-02-14 23:45                 ` [PATCH 2/3 v4] diff --stat: better alignment for binary files Zbigniew Jędrzejewski-Szmek
2012-02-14 23:45                 ` [PATCH 3/3 v4] Update diff --stat output in tests and tutorial Zbigniew Jędrzejewski-Szmek
2012-02-15  1:21                   ` Junio C Hamano
2012-02-15 11:03                     ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big change counts Zbigniew Jędrzejewski-Szmek
2012-02-15 11:03                       ` [PATCH 2/3 v5] diff --stat: use the full terminal width Zbigniew Jędrzejewski-Szmek
2012-02-15 18:07                         ` Junio C Hamano
2012-02-15 11:03                       ` [PATCH 3/3 v5] diff --stat: use less columns for change counts Zbigniew Jędrzejewski-Szmek
2012-02-15 12:12                         ` Nguyen Thai Ngoc Duy
2012-02-15 17:12                       ` [PATCH 1/3 v5] diff --stat: tests for long filenames and big " Junio C Hamano
2012-02-15 17:33                         ` Junio C Hamano
2012-02-16  9:57                         ` Zbigniew Jędrzejewski-Szmek
2012-02-16 20:01                           ` Junio C Hamano
2012-02-15  0:07                 ` [PATCH 1/3 v4] diff --stat: use the full terminal width Junio C Hamano
2012-02-15  1:18                 ` Junio C Hamano
2012-02-15  7:39                 ` Johannes Sixt
2012-02-09 23:58 ` [PATCH 4/4] diff --stat: use most of the space for file names Zbigniew Jędrzejewski-Szmek
2012-02-10  0:55   ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.