Git development
 help / color / mirror / Atom feed
* [PATCH v3 2/2] find_pack_entry(): do not keep packed_git pointer locally
From: Nguyễn Thái Ngọc Duy @ 2012-02-01 13:48 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nicolas Pitre,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <1328104135-475-1-git-send-email-pclouds@gmail.com>

Commit f7c22cc (always start looking up objects in the last used pack
first - 2007-05-30) introduce a static packed_git* pointer as an
optimization.  The kept pointer however may become invalid if
free_pack_by_name() happens to free that particular pack.

Current code base does not access packs after calling
free_pack_by_name() so it should not be a problem. Anyway, move the
pointer out so that free_pack_by_name() can reset it to avoid running
into troubles in future.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Since Junio's already done the hard work. It'd be silly of me not to
 take advantage and credit for free :)

 The new loop looks much better.

 sha1_file.c |   27 +++++++++++++--------------
 1 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index ff5bf42..ebe77b3 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -54,6 +54,8 @@ static struct cached_object empty_tree = {
 	0
 };
 
+static struct packed_git *last_found_pack;
+
 static struct cached_object *find_cached_object(const unsigned char *sha1)
 {
 	int i;
@@ -720,6 +722,8 @@ void free_pack_by_name(const char *pack_name)
 			close_pack_index(p);
 			free(p->bad_object_sha1);
 			*pp = p->next;
+			if (last_found_pack == p)
+				last_found_pack = NULL;
 			free(p);
 			return;
 		}
@@ -2044,27 +2048,22 @@ static int find_pack_entry_1(const unsigned char *sha1,
 
 static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
 {
-	static struct packed_git *last_found = (void *)1;
 	struct packed_git *p;
 
 	prepare_packed_git();
 	if (!packed_git)
 		return 0;
-	p = (last_found == (void *)1) ? packed_git : last_found;
 
-	do {
-		if (find_pack_entry_1(sha1, p, e)) {
-			last_found = p;
-			return 1;
-		}
+	if (last_found_pack && find_pack_entry_1(sha1, last_found_pack, e))
+		return 1;
 
-		if (p == last_found)
-			p = packed_git;
-		else
-			p = p->next;
-		if (p == last_found)
-			p = p->next;
-	} while (p);
+	for (p = packed_git; p; p = p->next) {
+		if (p == last_found_pack || !find_pack_entry_1(sha1, p, e))
+			continue;
+
+		last_found_pack = p;
+		return 1;
+	}
 	return 0;
 }
 
-- 
1.7.8.36.g69ee2

^ permalink raw reply related

* [PATCH v3 1/2] Factor find_pack_entry()'s core out
From: Nguyễn Thái Ngọc Duy @ 2012-02-01 13:48 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Nicolas Pitre,
	Nguyễn Thái Ngọc Duy
In-Reply-To: <1328010239-29669-1-git-send-email-pclouds@gmail.com>


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 sha1_file.c |   59 +++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 88f2151..ff5bf42 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2010,11 +2010,42 @@ int is_pack_valid(struct packed_git *p)
 	return !open_packed_git(p);
 }
 
+static int find_pack_entry_1(const unsigned char *sha1,
+			     struct packed_git *p, struct pack_entry *e)
+{
+	off_t offset;
+	if (p->num_bad_objects) {
+		unsigned i;
+		for (i = 0; i < p->num_bad_objects; i++)
+			if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
+				return 0;
+	}
+
+	offset = find_pack_entry_one(sha1, p);
+	if (!offset)
+		return 0;
+
+	/*
+	 * We are about to tell the caller where they can locate the
+	 * requested object.  We better make sure the packfile is
+	 * still here and can be accessed before supplying that
+	 * answer, as it may have been deleted since the index was
+	 * loaded!
+	 */
+	if (!is_pack_valid(p)) {
+		warning("packfile %s cannot be accessed", p->pack_name);
+		return 0;
+	}
+	e->offset = offset;
+	e->p = p;
+	hashcpy(e->sha1, sha1);
+	return 1;
+}
+
 static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
 {
 	static struct packed_git *last_found = (void *)1;
 	struct packed_git *p;
-	off_t offset;
 
 	prepare_packed_git();
 	if (!packed_git)
@@ -2022,35 +2053,11 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
 	p = (last_found == (void *)1) ? packed_git : last_found;
 
 	do {
-		if (p->num_bad_objects) {
-			unsigned i;
-			for (i = 0; i < p->num_bad_objects; i++)
-				if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
-					goto next;
-		}
-
-		offset = find_pack_entry_one(sha1, p);
-		if (offset) {
-			/*
-			 * We are about to tell the caller where they can
-			 * locate the requested object.  We better make
-			 * sure the packfile is still here and can be
-			 * accessed before supplying that answer, as
-			 * it may have been deleted since the index
-			 * was loaded!
-			 */
-			if (!is_pack_valid(p)) {
-				warning("packfile %s cannot be accessed", p->pack_name);
-				goto next;
-			}
-			e->offset = offset;
-			e->p = p;
-			hashcpy(e->sha1, sha1);
+		if (find_pack_entry_1(sha1, p, e)) {
 			last_found = p;
 			return 1;
 		}
 
-		next:
 		if (p == last_found)
 			p = packed_git;
 		else
-- 
1.7.8.36.g69ee2

^ permalink raw reply related

* Re: [PATCH] gitk: make "git describe" output clickable, too
From: Jim Meyering @ 2012-02-01 13:17 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Paul Mackerras, git list
In-Reply-To: <7v62hl4llk.fsf@alter.siamese.dyndns.org>

Junio C Hamano wrote:
> Jim Meyering <jim@meyering.net> writes:
>
>> I noticed that automake's contribution guidelines suggest using
>> "git describe" output in commit logs to reference previous commits.
>> By contrast, in coreutils, I had acquired the habit of using a bare SHA1
>> prefix (8 hex digits), since gitk creates clickable links for that, and
>> not for "git describe" output.
>>
>> I prefer the readability of the full "git describe" output, yet want to
>> retain the gitk links, so wrote the following that renders as clickable
>> not just SHA1-like strings, but also an SHA1-like string that is
>> prefixed by "-g".
>>
>> Signed-off-by: Jim Meyering <meyering@redhat.com>
>> ---
>> This is relative to master.
>> Think of this as mere proof-of-concept:
>
> Paul, I think this makes tons of sense. Comments?

Thanks for the feedback, Junio.

>> Ideally, the string preceding the -g would be used to disambiguate
>> the SHA1 prefix, but that would require more code.
>>
>> I confess that I haven't looked to see if documentation needs
>> to be updated or if this would merit test suite additions.
>>
>>  gitk-git/gitk |    6 +++++-
>>  1 files changed, 5 insertions(+), 1 deletions(-)
>>
>> diff --git a/gitk-git/gitk b/gitk-git/gitk
>> index 4cde0c4..f8eb613 100755
>> --- a/gitk-git/gitk
>> +++ b/gitk-git/gitk
>> @@ -6688,7 +6688,7 @@ proc appendwithlinks {text tags} {
>>
>>      set start [$ctext index "end - 1c"]
>>      $ctext insert end $text $tags
>> -    set links [regexp -indices -all -inline {\m[0-9a-f]{6,40}\M} $text]
>> +    set links [regexp -indices -all -inline {(?:\m|-g)[0-9a-f]{6,40}\M} $text]
>>      foreach l $links {
>>  	set s [lindex $l 0]
>>  	set e [lindex $l 1]
>> @@ -6704,6 +6704,10 @@ proc appendwithlinks {text tags} {
>>  proc setlink {id lk} {
>>      global curview ctext pendinglinks
>>
>> +    if {[string range $id 0 1] eq "-g"} {
>> +      set id [string range $id 2 end]
>> +    }
>> +
>>      set known 0
>>      if {[string length $id] < 40} {
>>  	set matches [longid $id]
>> --
>> 1.7.8.163.g9859a

^ permalink raw reply

* [PATCH v2] Use correct grammar in diffstat summary line
From: Nguyễn Thái Ngọc Duy @ 2012-02-01 12:55 UTC (permalink / raw)
  To: git
  Cc: Thomas Dickey, Junio C Hamano, Jonathan Nieder,
	Ævar Arnfjörð, Frederik Schwarzer, Brandon Casey,
	dickey, Nguyễn Thái Ngọc Duy
In-Reply-To: <1328019840-6168-1-git-send-email-pclouds@gmail.com>

"git diff --stat" and "git apply --stat" now learn to print the line
"%d files changed, %d insertions(+), %d deletions(-)" in singular form
whenever applicable. "0 insertions" and "0 deletions" are also omitted
unless they are both zero.

Also make this line translatable.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Second try. Make it unconditionally (I'd still rather have no changes
 when LANG=C). Also omit "0 operations", although I keep "%d files
 changed, 0 insertions(+), 0 deletions(-)" for binary diff.

 In Vietnamese, the summary line is "thay đổi 68 tập tin, thêm(+) 163,
 xoá(-) 116". Lovely. Perhaps I'll translate git into Vietnamese after
 all :)

 And this patch's diffstat looks just scary due to test suite's updates.

 builtin/apply.c                                    |    3 +-
 diff.c                                             |   53 ++++++++++++++++++--
 diff.h                                             |    3 +
 t/t0023-crlf-am.sh                                 |    2 +-
 t/t1200-tutorial.sh                                |    2 +-
 t/t3300-funny-names.sh                             |    2 +-
 t/t3508-cherry-pick-many-commits.sh                |   12 ++--
 t/t3903-stash.sh                                   |    4 +-
 ...ff-tree_--cc_--patch-with-stat_--summary_master |    2 +-
 ...diff-tree_--cc_--patch-with-stat_--summary_side |    2 +-
 .../diff.diff-tree_--cc_--patch-with-stat_master   |    2 +-
 .../diff.diff-tree_--cc_--stat_--summary_master    |    2 +-
 t/t4013/diff.diff-tree_--cc_--stat_--summary_side  |    2 +-
 t/t4013/diff.diff-tree_--cc_--stat_master          |    2 +-
 ...pretty=oneline_--root_--patch-with-stat_initial |    2 +-
 .../diff.diff-tree_--pretty_--patch-with-stat_side |    2 +-
 ...-tree_--pretty_--root_--patch-with-stat_initial |    2 +-
 ...f-tree_--pretty_--root_--stat_--summary_initial |    2 +-
 .../diff.diff-tree_--pretty_--root_--stat_initial  |    2 +-
 ...diff.diff-tree_--root_--patch-with-stat_initial |    2 +-
 t/t4013/diff.diff-tree_-c_--stat_--summary_master  |    2 +-
 t/t4013/diff.diff-tree_-c_--stat_--summary_side    |    2 +-
 t/t4013/diff.diff-tree_-c_--stat_master            |    2 +-
 .../diff.diff_--patch-with-stat_-r_initial..side   |    2 +-
 t/t4013/diff.diff_--patch-with-stat_initial..side  |    2 +-
 t/t4013/diff.diff_--stat_initial..side             |    2 +-
 t/t4013/diff.diff_-r_--stat_initial..side          |    2 +-
 ..._--attach_--stdout_--suffix=.diff_initial..side |    2 +-
 ....format-patch_--attach_--stdout_initial..master |    4 +-
 ...format-patch_--attach_--stdout_initial..master^ |    2 +-
 ...ff.format-patch_--attach_--stdout_initial..side |    2 +-
 ...nline_--stdout_--numbered-files_initial..master |    4 +-
 ...tdout_--subject-prefix=TESTCASE_initial..master |    4 +-
 ....format-patch_--inline_--stdout_initial..master |    4 +-
 ...format-patch_--inline_--stdout_initial..master^ |    2 +-
 ...ff.format-patch_--inline_--stdout_initial..side |    2 +-
 ...tch_--stdout_--cover-letter_-n_initial..master^ |    2 +-
 ...at-patch_--stdout_--no-numbered_initial..master |    4 +-
 ...ormat-patch_--stdout_--numbered_initial..master |    4 +-
 t/t4013/diff.format-patch_--stdout_initial..master |    4 +-
 .../diff.format-patch_--stdout_initial..master^    |    2 +-
 t/t4013/diff.format-patch_--stdout_initial..side   |    2 +-
 ....log_--patch-with-stat_--summary_master_--_dir_ |    6 +-
 t/t4013/diff.log_--patch-with-stat_master          |    4 +-
 t/t4013/diff.log_--patch-with-stat_master_--_dir_  |    6 +-
 ..._--root_--cc_--patch-with-stat_--summary_master |    8 ++--
 ...f.log_--root_--patch-with-stat_--summary_master |    6 +-
 t/t4013/diff.log_--root_--patch-with-stat_master   |    6 +-
 ...og_--root_-c_--patch-with-stat_--summary_master |    8 ++--
 t/t4013/diff.show_--patch-with-stat_--summary_side |    2 +-
 t/t4013/diff.show_--patch-with-stat_side           |    2 +-
 t/t4013/diff.show_--stat_--summary_side            |    2 +-
 t/t4013/diff.show_--stat_side                      |    2 +-
 ...nged_--patch-with-stat_--summary_master_--_dir_ |    6 +-
 t/t4013/diff.whatchanged_--patch-with-stat_master  |    4 +-
 ...ff.whatchanged_--patch-with-stat_master_--_dir_ |    6 +-
 ..._--root_--cc_--patch-with-stat_--summary_master |    8 ++--
 ...anged_--root_--patch-with-stat_--summary_master |    6 +-
 ...iff.whatchanged_--root_--patch-with-stat_master |    6 +-
 ...ed_--root_-c_--patch-with-stat_--summary_master |    8 ++--
 t/t4014-format-patch.sh                            |    2 +-
 t/t4030-diff-textconv.sh                           |    2 +-
 t/t4045-diff-relative.sh                           |    2 +-
 t/t4049-diff-stat-count.sh                         |    2 +-
 t/t4100/t-apply-8.expect                           |    2 +-
 t/t4100/t-apply-9.expect                           |    2 +-
 t/t5150-request-pull.sh                            |    2 +-
 t/t7602-merge-octopus-many.sh                      |    6 +-
 68 files changed, 163 insertions(+), 116 deletions(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index c24dc54..389898f 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -14,6 +14,7 @@
 #include "builtin.h"
 #include "string-list.h"
 #include "dir.h"
+#include "diff.h"
 #include "parse-options.h"
 
 /*
@@ -3241,7 +3242,7 @@ static void stat_patch_list(struct patch *patch)
 		show_stats(patch);
 	}
 
-	printf(" %d files changed, %d insertions(+), %d deletions(-)\n", files, adds, dels);
+	print_stat_summary(stdout, files, adds, dels);
 }
 
 static void numstat_patch_list(struct patch *patch)
diff --git a/diff.c b/diff.c
index 7e15426..5c31b36 100644
--- a/diff.c
+++ b/diff.c
@@ -1322,6 +1322,52 @@ static void fill_print_name(struct diffstat_file *file)
 	file->print_name = pname;
 }
 
+int print_stat_summary(FILE *fp, int files, int insertions, int deletions)
+{
+	struct strbuf sb = STRBUF_INIT;
+	int ret;
+
+	if (!files) {
+		assert(insertions == 0 && deletions == 0);
+		return fputs(_(" no changes\n"), fp);
+	}
+
+	strbuf_addf(&sb,
+		    ngettext(" %d file changed", " %d files changed",
+			     files),
+		    files);
+
+	/*
+	 * For binary diff, the caller may want to print "x files
+	 * changed" with insertions == 0 && deletions == 0. Not
+	 * omitting "0 insertions(+), 0 deletions(-)" in this case is
+	 * probably less confusing (i.e skip over "2 files changed but
+	 * nothing about added/removed lines? Is this a bug in
+	 * git??").
+	 */
+	if (insertions || deletions == 0) {
+		strbuf_addf(&sb,
+			    /* TRANSLATORS: "+" in (+) is a line
+			       addition marker, do not translate it */
+			    ngettext(", %d insertion(+)", ", %d insertions(+)",
+				     insertions),
+			    insertions);
+	}
+
+	if (deletions || insertions == 0) {
+		strbuf_addf(&sb,
+			    /* TRANSLATORS: "-" in (-) is a line
+			       removal marker, do not translate it */
+			    ngettext(", %d deletion(-)", ", %d deletions(-)",
+				     deletions),
+			    deletions);
+	}
+	strbuf_addch(&sb, '\n');
+	ret = fputs(sb.buf, fp);
+	strbuf_release(&sb);
+	return ret;
+}
+
 static void show_stats(struct diffstat_t *data, struct diff_options *options)
 {
 	int i, len, add, del, adds = 0, dels = 0;
@@ -1475,9 +1521,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)
 		extra_shown = 1;
 	}
 	fprintf(options->file, "%s", line_prefix);
-	fprintf(options->file,
-	       " %d files changed, %d insertions(+), %d deletions(-)\n",
-	       total_files, adds, dels);
+	print_stat_summary(options->file, total_files, adds, dels);
 }
 
 static void show_shortstats(struct diffstat_t *data, struct diff_options *options)
@@ -1507,8 +1551,7 @@ static void show_shortstats(struct diffstat_t *data, struct diff_options *option
 				options->output_prefix_data);
 		fprintf(options->file, "%s", msg->buf);
 	}
-	fprintf(options->file, " %d files changed, %d insertions(+), %d deletions(-)\n",
-	       total_files, adds, dels);
+	print_stat_summary(options->file, total_files, adds, dels);
 }
 
 static void show_numstat(struct diffstat_t *data, struct diff_options *options)
diff --git a/diff.h b/diff.h
index ae71f4c..7af5f1e 100644
--- a/diff.h
+++ b/diff.h
@@ -324,4 +324,7 @@ extern struct userdiff_driver *get_textconv(struct diff_filespec *one);
 
 extern int parse_rename_score(const char **cp_p);
 
+extern int print_stat_summary(FILE *fp, int files,
+			      int insertions, int deletions);
+
 #endif /* DIFF_H */
diff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh
index aaed725..18fe27b 100755
--- a/t/t0023-crlf-am.sh
+++ b/t/t0023-crlf-am.sh
@@ -12,7 +12,7 @@ Subject: test1
 
 ---
  foo |    1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
  create mode 100644 foo
 
 diff --git a/foo b/foo
diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh
index 5e29e13..9356bea 100755
--- a/t/t1200-tutorial.sh
+++ b/t/t1200-tutorial.sh
@@ -156,7 +156,7 @@ Updating VARIABLE..VARIABLE
 FASTFORWARD (no commit created; -m option ignored)
  example |    1 +
  hello   |    1 +
- 2 files changed, 2 insertions(+), 0 deletions(-)
+ 2 files changed, 2 insertions(+)
 EOF
 
 test_expect_success 'git resolve' '
diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh
index 5e29a05..9f00ada 100755
--- a/t/t3300-funny-names.sh
+++ b/t/t3300-funny-names.sh
@@ -167,7 +167,7 @@ test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny' \
 test_expect_success TABS_IN_FILENAMES 'setup expect' '
 cat >expected <<\EOF
  "tabs\t,\" (dq) and spaces"
- 1 files changed, 0 insertions(+), 0 deletions(-)
+ 1 file changed, 0 insertions(+), 0 deletions(-)
 EOF
 '
 
diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh
index 8e09fd0..1b3a344 100755
--- a/t/t3508-cherry-pick-many-commits.sh
+++ b/t/t3508-cherry-pick-many-commits.sh
@@ -38,13 +38,13 @@ test_expect_success 'cherry-pick first..fourth works' '
 	cat <<-\EOF >expected &&
 	[master OBJID] second
 	 Author: A U Thor <author@example.com>
-	 1 files changed, 1 insertions(+), 0 deletions(-)
+	 1 file changed, 1 insertion(+)
 	[master OBJID] third
 	 Author: A U Thor <author@example.com>
-	 1 files changed, 1 insertions(+), 0 deletions(-)
+	 1 file changed, 1 insertion(+)
 	[master OBJID] fourth
 	 Author: A U Thor <author@example.com>
-	 1 files changed, 1 insertions(+), 0 deletions(-)
+	 1 file changed, 1 insertion(+)
 	EOF
 
 	git checkout -f master &&
@@ -64,15 +64,15 @@ test_expect_success 'cherry-pick --strategy resolve first..fourth works' '
 	Trying simple merge.
 	[master OBJID] second
 	 Author: A U Thor <author@example.com>
-	 1 files changed, 1 insertions(+), 0 deletions(-)
+	 1 file changed, 1 insertion(+)
 	Trying simple merge.
 	[master OBJID] third
 	 Author: A U Thor <author@example.com>
-	 1 files changed, 1 insertions(+), 0 deletions(-)
+	 1 file changed, 1 insertion(+)
 	Trying simple merge.
 	[master OBJID] fourth
 	 Author: A U Thor <author@example.com>
-	 1 files changed, 1 insertions(+), 0 deletions(-)
+	 1 file changed, 1 insertion(+)
 	EOF
 
 	git checkout -f master &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index dbe2ac1..663c60a 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -444,7 +444,7 @@ test_expect_success 'stash show - stashes on stack, stash-like argument' '
 	git reset --hard &&
 	cat >expected <<-EOF &&
 	 file |    1 +
-	 1 files changed, 1 insertions(+), 0 deletions(-)
+	 1 file changed, 1 insertion(+)
 	EOF
 	git stash show ${STASH_ID} >actual &&
 	test_cmp expected actual
@@ -482,7 +482,7 @@ test_expect_success 'stash show - no stashes on stack, stash-like argument' '
 	git reset --hard &&
 	cat >expected <<-EOF &&
 	 file |    1 +
-	 1 files changed, 1 insertions(+), 0 deletions(-)
+	 1 file changed, 1 insertion(+)
 	EOF
 	git stash show ${STASH_ID} >actual &&
 	test_cmp expected 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..2f8560c 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
@@ -2,7 +2,7 @@ $ git diff-tree --cc --patch-with-stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --cc dir/sub
 index cead32e,7289e35..992913c
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..72e03c1 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
@@ -3,7 +3,7 @@ c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
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..8b357d9 100644
--- a/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--patch-with-stat_master
@@ -2,7 +2,7 @@ $ git diff-tree --cc --patch-with-stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --cc dir/sub
 index cead32e,7289e35..992913c
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
index cc6eb3b..e0568d6 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_master
@@ -2,5 +2,5 @@ $ git diff-tree --cc --stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 $
diff --git a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
index 50362be..5afc823 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_--cc_--stat_--summary_side
@@ -3,6 +3,6 @@ c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..f48367a 100644
--- a/t/t4013/diff.diff-tree_--cc_--stat_master
+++ b/t/t4013/diff.diff-tree_--cc_--stat_master
@@ -2,5 +2,5 @@ $ git diff-tree --cc --stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 $
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..590864c 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
@@ -3,7 +3,7 @@ $ git diff-tree --pretty=oneline --root --patch-with-stat initial
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 new file mode 100644
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..e05e778 100644
--- a/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
+++ b/t/t4013/diff.diff-tree_--pretty_--patch-with-stat_side
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
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..0e2c956 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
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 new file mode 100644
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..384fa44 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_--summary_initial
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
  create mode 100644 dir/sub
  create mode 100644 file0
  create mode 100644 file2
diff --git a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
index 9154aa4..10384a8 100644
--- a/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
+++ b/t/t4013/diff.diff-tree_--pretty_--root_--stat_initial
@@ -8,5 +8,5 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
 $
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..f57062e 100644
--- a/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
+++ b/t/t4013/diff.diff-tree_--root_--patch-with-stat_initial
@@ -3,7 +3,7 @@ $ git diff-tree --root --patch-with-stat initial
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 new file mode 100644
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_master b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
index ac9f641..7088683 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_master
@@ -2,5 +2,5 @@ $ git diff-tree -c --stat --summary master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 $
diff --git a/t/t4013/diff.diff-tree_-c_--stat_--summary_side b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
index 2afcca1..ef216ab 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_--summary_side
+++ b/t/t4013/diff.diff-tree_-c_--stat_--summary_side
@@ -3,6 +3,6 @@ c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..ad19f10 100644
--- a/t/t4013/diff.diff-tree_-c_--stat_master
+++ b/t/t4013/diff.diff-tree_-c_--stat_master
@@ -2,5 +2,5 @@ $ git diff-tree -c --stat master
 59d314ad6f356dd08601a4cd5e530381da3e3c64
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 $
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..ddad917 100644
--- a/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_-r_initial..side
@@ -2,7 +2,7 @@ $ git diff --patch-with-stat -r initial..side
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.diff_--patch-with-stat_initial..side b/t/t4013/diff.diff_--patch-with-stat_initial..side
index 8b50629..bdbd114 100644
--- a/t/t4013/diff.diff_--patch-with-stat_initial..side
+++ b/t/t4013/diff.diff_--patch-with-stat_initial..side
@@ -2,7 +2,7 @@ $ git diff --patch-with-stat initial..side
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.diff_--stat_initial..side b/t/t4013/diff.diff_--stat_initial..side
index 0517b5d..6d08f3d 100644
--- a/t/t4013/diff.diff_--stat_initial..side
+++ b/t/t4013/diff.diff_--stat_initial..side
@@ -2,5 +2,5 @@ $ git diff --stat initial..side
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 $
diff --git a/t/t4013/diff.diff_-r_--stat_initial..side b/t/t4013/diff.diff_-r_--stat_initial..side
index 245220d..2ddb254 100644
--- a/t/t4013/diff.diff_-r_--stat_initial..side
+++ b/t/t4013/diff.diff_-r_--stat_initial..side
@@ -2,5 +2,5 @@ $ git diff -r --stat initial..side
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 $
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..3cab049 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
@@ -15,7 +15,7 @@ Content-Transfer-Encoding: 8bit
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..564a4d3 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 
@@ -124,7 +124,7 @@ Content-Transfer-Encoding: 8bit
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..4f28460 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..master^
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  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..b10cc2e 100644
--- a/t/t4013/diff.format-patch_--attach_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--attach_--stdout_initial..side
@@ -15,7 +15,7 @@ Content-Transfer-Encoding: 8bit
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..a976a8a 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
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 
@@ -124,7 +124,7 @@ Content-Transfer-Encoding: 8bit
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..b4fd664 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
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 
@@ -124,7 +124,7 @@ Content-Transfer-Encoding: 8bit
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..0d31036 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 
@@ -124,7 +124,7 @@ Content-Transfer-Encoding: 8bit
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..18d4714 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..master^
@@ -75,7 +75,7 @@ Content-Transfer-Encoding: 8bit
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 
diff --git a/t/t4013/diff.format-patch_--inline_--stdout_initial..side b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
index 67633d4..3572f20 100644
--- a/t/t4013/diff.format-patch_--inline_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--inline_--stdout_initial..side
@@ -15,7 +15,7 @@ Content-Transfer-Encoding: 8bit
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  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..54cdcda 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^
@@ -75,7 +75,7 @@ Subject: [DIFFERENT_PREFIX 2/2] Third
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
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..23194eb 100644
--- a/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--no-numbered_initial..master
@@ -53,7 +53,7 @@ Subject: [PATCH] Third
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -88,7 +88,7 @@ Subject: [PATCH] Side
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
index 8e67dbf..78f1a80 100644
--- a/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_--numbered_initial..master
@@ -53,7 +53,7 @@ Subject: [PATCH 2/3] Third
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -88,7 +88,7 @@ Subject: [PATCH 3/3] Side
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master b/t/t4013/diff.format-patch_--stdout_initial..master
index 7b89978..a3dab7f 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master
+++ b/t/t4013/diff.format-patch_--stdout_initial..master
@@ -53,7 +53,7 @@ Subject: [PATCH 2/3] Third
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -88,7 +88,7 @@ Subject: [PATCH 3/3] Side
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_initial..master^ b/t/t4013/diff.format-patch_--stdout_initial..master^
index b7f9725..39f4a3f 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..master^
+++ b/t/t4013/diff.format-patch_--stdout_initial..master^
@@ -53,7 +53,7 @@ Subject: [PATCH 2/2] Third
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.format-patch_--stdout_initial..side b/t/t4013/diff.format-patch_--stdout_initial..side
index e765088..8810920 100644
--- a/t/t4013/diff.format-patch_--stdout_initial..side
+++ b/t/t4013/diff.format-patch_--stdout_initial..side
@@ -8,7 +8,7 @@ Subject: [PATCH] Side
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
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..4085bbd 100644
--- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
@@ -13,7 +13,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
     Side
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
@@ -32,7 +32,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
     Third
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 8422d40..cead32e 100644
@@ -54,7 +54,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     This is the second commit.
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..8422d40 100644
diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master
index 14595a6..4586279 100644
--- a/t/t4013/diff.log_--patch-with-stat_master
+++ b/t/t4013/diff.log_--patch-with-stat_master
@@ -15,7 +15,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
@@ -56,7 +56,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 8422d40..cead32e 100644
diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
index 5a4e727..6e172cf 100644
--- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
@@ -13,7 +13,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
     Side
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
@@ -32,7 +32,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
     Third
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 8422d40..cead32e 100644
@@ -54,7 +54,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     This is the second commit.
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..8422d40 100644
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..48b0d4b 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
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --cc dir/sub
 index cead32e,7289e35..992913c
@@ -47,7 +47,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
@@ -89,7 +89,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -165,7 +165,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
  create mode 100644 dir/sub
  create mode 100644 file0
  create mode 100644 file2
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..f9dc512 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
@@ -15,7 +15,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
@@ -57,7 +57,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -133,7 +133,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
  create mode 100644 dir/sub
  create mode 100644 file0
  create mode 100644 file2
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master
index 5f0c98f..0807ece 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_master
@@ -15,7 +15,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
@@ -56,7 +56,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 8422d40..cead32e 100644
@@ -130,7 +130,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 new file mode 100644
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..84f5ef6 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
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --combined dir/sub
 index cead32e,7289e35..992913c
@@ -47,7 +47,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
@@ -89,7 +89,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -165,7 +165,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
  create mode 100644 dir/sub
  create mode 100644 file0
  create mode 100644 file2
diff --git a/t/t4013/diff.show_--patch-with-stat_--summary_side b/t/t4013/diff.show_--patch-with-stat_--summary_side
index 377f2b7..e60384d 100644
--- a/t/t4013/diff.show_--patch-with-stat_--summary_side
+++ b/t/t4013/diff.show_--patch-with-stat_--summary_side
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
diff --git a/t/t4013/diff.show_--patch-with-stat_side b/t/t4013/diff.show_--patch-with-stat_side
index fb14c53..a3a3255 100644
--- a/t/t4013/diff.show_--patch-with-stat_side
+++ b/t/t4013/diff.show_--patch-with-stat_side
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
diff --git a/t/t4013/diff.show_--stat_--summary_side b/t/t4013/diff.show_--stat_--summary_side
index 5bd5977..d16f464 100644
--- a/t/t4013/diff.show_--stat_--summary_side
+++ b/t/t4013/diff.show_--stat_--summary_side
@@ -8,6 +8,6 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 $
diff --git a/t/t4013/diff.show_--stat_side b/t/t4013/diff.show_--stat_side
index 3b22327..6300c05 100644
--- a/t/t4013/diff.show_--stat_side
+++ b/t/t4013/diff.show_--stat_side
@@ -8,5 +8,5 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 $
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..16ae543 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_--summary_master_--_dir_
@@ -6,7 +6,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
     Side
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
@@ -25,7 +25,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
     Third
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 8422d40..cead32e 100644
@@ -47,7 +47,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     This is the second commit.
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..8422d40 100644
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master b/t/t4013/diff.whatchanged_--patch-with-stat_master
index 1e1bbe1..f3e45ec 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
@@ -49,7 +49,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 8422d40..cead32e 100644
diff --git a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
index 13789f1..c77f0bc 100644
--- a/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.whatchanged_--patch-with-stat_master_--_dir_
@@ -6,7 +6,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
     Side
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
@@ -25,7 +25,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
     Third
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 8422d40..cead32e 100644
@@ -47,7 +47,7 @@ Date:   Mon Jun 26 00:01:00 2006 +0000
     This is the second commit.
 ---
  dir/sub |    2 ++
- 1 files changed, 2 insertions(+), 0 deletions(-)
+ 1 file changed, 2 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..8422d40 100644
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..8d03efe 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
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --cc dir/sub
 index cead32e,7289e35..992913c
@@ -47,7 +47,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
@@ -89,7 +89,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -165,7 +165,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
  create mode 100644 dir/sub
  create mode 100644 file0
  create mode 100644 file2
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..1874d06 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_master
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
@@ -50,7 +50,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -126,7 +126,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
  create mode 100644 dir/sub
  create mode 100644 file0
  create mode 100644 file2
diff --git a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
index 9b0349c..5211ff2 100644
--- a/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
+++ b/t/t4013/diff.whatchanged_--root_--patch-with-stat_master
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 35d242b..7289e35 100644
@@ -49,7 +49,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 index 8422d40..cead32e 100644
@@ -123,7 +123,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
 
 diff --git a/dir/sub b/dir/sub
 new file mode 100644
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..ad30245 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
@@ -8,7 +8,7 @@ Date:   Mon Jun 26 00:04:00 2006 +0000
 
  dir/sub |    2 ++
  file0   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
 
 diff --combined dir/sub
 index cead32e,7289e35..992913c
@@ -47,7 +47,7 @@ Date:   Mon Jun 26 00:03:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file3   |    4 ++++
- 3 files changed, 9 insertions(+), 0 deletions(-)
+ 3 files changed, 9 insertions(+)
  create mode 100644 file3
 
 diff --git a/dir/sub b/dir/sub
@@ -89,7 +89,7 @@ Date:   Mon Jun 26 00:02:00 2006 +0000
 ---
  dir/sub |    2 ++
  file1   |    3 +++
- 2 files changed, 5 insertions(+), 0 deletions(-)
+ 2 files changed, 5 insertions(+)
  create mode 100644 file1
 
 diff --git a/dir/sub b/dir/sub
@@ -165,7 +165,7 @@ Date:   Mon Jun 26 00:00:00 2006 +0000
  dir/sub |    2 ++
  file0   |    3 +++
  file2   |    3 +++
- 3 files changed, 8 insertions(+), 0 deletions(-)
+ 3 files changed, 8 insertions(+)
  create mode 100644 dir/sub
  create mode 100644 file0
  create mode 100644 file2
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 6797512..7dfe716 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -520,7 +520,7 @@ test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 cat > expect << EOF
 ---
  file |   16 ++++++++++++++++
- 1 files changed, 16 insertions(+), 0 deletions(-)
+ 1 file changed, 16 insertions(+)
 
 diff --git a/file b/file
 index 40f36c6..2dc5c23 100644
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index 88c5619..4ac162c 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -86,7 +86,7 @@ test_expect_success 'status -v produces text' '
 
 cat >expect.stat <<'EOF'
  file |  Bin 2 -> 4 bytes
- 1 files changed, 0 insertions(+), 0 deletions(-)
+ 1 file changed, 0 insertions(+), 0 deletions(-)
 EOF
 test_expect_success 'diffstat does not run textconv' '
 	echo file diff=fail >.gitattributes &&
diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh
index 8a3c63b..bd119be 100755
--- a/t/t4045-diff-relative.sh
+++ b/t/t4045-diff-relative.sh
@@ -33,7 +33,7 @@ check_stat() {
 expect=$1; shift
 cat >expected <<EOF
  $expect |    1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
 EOF
 test_expect_success "--stat $*" "
 	git diff --stat $* HEAD^ >actual &&
diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh
index 641e70d..a6d1887 100755
--- a/t/t4049-diff-stat-count.sh
+++ b/t/t4049-diff-stat-count.sh
@@ -16,7 +16,7 @@ test_expect_success setup '
 	cat >expect <<-\EOF
 	 a |    1 +
 	 b |    1 +
-	 2 files changed, 2 insertions(+), 0 deletions(-)
+	 2 files changed, 2 insertions(+)
 	EOF
 	git diff --stat --stat-count=2 >actual &&
 	test_cmp expect actual
diff --git a/t/t4100/t-apply-8.expect b/t/t4100/t-apply-8.expect
index eef7f2e..55a55c3 100644
--- a/t/t4100/t-apply-8.expect
+++ b/t/t4100/t-apply-8.expect
@@ -1,2 +1,2 @@
  t/t4100-apply-stat.sh |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/t/t4100/t-apply-9.expect b/t/t4100/t-apply-9.expect
index eef7f2e..55a55c3 100644
--- a/t/t4100/t-apply-9.expect
+++ b/t/t4100/t-apply-9.expect
@@ -1,2 +1,2 @@
  t/t4100-apply-stat.sh |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
+ 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index da25bc2..34c482f 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -95,7 +95,7 @@ test_expect_success 'setup: two scripts for reading pull requests' '
 	b
 	: diffstat
 	n
-	/ [0-9]* files changed/ {
+	/ [0-9]* files\? changed/ {
 		a\\
 	DIFFSTAT
 		b
diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh
index 61f36ba..5783ebf 100755
--- a/t/t7602-merge-octopus-many.sh
+++ b/t/t7602-merge-octopus-many.sh
@@ -57,7 +57,7 @@ Merge made by the 'octopus' strategy.
  c2.c |    1 +
  c3.c |    1 +
  c4.c |    1 +
- 3 files changed, 3 insertions(+), 0 deletions(-)
+ 3 files changed, 3 insertions(+)
  create mode 100644 c2.c
  create mode 100644 c3.c
  create mode 100644 c4.c
@@ -74,7 +74,7 @@ Already up-to-date with c4
 Trying simple merge with c5
 Merge made by the 'octopus' strategy.
  c5.c |    1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
+ 1 file changed, 1 insertion(+)
  create mode 100644 c5.c
 EOF
 
@@ -89,7 +89,7 @@ Trying simple merge with c2
 Merge made by the 'octopus' strategy.
  c1.c |    1 +
  c2.c |    1 +
- 2 files changed, 2 insertions(+), 0 deletions(-)
+ 2 files changed, 2 insertions(+)
  create mode 100644 c1.c
  create mode 100644 c2.c
 EOF
-- 
1.7.8.36.g69ee2

^ permalink raw reply related

* Re: [BUG] git clean -X skips a directory containing only ignored files
From: Michael Schubert @ 2012-02-01 12:18 UTC (permalink / raw)
  To: Andrew Wong; +Cc: Paul Berry, git
In-Reply-To: <4F2814D7.8030504@sohovfx.com>

On 01/31/2012 05:20 PM, Andrew Wong wrote:
> I think there were a bit of discussions on this issues just while ago too:
> http://thread.gmane.org/gmane.comp.version-control.git/188605

Thanks, missed that.

Below a patch with an update for Documentation/git-clean.txt - I'm not sure
if the issue should be described more accurate.?

-- >8 --

Subject: [PATCH] Documentation: tell about "git clean -Xd" bug

"git clean -Xd" doesn't work as expected (delete all ignored files and
untracked directories), because Git's dir subsystem is skipping
directories which both aren't explicitly ignored and don't hold any
tracked files.

Tell about this limitation in BUGS.

Signed-off-by: Michael Schubert <mschub@elegosoft.com>
---
 Documentation/git-clean.txt |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt
index 79fb984..888c07d 100644
--- a/Documentation/git-clean.txt
+++ b/Documentation/git-clean.txt
@@ -29,7 +29,8 @@ OPTIONS
 	Remove untracked directories in addition to untracked files.
 	If an untracked directory is managed by a different git
 	repository, it is not removed by default.  Use -f option twice
-	if you really want to remove such a directory.
+	if you really want to remove such a directory.  Also see BUGS
+	below.
 
 -f::
 --force::
@@ -63,6 +64,11 @@ OPTIONS
 	Remove only files ignored by git.  This may be useful to rebuild
 	everything from scratch, but keep manually created files.
 
+BUGS
+----
+'git-clean -Xd' doesn't work as expected for directories which don't hold
+any tracked files and aren't explicitly ignored either.
+
 GIT
 ---
 Part of the linkgit:git[1] suite
-- 
1.7.9.174.g356eff6

^ permalink raw reply related

* Re: What's cooking in git.git (Jan 2012, #08; Tue, 31)
From: Jakub Narebski @ 2012-02-01 12:07 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Bernhard R. Link
In-Reply-To: <7vlion3tr5.fsf@alter.siamese.dyndns.org>

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

> --------------------------------------------------
> [Cooking]
> 
> * bl/gitweb-project-filter (2012-01-31) 8 commits
>  - gitweb: Make project search respect project_filter
>  - gitweb: improve usability of projects search form
>  - gitweb: place links to parent directories in page header
>  - gitweb: show active project_filter in project_list page header
>  - gitweb: limit links to alternate forms of project_list to active project_filter
>  - gitweb: add project_filter to limit project list to a subdirectory
>  - gitweb: prepare git_get_projects_list for use outside 'forks'.
>  - gitweb: move hard coded .git suffix out of git_get_projects_list
> 
> Seems to break test 9502.

Hmmm... strange.  I have applied my patches on top of earlier version
of project_filter commits:

   - gitweb: Make project search respect project_filter
   - gitweb: Improve projects search form
   - gitweb: place links to parent directories in page header
   - gitweb: add project_filter to limit project list to a subdirectory

and all gitweb tests passes.

I will investigate.

-- 
Jakub Narebski

^ permalink raw reply

* ANNOUNCE: Git for Windows 1.7.9
From: Pat Thoyts @ 2012-02-01 11:23 UTC (permalink / raw)
  To: msysGit; +Cc: Git Mailing List

This release brings the latest release of Git to Windows users.

Pre-built installers are available from
http://code.google.com/p/msysgit/downloads/list

Further details about the Git for Windows project are at
http://code.google.com/p/msysgit/

^ permalink raw reply

* Re: [PATCH] Correct singular form in diff summary line for human interaction
From: Thomas Dickey @ 2012-02-01  9:40 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: dickey, Nguyen Thai Ngoc Duy, Jonathan Nieder, git,
	Ævar Arnfjörð, Frederik Schwarzer, Brandon Casey,
	dickey
In-Reply-To: <7vk4475k5s.fsf@alter.siamese.dyndns.org>

[-- Attachment #1: Type: text/plain, Size: 3686 bytes --]

On Tue, Jan 31, 2012 at 07:04:15PM -0800, Junio C Hamano wrote:
> Thomas Dickey <dickey@his.com> writes:
> 
> > On Wed, Feb 01, 2012 at 08:32:43AM +0700, Nguyen Thai Ngoc Duy wrote:
> >> On Wed, Feb 1, 2012 at 12:50 AM, Junio C Hamano <gitster@pobox.com> wrote:
> >> >> If there is an environment variable to say "I don't want to see
> >> >> variations on strings intended for humans", can it be spelled as
> >> >> LC_ALL=C?
> >> >
> >> >  ...
> >
> > ... diffstat (google helped find context)
> 
> When we show diffstat from "git diff --stat" (or "git apply --stat"), we
> currently do not do any singular/plural on the last line of the output
> that summarizes the graph, ending up with:
> 
> 	1 files changed, 1 insertions(+), 0 deletions(-)
> 
> when there is a single line insertion to a file and nothing else.
> 
> My recollection is that our behaviour originally came from our desire to
> be as close as what "diffstat" produces, but that does not seem to be the
> case.  I observed that the output from recent versions of "diffstat" is
> much more human friendly.  We get these, depending on the input, from
> "diffstat" version 1.53:

I added the PLURAL() macro in 1.22, in 1996/3/16, which was a few months
before Tony Nugent commented that it was being used by other people.  Since
I'd been sending patches with diffstat's since mid-1994, it's possible
that there were a few copies using the form without plurals.  But it's
been quite a while.  Also, it was in 1998/1/17 that I modified the
copyright notice (1.26) at the request of someone in the Linux group, so
I'd assume that they would have started using the newer version.

Except for later applying PLURAL to the number of files changed (which Jean
Delvare pointed out in 2005), the message construction has not changed since
then.  The insert/delete/modify parts of the message were optional as you see in
my earliest version (1.3) from 1993/10/23:

	printf("%d files changed", num_files);
	if (total_ins) printf(", %d insertions", total_ins);
	if (total_del) printf(", %d deletions", total_del);
	if (total_mod) printf(", %d modifications", total_mod);
	printf("\n");
 
>         1 file changed, 1 insertion(+)
>         1 file changed, 1 deletion(-)
> 	0 files changed
> 	2 files changed, 3 insertions(+), 1 deletion(-)
> 
> Namely, it does singular/plural correctly, and omits unnecessary "0
> deletions(-)" and "0 insertions(+)".
> 
> I was wondering if you remember what the behaviour of older versions of
> "diffstat" was, and if it was changed to be more human friendly over
> time. It is very possible that I am misremembering this and "diffstat" has
> always done the singular/plural correctly and omitted useless "0 lines".

I have back to 1.3 in my archive. I use rcshist to look for things like this.
(also, for small things like this, I have a script that pulls all versions,
with proper timestamps to make it simpler to sort the files by date).
 
> Somehow it seems hard to get hold of older versions of "diffstat", and I
> was hoping that I could get that information straight out of the current
> maintainer.

I can provide the information.

Actually a couple of weeks ago I was experimenting with rcs-fast-export, but
found that would need more work to export diffstat (I use branches a lot)
I'm using "conflict" as a test-case for the changes that I'm making to support
exporting mawk.

> Thanks for responding and sorry for the lack of context of the original
> message.

no problem - google was helpful ;-)

-- 
Thomas E. Dickey <dickey@invisible-island.net>
http://invisible-island.net
ftp://invisible-island.net

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH] Don't search files with an unset "grep" attribute
From: Conrad Irwin @ 2012-02-01  9:28 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git, Nguyen Thai Ngoc Duy, Dov Grobgeld
In-Reply-To: <20120201091009.GA20984@sigill.intra.peff.net>

On Wed, Feb 1, 2012 at 1:10 AM, Jeff King <peff@peff.net> wrote:
> On Wed, Feb 01, 2012 at 03:20:05AM -0500, Jeff King wrote:
>
> Actually, it's a little bit more complicated. I was looking at a
> slightly old version of grep.c. Since 0579f91 (grep: enable threading
> with -p and -W using lazy attribute lookup, 2011-12-12), the lookup
> happens in lots of sub-functions, and locking is required.

Heh, you just beat me to it.

> But there's more. Respecting binary attributes does mean looking up
> attributes for _every_ file. And that has a noticeable impact. My
> best-of-five for "git grep foo" on linux-2.6 went from 0.302s to 0.392s.
> Yuck.

The first time I introduced this behaviour[1], I made it conditional
on a preference — those who wanted "good" grep could set the
preference, while those who wanted "fast" grep could not. I think
that's not a good idea, though if the performance issues are
show-stoppers, I'd suggest the opposite preference (so speed-freaks
can disable the checks).

Tests from [1] included below in case they're still useful (they pass
with your change)

[1] http://article.gmane.org/gmane.comp.version-control.git/179299/match=grep
---

diff --git a/t/t7008-grep-binary.sh b/t/t7008-grep-binary.sh
index 917a264..4d94461 100755
--- a/t/t7008-grep-binary.sh
+++ b/t/t7008-grep-binary.sh
@@ -99,4 +99,23 @@ test_expect_success 'git grep y<NUL>x a' "
        test_must_fail git grep -f f a
 "

+test_expect_success 'git -c grep.binaryFiles=1 grep ina a' "
+       echo 'a diff' > .gitattributes &&
+       printf 'binaryQfile' | q_to_nul >a &&
+       echo 'a:binaryQfile' | q_to_nul >expect &&
+       git -c grep.binaryFiles=1 grep ina a > actual &&
+       rm .gitattributes &&
+       test_cmp expect actual
+"
+test_expect_success 'git -c grep.binaryFiles=1 grep tex t' "
+       echo 'text' > t &&
+       git add t &&
+       echo 't -diff' > .gitattributes &&
+       echo Binary file t matches >expect &&
+       git -c grep.binaryFiles=1 grep tex t >actual &&
+       rm .gitattributes &&
+       test_cmp expect actual
+"
+
+
 test_done

^ permalink raw reply related

* Re: [PATCH] Don't search files with an unset "grep" attribute
From: Jeff King @ 2012-02-01  9:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Conrad Irwin, git, Nguyen Thai Ngoc Duy, Dov Grobgeld
In-Reply-To: <20120201082005.GA32348@sigill.intra.peff.net>

On Wed, Feb 01, 2012 at 03:20:05AM -0500, Jeff King wrote:

> Here's the bug-fix patch. Not quite ready for inclusion, as it obviously
> needs tests and a commit message. Also, we can cache the result of the
> userdiff lookup so the funcname code doesn't have to look it up again.

Actually, it's a little bit more complicated. I was looking at a
slightly old version of grep.c. Since 0579f91 (grep: enable threading
with -p and -W using lazy attribute lookup, 2011-12-12), the lookup
happens in lots of sub-functions, and locking is required.

So this is what the patch looks like with proper locking and caching of
the looked-up driver. It's quite messy because the cached driver pointer
has to get passed around quite a bit. And I'm not sure it buys that much
in practice. The cost of attribute lookup _is_ noticeable (which I'll
discuss below), but funcname lookup only happens when we get a grep hit.
So unless you are searching for something extremely common, you're only
going to do a lookup very occasionally (compared to the load of actually
searching through the files). So all of the messiness and caching may
not be worth the effort, as I wasn't able to measure a performance gain.

But there's more. Respecting binary attributes does mean looking up
attributes for _every_ file. And that has a noticeable impact. My
best-of-five for "git grep foo" on linux-2.6 went from 0.302s to 0.392s.
Yuck.

Part of the problem, I suspect, is that the attribute lookup code is
optimized for locality. We only unwind as much of the stack as we need,
so looking at "foo/bar/baz.c" after "foo/bar/bleep.c" is much cheaper
than looking at "some/other/directory.c". But with threaded grep, that
locality is likely lost, as we are mixing up attribute requests from
different threads.

Given that binary lookup means we need every file's gitattribute, it
might be better to look them up serially at the beginning of the
program, and then pass the resulting userdiff driver to grep_buffer
along with each path.

---
diff --git a/grep.c b/grep.c
index 486230b..3ca840a 100644
--- a/grep.c
+++ b/grep.c
@@ -829,15 +829,28 @@ static inline void grep_attr_unlock(struct grep_opt *opt)
 #define grep_attr_unlock(opt)
 #endif
 
-static int match_funcname(struct grep_opt *opt, const char *name, char *bol, char *eol)
+static struct userdiff_driver *get_cached_userdiff(struct grep_opt *opt,
+						   const char *path,
+						   struct userdiff_driver **drv)
 {
-	xdemitconf_t *xecfg = opt->priv;
-	if (xecfg && !xecfg->find_func) {
-		struct userdiff_driver *drv;
+	if (!*drv) {
 		grep_attr_lock(opt);
-		drv = userdiff_find_by_path(name);
+		*drv = userdiff_find_by_path(path);
+		if (!*drv)
+			*drv = userdiff_find_by_name("default");
 		grep_attr_unlock(opt);
-		if (drv && drv->funcname.pattern) {
+	}
+	return *drv;
+}
+
+static int match_funcname(struct grep_opt *opt, const char *name,
+			  struct userdiff_driver **drv_p,
+			  char *bol, char *eol)
+{
+	xdemitconf_t *xecfg = opt->priv;
+	if (xecfg && !xecfg->find_func) {
+		struct userdiff_driver *drv = get_cached_userdiff(opt, name, drv_p);
+		if (drv->funcname.pattern) {
 			const struct userdiff_funcname *pe = &drv->funcname;
 			xdiff_set_find_func(xecfg, pe->pattern, pe->cflags);
 		} else {
@@ -859,6 +872,7 @@ static int match_funcname(struct grep_opt *opt, const char *name, char *bol, cha
 }
 
 static void show_funcname_line(struct grep_opt *opt, const char *name,
+			       struct userdiff_driver **drv_p,
 			       char *buf, char *bol, unsigned lno)
 {
 	while (bol > buf) {
@@ -871,20 +885,21 @@ static void show_funcname_line(struct grep_opt *opt, const char *name,
 		if (lno <= opt->last_shown)
 			break;
 
-		if (match_funcname(opt, name, bol, eol)) {
+		if (match_funcname(opt, name, drv_p, bol, eol)) {
 			show_line(opt, bol, eol, name, lno, '=');
 			break;
 		}
 	}
 }
 
-static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
-			     char *bol, char *end, unsigned lno)
+static void show_pre_context(struct grep_opt *opt, const char *name,
+			     struct userdiff_driver **drv_p,
+			     char *buf, char *bol, char *end, unsigned lno)
 {
 	unsigned cur = lno, from = 1, funcname_lno = 0;
 	int funcname_needed = !!opt->funcname;
 
-	if (opt->funcbody && !match_funcname(opt, name, bol, end))
+	if (opt->funcbody && !match_funcname(opt, name, drv_p, bol, end))
 		funcname_needed = 2;
 
 	if (opt->pre_context < lno)
@@ -900,7 +915,7 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
 		while (bol > buf && bol[-1] != '\n')
 			bol--;
 		cur--;
-		if (funcname_needed && match_funcname(opt, name, bol, eol)) {
+		if (funcname_needed && match_funcname(opt, name, drv_p, bol, eol)) {
 			funcname_lno = cur;
 			funcname_needed = 0;
 		}
@@ -908,7 +923,7 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
 
 	/* We need to look even further back to find a function signature. */
 	if (opt->funcname && funcname_needed)
-		show_funcname_line(opt, name, buf, bol, cur);
+		show_funcname_line(opt, name, drv_p, buf, bol, cur);
 
 	/* Back forward. */
 	while (cur < lno) {
@@ -983,6 +998,17 @@ static void std_output(struct grep_opt *opt, const void *buf, size_t size)
 	fwrite(buf, size, 1, stdout);
 }
 
+static int grep_buffer_is_binary(struct grep_opt *opt,
+				 const char *path,
+				 char *buf, unsigned long size,
+				 struct userdiff_driver **drv_p)
+{
+	struct userdiff_driver *drv = get_cached_userdiff(opt, path, drv_p);
+	if (drv && drv->binary != -1)
+		return drv->binary;
+	return buffer_is_binary(buf, size);
+}
+
 static int grep_buffer_1(struct grep_opt *opt, const char *name,
 			 char *buf, unsigned long size, int collect_hits)
 {
@@ -996,6 +1022,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
 	int show_function = 0;
 	enum grep_context ctx = GREP_CONTEXT_HEAD;
 	xdemitconf_t xecfg;
+	struct userdiff_driver *drv = NULL;
 
 	if (!opt->output)
 		opt->output = std_output;
@@ -1017,11 +1044,11 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
 
 	switch (opt->binary) {
 	case GREP_BINARY_DEFAULT:
-		if (buffer_is_binary(buf, size))
+		if (grep_buffer_is_binary(opt, name, buf, size, &drv))
 			binary_match_only = 1;
 		break;
 	case GREP_BINARY_NOMATCH:
-		if (buffer_is_binary(buf, size))
+		if (grep_buffer_is_binary(opt, name, buf, size, &drv))
 			return 0; /* Assume unmatch */
 		break;
 	case GREP_BINARY_TEXT:
@@ -1099,16 +1126,16 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
 			 * pre-context lines, we would need to show them.
 			 */
 			if (opt->pre_context || opt->funcbody)
-				show_pre_context(opt, name, buf, bol, eol, lno);
+				show_pre_context(opt, name, &drv, buf, bol, eol, lno);
 			else if (opt->funcname)
-				show_funcname_line(opt, name, buf, bol, lno);
+				show_funcname_line(opt, name, &drv, buf, bol, lno);
 			show_line(opt, bol, eol, name, lno, ':');
 			last_hit = lno;
 			if (opt->funcbody)
 				show_function = 1;
 			goto next_line;
 		}
-		if (show_function && match_funcname(opt, name, bol, eol))
+		if (show_function && match_funcname(opt, name, &drv, bol, eol))
 			show_function = 0;
 		if (show_function ||
 		    (last_hit && lno <= last_hit + opt->post_context)) {

^ permalink raw reply related

* Re: [PATCH] Don't search files with an unset "grep" attribute
From: Jeff King @ 2012-02-01  8:20 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Conrad Irwin, git, Nguyen Thai Ngoc Duy, Dov Grobgeld
In-Reply-To: <7vhazb3rtm.fsf@alter.siamese.dyndns.org>

On Wed, Feb 01, 2012 at 12:01:41AM -0800, Junio C Hamano wrote:

> > So if this was all spelled:
> >
> >   $ cat .gitattributes
> >   *.pdf filetype=pdf
> >   $ cat .git/config
> >   [filetype "pdf"]
> >           binary = true
> >           textconv = pdf2txt
> >
> > I think it would be a no-brainer that those type attributes should apply
> > to "git grep".
> 
> I think this discussion has, instead of forking into two equally
> interesting subthreads, veered to a more intellectually stimulating
> tangent and we ended up losing focus.

That's what I'm here for.

> Regardless of what to do with "I do not want to grep in these types of
> files" and "I want textconv applied when grepping in these types", which
> would be new attributes to implement two new features, I would like to see
> us first concentrate on fixing the "binary" issue.  When somebody tells us
> "Your autodetection may screw it up, but this file is binary; just show
> 'Binary files differ.' when comparing." with "-diff" (or "binary"), we
> should honor that when "git grep" decides if it should take the 'Binary
> file matches' codepath.  We currently do not, and it clearly is a bug.

Right. It may have been lost in the verbosity of what I wrote in my
previous email, but I completely agree. With the caveat that one should
also respect "diff=foo" coupled with "diff.foo.binary = true" as making
something binary. But that is already handled transparently by the
userdiff.[ch] code (which seems like the obvious entry point for
grep to use for attribute lookup, and which we already use there for
funcname lookup).

The trivial-ish patch is below.

> We should have to teach the underlying machinery that matches pathspec
> about negative pathspec entries only once. After we have done so, all the
> callers, not just "git grep", should be able to take advantage of the
> change by just learning to place negative pathspec entries in the "struct
> pathspec" they pass to the machinery.  Doing anything else will lead to
> madness of adding ad-hoc "here we should further filter with the other
> negative 'struct pathspec'" in each and every application.

Yes, I agree.

> But I suspect that it would not materialize anytime soon.  And I also
> suspect that the correct handling of 'Binary file matches', which is a
> pure bugfix, should solve the original issue started these threads 90% in
> practice.

Also agree. Let's fix the bug and then give it some time to see whether
people really want more explicit exclusions.

Here's the bug-fix patch. Not quite ready for inclusion, as it obviously
needs tests and a commit message. Also, we can cache the result of the
userdiff lookup so the funcname code doesn't have to look it up again.

---
diff --git a/grep.c b/grep.c
index b29d09c..d7ab054 100644
--- a/grep.c
+++ b/grep.c
@@ -960,6 +960,15 @@ static void std_output(struct grep_opt *opt, const void *buf, size_t size)
 	fwrite(buf, size, 1, stdout);
 }
 
+static int grep_buffer_is_binary(const char *path,
+				 char *buf, unsigned long size)
+{
+	struct userdiff_driver *drv = userdiff_find_by_path(path);
+	if (drv && drv->binary != -1)
+		return drv->binary;
+	return buffer_is_binary(buf, size);
+}
+
 static int grep_buffer_1(struct grep_opt *opt, const char *name,
 			 char *buf, unsigned long size, int collect_hits)
 {
@@ -994,11 +1003,11 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
 
 	switch (opt->binary) {
 	case GREP_BINARY_DEFAULT:
-		if (buffer_is_binary(buf, size))
+		if (grep_buffer_is_binary(name, buf, size))
 			binary_match_only = 1;
 		break;
 	case GREP_BINARY_NOMATCH:
-		if (buffer_is_binary(buf, size))
+		if (grep_buffer_is_binary(name, buf, size))
 			return 0; /* Assume unmatch */
 		break;
 	case GREP_BINARY_TEXT:

^ permalink raw reply related

* Re: [PATCH] Don't search files with an unset "grep" attribute
From: Junio C Hamano @ 2012-02-01  8:01 UTC (permalink / raw)
  To: Jeff King; +Cc: Conrad Irwin, git, Nguyen Thai Ngoc Duy, Dov Grobgeld
In-Reply-To: <20120125214625.GA4666@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> On Mon, Jan 23, 2012 at 10:59:45PM -0800, Junio C Hamano wrote:
>
>> Conrad Irwin <conrad.irwin@gmail.com> writes:
>> > I used to use this approach, hooking into the "diff" attribute directly to mark
>> > a file as binary, however that was clearly a hack.
>> 
>> After thinking about this a bit more, I have to say I disagree that it is
>> a hack.
>
> I kind of agree.
>
> The biggest problem is that the name is wrong.  The "diff.*.command"
> option really is about generating a diff between two blobs of a certain
> type. But "diff.*.textconv" and "diff.*.binary" are really just
> attributes of the file, and may or may not have to do with generating a
> diff. Ditto for diff.*.funcname, I think.
>
> You argue, and I agree, that if we are talking about attributes of the
> files and not diff-specific things, then other parts of git can and
> should make use of that information.
>
> So if this was all spelled:
>
>   $ cat .gitattributes
>   *.pdf filetype=pdf
>   $ cat .git/config
>   [filetype "pdf"]
>           binary = true
>           textconv = pdf2txt
>
> I think it would be a no-brainer that those type attributes should apply
> to "git grep".

I think this discussion has, instead of forking into two equally
interesting subthreads, veered to a more intellectually stimulating
tangent and we ended up losing focus.

Regardless of what to do with "I do not want to grep in these types of
files" and "I want textconv applied when grepping in these types", which
would be new attributes to implement two new features, I would like to see
us first concentrate on fixing the "binary" issue.  When somebody tells us
"Your autodetection may screw it up, but this file is binary; just show
'Binary files differ.' when comparing." with "-diff" (or "binary"), we
should honor that when "git grep" decides if it should take the 'Binary
file matches' codepath.  We currently do not, and it clearly is a bug.

This is especially made somewhat urgent because I do not want a half-baked
"two pathspecs" approach that only "git grep" knows about when we add the
support for "git grep --exclude-path=...".

We should have to teach the underlying machinery that matches pathspec
about negative pathspec entries only once. After we have done so, all the
callers, not just "git grep", should be able to take advantage of the
change by just learning to place negative pathspec entries in the "struct
pathspec" they pass to the machinery.  Doing anything else will lead to
madness of adding ad-hoc "here we should further filter with the other
negative 'struct pathspec'" in each and every application.

But I suspect that it would not materialize anytime soon.  And I also
suspect that the correct handling of 'Binary file matches', which is a
pure bugfix, should solve the original issue started these threads 90% in
practice.

^ permalink raw reply

* Re: [PATCH] Fix an "variable might be used uninitialized" gcc warning
From: Miles Bader @ 2012-02-01  7:16 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Ramsay Jones, Junio C Hamano, GIT Mailing-list
In-Reply-To: <20120131194302.GD12443@burratino>

Jonathan Nieder <jrnieder@gmail.com> writes:
>> The versions which complain are 3.4.4 and 4.1.2, whereas 4.4.0 compiles
>> the code without complaint. So, gcc *may* be getting more sane, but I wouldn't
>> bet on it! :-P
>>
>> I've had examples of this kind of warning, which relies heavily on the
>> analysis performed primarily for the optimizer, come-and-go in gcc before
>
> Yep, judging from the commit message, Junio found the same warning
> in 4.6.2.
>
>> Having said that, unless you are going to decree that the project only
>> supports gcc (and presumably only some particular versions of gcc), then you
>> may well find similar warnings triggered when using other compilers anyway ...
>
> Sure, when the control flow grows too complicated, that's probably worth
> fixing anyway, for the sake of humans especially.
>
> Sometimes gcc is the only crazy one, though. ;-)

It's hard to see how any compiler could detect that "mode" always
receives a value here .... it would have to realize that "stage" always
becomes 2 before the loop is exited, and that seems to depend on
non-trivial properties of external data structures...

-miles

-- 
Joy, n. An emotion variously excited, but in its highest degree arising from
the contemplation of grief in another.

^ permalink raw reply

* What's cooking in git.git (Jan 2012, #08; Tue, 31)
From: Junio C Hamano @ 2012-02-01  7:19 UTC (permalink / raw)
  To: git

What's cooking in git.git (Jan 2012, #08; Tue, 31)
--------------------------------------------------

Here are the topics that have been cooking.  Commits prefixed with '-' are
only in 'pu' (proposed updates) while commits prefixed with '+' are in
'next'.

As promised in the recent couple of issues of "What's cooking", the first
batch of topics that have been cooking in 'next' are now in 'master'. The
tip of 'next' hasn't been rewound yet, but it soon will after the second
batch of topics graduate.

Here are the repositories that have my integration branches:

With maint, master, next, pu, todo:

        git://git.kernel.org/pub/scm/git/git.git
        git://repo.or.cz/alt-git.git
        https://code.google.com/p/git-core/
        https://github.com/git/git

With only maint and master:

        git://git.sourceforge.jp/gitroot/git-core/git.git
        git://git-core.git.sourceforge.net/gitroot/git-core/git-core

With all the topics and integration branches:

        https://github.com/gitster/git

The preformatted documentation in HTML and man format are found in:

        git://git.kernel.org/pub/scm/git/git-{htmldocs,manpages}.git/
        git://repo.or.cz/git-{htmldocs,manpages}.git/
        https://code.google.com/p/git-{htmldocs,manpages}.git/
        https://github.com/gitster/git-{htmldocs,manpages}.git/

--------------------------------------------------
[New Topics]

* fc/zsh-completion (2012-01-30) 4 commits
 - (squash to previous?) completion: remove unused code
 - completion: simplify __git_remotes
 - (squash) completion-style
 - completion: be nicer with zsh

Somehow only 2 out of 4-part series seem to have reached the list, missing
the other 2.

* jc/maint-request-pull-for-tag (2012-01-31) 1 commit
 - request-pull: explicitly ask tags/$name to be pulled

Usability improvement.
Will merge to 'next'.

* nd/find-pack-entry-recent-cache-invalidation (2012-01-31) 1 commit
 - find_pack_entry(): do not keep packed_git pointer locally

Review comments sent.

* nd/pack-objects-parseopt (2012-01-31) 1 commit
 - pack-objects: convert to use parse_options()

Review comments sent.

* tr/merge-edit-guidance (2012-01-31) 1 commit
  (merged to 'next' on 2012-01-31 at bb678f7)
 + merge: add instructions to the commit message when editing

Will merge to 'master' in the second batch.

--------------------------------------------------
[Graduated to "master"]

* ar/i18n-no-gettext (2012-01-27) 4 commits
  (merged to 'next' on 2012-01-27 at 0ecf258)
 + i18n: Do not force USE_GETTEXT_SCHEME=fallthrough on NO_GETTEXT
  (merged to 'next' on 2012-01-23 at 694a94e)
 + i18n: Make NO_GETTEXT imply fallthrough scheme in shell l10n
 + add a Makefile switch to avoid gettext translation in shell scripts
 + git-sh-i18n: restructure the logic to compute gettext.sh scheme

* da/maint-mergetool-twoway (2012-01-23) 1 commit
  (merged to 'next' on 2012-01-23 at f927323)
 + mergetool: Provide an empty file when needed

Caters to GUI merge backends that cannot merge two files without
a base by giving them an empty file as a "pretend" common ancestor.

* jc/advise-i18n (2011-12-22) 1 commit
  (merged to 'next' on 2012-01-23 at 6447013)
 + i18n of multi-line advice messages

Allow localization of advice messages that tend to be longer and
multi-line formatted. For now this is deliberately limited to advise()
interface and not vreportf() in general as touching the latter has
interactions with error() that has plumbing callers whose prefix "error: "
should never be translated.

* jl/submodule-re-add (2012-01-24) 1 commit
  (merged to 'next' on 2012-01-26 at 482553e)
 + submodule add: fix breakage when re-adding a deep submodule

"git submodule add" forgot to recompute the name to be stored in .gitmodules
when the module was once added to the superproject and already initialized.

* ks/sort-wildcard-in-makefile (2012-01-22) 1 commit
  (merged to 'next' on 2012-01-23 at e2e0c1d)
 + t/Makefile: Use $(sort ...) explicitly where needed

t/Makefile is adjusted to prevent newer versions of GNU make from running
tests in seemingly random order.

* ld/git-p4-branches-and-labels (2012-01-20) 5 commits
  (merged to 'next' on 2012-01-23 at 9020ec4)
 + git-p4: label import fails with multiple labels at the same changelist
 + git-p4: add test for p4 labels
 + git-p4: importing labels should cope with missing owner
 + git-p4: cope with labels with empty descriptions
 + git-p4: handle p4 branches and labels containing shell chars
 (this branch is used by va/git-p4-branch.)

* nd/clone-detached (2012-01-24) 12 commits
  (merged to 'next' on 2012-01-26 at 7b0cc8a)
 + clone: fix up delay cloning conditions
  (merged to 'next' on 2012-01-23 at bee31c6)
 + push: do not let configured foreign-vcs permanently clobbered
  (merged to 'next' on 2012-01-23 at 9cab64e)
 + clone: print advice on checking out detached HEAD
 + clone: allow --branch to take a tag
 + clone: refuse to clone if --branch points to bogus ref
 + clone: --branch=<branch> always means refs/heads/<branch>
 + clone: delay cloning until after remote HEAD checking
 + clone: factor out remote ref writing
 + clone: factor out HEAD update code
 + clone: factor out checkout code
 + clone: write detached HEAD in bare repositories
 + t5601: add missing && cascade

"git clone" learned to detach the HEAD in the resulting repository when
the source repository's HEAD does not point to a branch.

* rr/sequencer (2012-01-11) 2 commits
  (merged to 'next' on 2012-01-23 at f349b56)
 + sequencer: factor code out of revert builtin
 + revert: prepare to move replay_action to header

Moving large chunk of code out of cherry-pick/revert for later reuse,
primarily to prepare for the next cycle.

* tr/grep-l-with-decoration (2012-01-23) 1 commit
  (merged to 'next' on 2012-01-23 at 42b8795)
 + grep: fix -l/-L interaction with decoration lines

Using "git grep -l/-L" together with options -W or --break may not make
much sense as the output is to only count the number of hits and there is
no place for file breaks, but the latter options made "-l/-L" to miscount
the hits.

* va/git-p4-branch (2012-01-26) 4 commits
  (merged to 'next' on 2012-01-26 at e67c52a)
 + t9801: do not overuse test_must_fail
 + git-p4: Change p4 command invocation
 + git-p4: Add test case for complex branch import
 + git-p4: Search for parent commit on branch creation
 (this branch uses ld/git-p4-branches-and-labels.)

--------------------------------------------------
[Stalled]

* jc/advise-push-default (2011-12-18) 1 commit
 - push: hint to use push.default=upstream when appropriate

Peff had a good suggestion outlining an updated code structure so that
somebody new can try to dip his or her toes in the development. Any
takers?

Waiting for a reroll.

* ss/git-svn-prompt-sans-terminal (2012-01-04) 3 commits
 - fixup! 15eaaf4
 - git-svn, perl/Git.pm: extend Git::prompt helper for querying users
  (merged to 'next' on 2012-01-05 at 954f125)
 + perl/Git.pm: "prompt" helper to honor GIT_ASKPASS and SSH_ASKPASS

The bottom one has been replaced with a rewrite based on comments from
Ævar. The second one needs more work, both in perl/Git.pm and prompt.c, to
give precedence to tty over SSH_ASKPASS when terminal is available.

Will defer till the next cycle.

* nd/commit-ignore-i-t-a (2012-01-16) 2 commits
 - commit, write-tree: allow to ignore CE_INTENT_TO_ADD while writing trees
 - cache-tree: update API to take abitrary flags

May want to consider this as fixing an earlier UI mistake, and not as a
feature that devides the userbase.

Will defer till the next cycle.

--------------------------------------------------
[Cooking]

* bl/gitweb-project-filter (2012-01-31) 8 commits
 - gitweb: Make project search respect project_filter
 - gitweb: improve usability of projects search form
 - gitweb: place links to parent directories in page header
 - gitweb: show active project_filter in project_list page header
 - gitweb: limit links to alternate forms of project_list to active project_filter
 - gitweb: add project_filter to limit project list to a subdirectory
 - gitweb: prepare git_get_projects_list for use outside 'forks'.
 - gitweb: move hard coded .git suffix out of git_get_projects_list

Seems to break test 9502.

* rt/completion-branch-edit-desc (2012-01-29) 1 commit
  (merged to 'next' on 2012-01-31 at a0195c8)
 + completion: --edit-description option for git-branch

* jn/svn-fe (2012-01-27) 44 commits
  (merged to 'next' on 2012-01-29 at 001a395)
 + vcs-svn/svndiff.c: squelch false "unused" warning from gcc
 + Merge branch 'svn-fe' of git://repo.or.cz/git/jrn into jn/svn-fe
 + vcs-svn: reset first_commit_done in fast_export_init
 + Merge branch 'db/text-delta' into svn-fe
 + vcs-svn: do not initialize report_buffer twice
 + Merge branch 'db/text-delta' into svn-fe
 + vcs-svn: avoid hangs from corrupt deltas
 + vcs-svn: guard against overflow when computing preimage length
 + Merge branch 'db/delta-applier' into db/text-delta
 + vcs-svn: implement text-delta handling
 + Merge branch 'db/delta-applier' into db/text-delta
 + Merge branch 'db/delta-applier' into svn-fe
 + vcs-svn: cap number of bytes read from sliding view
 + test-svn-fe: split off "test-svn-fe -d" into a separate function
 + vcs-svn: let deltas use data from preimage
 + vcs-svn: let deltas use data from postimage
 + vcs-svn: verify that deltas consume all inline data
 + vcs-svn: implement copyfrom_data delta instruction
 + vcs-svn: read instructions from deltas
 + vcs-svn: read inline data from deltas
 + vcs-svn: read the preimage when applying deltas
 + vcs-svn: parse svndiff0 window header
 + vcs-svn: skeleton of an svn delta parser
 + vcs-svn: make buffer_read_binary API more convenient
 + vcs-svn: learn to maintain a sliding view of a file
 + Makefile: list one vcs-svn/xdiff object or header per line
 + Merge branch 'db/svn-fe-code-purge' into svn-fe
 + vcs-svn: drop obj_pool
 + vcs-svn: drop treap
 + vcs-svn: drop string_pool
 + vcs-svn: pass paths through to fast-import
 + Merge branch 'db/strbufs-for-metadata' into db/svn-fe-code-purge
 + Merge branch 'db/length-as-hash' (early part) into db/svn-fe-code-purge
 + Merge branch 'db/vcs-svn-incremental' into svn-fe
 + vcs-svn: avoid using ls command twice
 + vcs-svn: use mark from previous import for parent commit
 + vcs-svn: handle filenames with dq correctly
 + vcs-svn: quote paths correctly for ls command
 + vcs-svn: eliminate repo_tree structure
 + vcs-svn: add a comment before each commit
 + vcs-svn: save marks for imported commits
 + vcs-svn: use higher mark numbers for blobs
 + vcs-svn: set up channel to read fast-import cat-blob response
 + Merge commit 'v1.7.5' into svn-fe

"vcs-svn"/"svn-fe" learned to read dumps with svn-deltas and support
incremental imports.

Will merge to 'master' in the second batch.

* jc/split-blob (2012-01-24) 6 commits
 - chunked-object: streaming checkout
 - chunked-object: fallback checkout codepaths
 - bulk-checkin: support chunked-object encoding
 - bulk-checkin: allow the same data to be multiply hashed
 - new representation types in the packstream
 - varint-in-pack: refactor varint encoding/decoding

Not ready.

I finished the streaming checkout codepath, but as explained in 127b177
(bulk-checkin: support chunked-object encoding, 2011-11-30), these are
still early steps of a long and painful journey. At least pack-objects and
fsck need to learn the new encoding for the series to be usable locally,
and then index-pack/unpack-objects needs to learn it to be used remotely.

Given that I heard a lot of noise that people want large files, and that I
was asked by somebody at GitTogether'11 privately for an advice on how to
pay developers (not me) to help adding necessary support, I am somewhat
dissapointed that the original patch series that was sent almost two
months ago still remains here without much comments and updates from the
developer community. I even made the interface to the logic that decides
where to split chunks easily replaceable, and I deliberately made the
logic in the original patch extremely stupid to entice others, especially
the "bup" fanboys, to come up with a better logic, thinking that giving
people an easy target to shoot for, they may be encouraged to help
out. The plan is not working :-(.

* jc/pull-signed-tag (2012-01-23) 1 commit
  (merged to 'next' on 2012-01-23 at 4257553)
 + merge: use editor by default in interactive sessions

"git merge" in an interactive session learned to spawn the editor by
default to let the user edit the auto-generated merge message, to
encourage people to explain their merges better. Legacy scripts can
export MERGE_AUTOEDIT=no to retain the historical behaviour.

Will merge to 'master' in the second batch and deal with any fallout in
'master'.

--------------------------------------------------
[Discarded]

* mh/ref-api-rest (2011-12-12) 35 commits
 . repack_without_ref(): call clear_packed_ref_cache()
 . read_packed_refs(): keep track of the directory being worked in
 . is_refname_available(): query only possibly-conflicting references
 . refs: read loose references lazily
 . read_loose_refs(): take a (ref_entry *) as argument
 . struct ref_dir: store a reference to the enclosing ref_cache
 . sort_ref_dir(): take (ref_entry *) instead of (ref_dir *)
 . do_for_each_ref_in_dir*(): take (ref_entry *) instead of (ref_dir *)
 . add_entry(): take (ref_entry *) instead of (ref_dir *)
 . search_ref_dir(): take (ref_entry *) instead of (ref_dir *)
 . find_containing_direntry(): use (ref_entry *) instead of (ref_dir *)
 . add_ref(): take (ref_entry *) instead of (ref_dir *)
 . read_packed_refs(): take (ref_entry *) instead of (ref_dir *)
 . find_ref(): take (ref_entry *) instead of (ref_dir *)
 . is_refname_available(): take (ref_entry *) instead of (ref_dir *)
 . get_loose_refs(): return (ref_entry *) instead of (ref_dir *)
 . get_packed_refs(): return (ref_entry *) instead of (ref_dir *)
 . refs: wrap top-level ref_dirs in ref_entries
 . get_ref_dir(): keep track of the current ref_dir
 . do_for_each_ref(): only iterate over the subtree that was requested
 . refs: sort ref_dirs lazily
 . sort_ref_dir(): do not sort if already sorted
 . refs: store references hierarchically
 . refs.c: rename ref_array -> ref_dir
 . struct ref_entry: nest the value part in a union
 . check_refname_component(): return 0 for zero-length components
 . free_ref_entry(): new function
 . refs.c: reorder definitions more logically
 . is_refname_available(): reimplement using do_for_each_ref_in_array()
 . names_conflict(): simplify implementation
 . names_conflict(): new function, extracted from is_refname_available()
 . repack_without_ref(): reimplement using do_for_each_ref_in_array()
 . do_for_each_ref_in_arrays(): new function
 . do_for_each_ref_in_array(): new function
 . do_for_each_ref(): correctly terminate while processesing extra_refs

Will be re-rolled. Discarded without prejudice.

* mm/zsh-completion-regression-fix (2012-01-17) 1 commit
  (merged to 'next' on 2012-01-23 at 7bc2e0a)
 + bash-completion: don't add quoted space for ZSH (fix regression)

Superseded by a better fix already in 'master'.

^ permalink raw reply

* [PATCH] request-pull: explicitly ask tags/$name to be pulled
From: Junio C Hamano @ 2012-02-01  5:50 UTC (permalink / raw)
  To: git; +Cc: Mark Brown

When asking for a tag to be pulled, disambiguate by leaving tags/ prefix
in front of the name of the tag. E.g.

    ... in the git repository at:

      git://example.com/git/git.git/ tags/v1.2.3

    for you to fetch changes up to 123456...

This way, older versions of "git pull" can be used to respond to such a
request more easily, as "git pull $URL v1.2.3" did not DWIM to fetch
v1.2.3 tag in older versions. Also this makes it clearer for humans that
the pull request is made for a tag and he should anticipate a signed one.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 * http://thread.gmane.org/gmane.linux.kernel/1245709/focus=1245909
   triggered this

 .../howto/using-signed-tag-in-pull-request.txt     |    4 ++--
 git-request-pull.sh                                |    2 +-
 t/t5150-request-pull.sh                            |    6 +-----
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/Documentation/howto/using-signed-tag-in-pull-request.txt b/Documentation/howto/using-signed-tag-in-pull-request.txt
index a1351c5..98c0033 100644
--- a/Documentation/howto/using-signed-tag-in-pull-request.txt
+++ b/Documentation/howto/using-signed-tag-in-pull-request.txt
@@ -109,7 +109,7 @@ The resulting msg.txt file begins like so:
 
  are available in the git repository at:
 
-   example.com:/git/froboz.git frotz-for-xyzzy
+   example.com:/git/froboz.git tags/frotz-for-xyzzy
 
  for you to fetch changes up to 703f05ad5835c...:
 
@@ -141,7 +141,7 @@ After receiving such a pull request message, the integrator fetches and
 integrates the tag named in the request, with:
 
 ------------
- $ git pull example.com:/git/froboz.git/ frotz-for-xyzzy
+ $ git pull example.com:/git/froboz.git/ tags/frotz-for-xyzzy
 ------------
 
 This operation will always open an editor to allow the integrator to fine
diff --git a/git-request-pull.sh b/git-request-pull.sh
index 64960d6..e6438e2 100755
--- a/git-request-pull.sh
+++ b/git-request-pull.sh
@@ -63,7 +63,7 @@ die "fatal: No commits in common between $base and $head"
 find_matching_ref='
 	sub abbr {
 		my $ref = shift;
-		if ($ref =~ s|refs/heads/|| || $ref =~ s|refs/tags/||) {
+		if ($ref =~ s|^refs/heads/|| || $ref =~ s|^refs/tags/|tags/|) {
 			return $ref;
 		} else {
 			return $ref;
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index da25bc2..7c1dc64 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -179,11 +179,7 @@ test_expect_success 'request names an appropriate branch' '
 		read repository &&
 		read branch
 	} <digest &&
-	{
-		test "$branch" = full ||
-		test "$branch" = master ||
-		test "$branch" = for-upstream
-	}
+	test "$branch" = tags/full
 
 '
 
-- 
1.7.9.155.gf6ee6

^ permalink raw reply related

* Re: [PATCH] Correct singular form in diff summary line for human interaction
From: Junio C Hamano @ 2012-02-01  3:04 UTC (permalink / raw)
  To: dickey
  Cc: Nguyen Thai Ngoc Duy, Jonathan Nieder, git,
	Ævar Arnfjörð, Frederik Schwarzer, Brandon Casey,
	dickey
In-Reply-To: <20120201015606.GA24482@debian50-32.invisible-island.net>

Thomas Dickey <dickey@his.com> writes:

> On Wed, Feb 01, 2012 at 08:32:43AM +0700, Nguyen Thai Ngoc Duy wrote:
>> On Wed, Feb 1, 2012 at 12:50 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> >> If there is an environment variable to say "I don't want to see
>> >> variations on strings intended for humans", can it be spelled as
>> >> LC_ALL=C?
>> >
>> >  ...
>
> ... diffstat (google helped find context)

When we show diffstat from "git diff --stat" (or "git apply --stat"), we
currently do not do any singular/plural on the last line of the output
that summarizes the graph, ending up with:

	1 files changed, 1 insertions(+), 0 deletions(-)

when there is a single line insertion to a file and nothing else.

My recollection is that our behaviour originally came from our desire to
be as close as what "diffstat" produces, but that does not seem to be the
case.  I observed that the output from recent versions of "diffstat" is
much more human friendly.  We get these, depending on the input, from
"diffstat" version 1.53:

        1 file changed, 1 insertion(+)
        1 file changed, 1 deletion(-)
	0 files changed
	2 files changed, 3 insertions(+), 1 deletion(-)

Namely, it does singular/plural correctly, and omits unnecessary "0
deletions(-)" and "0 insertions(+)".

I was wondering if you remember what the behaviour of older versions of
"diffstat" was, and if it was changed to be more human friendly over
time. It is very possible that I am misremembering this and "diffstat" has
always done the singular/plural correctly and omitted useless "0 lines".

Somehow it seems hard to get hold of older versions of "diffstat", and I
was hoping that I could get that information straight out of the current
maintainer.

Thanks for responding and sorry for the lack of context of the original
message.

^ permalink raw reply

* Re: logging disjoint sets of commits in a single command
From: Jeff King @ 2012-02-01  3:03 UTC (permalink / raw)
  To: Bryan O'Sullivan; +Cc: Junio C Hamano, git@vger.kernel.org
In-Reply-To: <CB4DCD5C.747%bryano@fb.com>

On Wed, Feb 01, 2012 at 01:02:57AM +0000, Bryan O'Sullivan wrote:

> By the way, the reason I'm even interested in this in the first place is
> that the performance of commands like "git blame" and "git log" on files
> and subtrees has become a problem for us (> 10 seconds per invocation,
> forecast to get much worse), and I wanted to see whether I could feed "git
> log" a specific list of revisions, and if so, whether that could yield
> good performance.

That sounds kind of slow. Is your repository really gigantic? Have you packed
everything? I'm just curious if there's some other way to make things
faster. Is the repository publicly available?

-Peff

^ permalink raw reply

* [BUG] gitk and "Ignore space change" option
From: Oleg Kostyuk @ 2012-02-01  2:42 UTC (permalink / raw)
  To: git

Debian/testing, git version 1.7.8.3

There is no possibility to:
1) save value of "Ignore space change" option into config file (~/.gitk)
2) pass some option in cmd line (like --ignore-space-change or -w)

So, there is no other control to "Ignore space change", except via
configuration dialog. This is very inconvenient, and I think this
should be considered as bug.

As solution, any of (1) or (2) could be implemented, but if both -
then this will be fantastic :)

Thanks!


PS: could be useful -
http://stackoverflow.com/questions/8221877/gitk-setting-ignore-space-change-option-to-be-true-by-default

-- 
Sincerely yours,
Oleg Kostyuk (CUB-UANIC)

^ permalink raw reply

* Re: [PATCH] Correct singular form in diff summary line for human interaction
From: Nguyen Thai Ngoc Duy @ 2012-02-01  2:37 UTC (permalink / raw)
  To: dickey
  Cc: Junio C Hamano, Jonathan Nieder, git,
	Ævar Arnfjörð, Frederik Schwarzer, Brandon Casey,
	dickey
In-Reply-To: <20120201015606.GA24482@debian50-32.invisible-island.net>

On Wed, Feb 1, 2012 at 8:56 AM, Thomas Dickey <dickey@his.com> wrote:
>> > If we were to touch this, I would prefer to do so unconditionally without
>> > "hrm, can we reliably guess this is meant for humans?" and release it
>> > unceremoniously, perhaps as part of the next release that will have a much
>> > bigger user-visible UI correction to 'merge'.
>>
>> Unconditionally change is fine to me. There's another implication
>> that's not mentioned in the commit message, this change also allows
>> non-English translations. Any objections on i18n or we just keep this
>> line English only? Personally if scripts do not matter any more, I see
>> no reasons this line cannot be translated.
>
> I seem to recall that gettext does support plurals...
>
> However, going that route means that even innocuous things like the
> parentheses "(+)" can be mangled by translators (guaranteed to break
> scripts ;-)

We disregard scripts at this point already, I think. "+" and "-"
should not be translated. We could either leave them out of
translatable text, or put a note to translators saying not to
translate them.
-- 
Duy

^ permalink raw reply

* Re: [PATCH] Correct singular form in diff summary line for human interaction
From: Thomas Dickey @ 2012-02-01  1:56 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy
  Cc: Junio C Hamano, Jonathan Nieder, git,
	Ævar Arnfjörð, Frederik Schwarzer, Brandon Casey,
	dickey
In-Reply-To: <CACsJy8Dd4_Pnvzxww38EfZt8NgRow+qxCReohc45XoNpfJCbYg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1313 bytes --]

On Wed, Feb 01, 2012 at 08:32:43AM +0700, Nguyen Thai Ngoc Duy wrote:
> On Wed, Feb 1, 2012 at 12:50 AM, Junio C Hamano <gitster@pobox.com> wrote:
> >> If there is an environment variable to say "I don't want to see
> >> variations on strings intended for humans", can it be spelled as
> >> LC_ALL=C?
> >
> >  ...

... diffstat (google helped find context)

> > If we were to touch this, I would prefer to do so unconditionally without
> > "hrm, can we reliably guess this is meant for humans?" and release it
> > unceremoniously, perhaps as part of the next release that will have a much
> > bigger user-visible UI correction to 'merge'.
> 
> Unconditionally change is fine to me. There's another implication
> that's not mentioned in the commit message, this change also allows
> non-English translations. Any objections on i18n or we just keep this
> line English only? Personally if scripts do not matter any more, I see
> no reasons this line cannot be translated.

I seem to recall that gettext does support plurals...

However, going that route means that even innocuous things like the
parentheses "(+)" can be mangled by translators (guaranteed to break
scripts ;-)

-- 
Thomas E. Dickey <dickey@invisible-island.net>
http://invisible-island.net
ftp://invisible-island.net

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH] Correct singular form in diff summary line for human interaction
From: Thomas Dickey @ 2012-02-01  1:45 UTC (permalink / raw)
  To: Nguyen Thai Ngoc Duy
  Cc: Junio C Hamano, Jonathan Nieder, git,
	Ævar Arnfjörð, Frederik Schwarzer, Brandon Casey,
	dickey
In-Reply-To: <CACsJy8Dd4_Pnvzxww38EfZt8NgRow+qxCReohc45XoNpfJCbYg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 530 bytes --]

On Wed, Feb 01, 2012 at 08:32:43AM +0700, Nguyen Thai Ngoc Duy wrote:
> On Wed, Feb 1, 2012 at 12:50 AM, Junio C Hamano <gitster@pobox.com> wrote:
> >> If there is an environment variable to say "I don't want to see
> >> variations on strings intended for humans", can it be spelled as
> >> LC_ALL=C?

I assume from Neider on the list that this is related to mawk, but I don't
have the email preceding this...

-- 
Thomas E. Dickey <dickey@invisible-island.net>
http://invisible-island.net
ftp://invisible-island.net

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH] Correct singular form in diff summary line for human interaction
From: Nguyen Thai Ngoc Duy @ 2012-02-01  1:32 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jonathan Nieder, git, Ævar Arnfjörð,
	Frederik Schwarzer, Brandon Casey, dickey
In-Reply-To: <7vvcnr92y0.fsf@alter.siamese.dyndns.org>

On Wed, Feb 1, 2012 at 12:50 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> If there is an environment variable to say "I don't want to see
>> variations on strings intended for humans", can it be spelled as
>> LC_ALL=C?
>
>  ...
>
> If we were to touch this, I would prefer to do so unconditionally without
> "hrm, can we reliably guess this is meant for humans?" and release it
> unceremoniously, perhaps as part of the next release that will have a much
> bigger user-visible UI correction to 'merge'.

Unconditionally change is fine to me. There's another implication
that's not mentioned in the commit message, this change also allows
non-English translations. Any objections on i18n or we just keep this
line English only? Personally if scripts do not matter any more, I see
no reasons this line cannot be translated.
-- 
Duy

^ permalink raw reply

* Re: logging disjoint sets of commits in a single command
From: Bryan O'Sullivan @ 2012-02-01  1:02 UTC (permalink / raw)
  To: Jeff King, Junio C Hamano; +Cc: git@vger.kernel.org
In-Reply-To: <20120201005332.GC30969@sigill.intra.peff.net>

On 2012-01-31, "Jeff King" <peff@peff.net> wrote:

>This topic came up
>recently, and I think the general consensus is that it would be cool to
>be able to do totally independent ranges, but that would be backwards
>incompatible with the current behavior.

That's totally sensible. I hadn't been able to tell from inspection
whether the behaviour was deliberate or not.

>which is of course slightly more annoying to type. If you're just
>interested in _single_ commits, though, you can just give the commits
>and turn off walking:
>
>  git log --no-walk 373af0c 590dfe2

Oh, nice! I hadn't seen that option.

By the way, the reason I'm even interested in this in the first place is
that the performance of commands like "git blame" and "git log" on files
and subtrees has become a problem for us (> 10 seconds per invocation,
forecast to get much worse), and I wanted to see whether I could feed "git
log" a specific list of revisions, and if so, whether that could yield
good performance.

I have it in mind to build a secondary index (maintained externally) so
that I can supply these git commands with precise lists of revisions for
much faster response times.

Thanks, guys!

^ permalink raw reply

* Re: logging disjoint sets of commits in a single command
From: Jeff King @ 2012-02-01  0:53 UTC (permalink / raw)
  To: Carlos Martín Nieto; +Cc: Bryan O'Sullivan, git@vger.kernel.org
In-Reply-To: <1328056769.31804.217.camel@centaur.lab.cmartin.tk>

On Wed, Feb 01, 2012 at 01:39:29AM +0100, Carlos Martín Nieto wrote:

> > Here's a sample command line against a kernel tree:
> > 
> > git log 373af0c^..373af0c 590dfe2^..590dfe2
> > 
> > I want git to log those two specific commits, but in fact it looks like
> > limit_list is marking 590dfe2 as UNINTERESTING while processing 373af0c,
> > and so it gets pruned.
> > 
> > Is there some way around this, or would a patch to fix it be acceptable?
> 
> From my reading of the manpage (and the way most git commands work) log
> accepts one range of commits. They all get bunched up together.

Right. That command is equivalent to:

  373af0c 590dfe2 --not 373af0c^ 590dfe2^

So the limiting for one range you're interested in ends up marking part
of the other as uninteresting, and that's by design. This topic came up
recently, and I think the general consensus is that it would be cool to
be able to do totally independent ranges, but that would be backwards
incompatible with the current behavior.

In the general case, you can emulate this with:

  { git log 373af0c^..373af0c
    git log 590dfe2^..590dfe2
  } | $PAGER

which is of course slightly more annoying to type. If you're just
interested in _single_ commits, though, you can just give the commits
and turn off walking:

  git log --no-walk 373af0c 590dfe2

> You might find cat-file's --batch mode interesting.
> 
>     git rev-list 373af0c^..373af0c | git cat-file --batch
>     git rev-list 590dfe2^..590dfe2 | git cat-file --batch
> 
> looks a lot like what you're looking for.

I think you could even drop the rev-lists in this case, since he just
wants a single commit. However, cat-file lacks the niceties of "log",
like fancy --pretty formatting and automatic diffing against parents.

-Peff

^ permalink raw reply

* Re: logging disjoint sets of commits in a single command
From: Junio C Hamano @ 2012-02-01  0:48 UTC (permalink / raw)
  To: Bryan O'Sullivan; +Cc: git@vger.kernel.org
In-Reply-To: <CB4DC442.72F%bryano@fb.com>

"Bryan O'Sullivan" <bryano@fb.com> writes:

> Here's a sample command line against a kernel tree:
>
> git log 373af0c^..373af0c 590dfe2^..590dfe2

This command line is _defined_ to be the same as this.

	git log ^373af0c^ 373af0c ^590dfe2^ 590dfe2

Hence,

> Is there some way around this, or would a patch to fix it be acceptable?

the answer to the second question is "no, that is not a fix but is a
breakage for the *current* Git users".

The answer to the first question is that you may be able to do something
like this:

        (
            git rev-list 373af0c^..373af0c
            git rev-list 590dfe2^..590dfe2
        ) |
        sort -u |
        xargs git show

Having said all that, for users of Git 2.0, giving richer meaning to the
explicit range notation to make your original command line work just like
the above scripted way would be more intuitive.  While an unconditional
change to break the current users would totally be unacceptable, we would
want to see somebody come up with a clean migration path toward that goal
without hurting existing users in the longer term.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox