git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] Hash-independent tests, part 5
@ 2019-08-18 19:16 brian m. carlson
  2019-08-18 19:16 ` [PATCH 01/14] t3201: abstract away SHA-1-specific constants brian m. carlson
                   ` (14 more replies)
  0 siblings, 15 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

This is the fifth series of test fixes for SHA-256 compatibility.  It
consists of 15 patches fixing various tests from t3201 through t4009 and
has only test fixes: no test helper changes are included.

There are approximately 75 remaining test patches (plus some additional
code changes) required for the test suite to pass successfully with
SHA-256, which does not include the patches required to replace SHA-1
near-collisions in tests with actual SHA-256 near-collisions.

brian m. carlson (14):
  t3201: abstract away SHA-1-specific constants
  t3206: abstract away hash size constants
  t3301: abstract away SHA-1-specific constants
  t3305: make hash size independent
  t3306: abstract away SHA-1-specific constants
  t3404: abstract away SHA-1-specific constants
  t3430: avoid hard-coded object IDs
  t3506: make hash independent
  t3600: make hash size independent
  t3800: make hash-size independent
  t3903: abstract away SHA-1-specific constants
  t4000: make hash size independent
  t4002: make hash independent
  t4009: make hash size independent

 t/t3201-branch-contains.sh    |   8 +-
 t/t3206-range-diff.sh         | 227 +++++++++++++++------
 t/t3301-notes.sh              | 140 ++++++++-----
 t/t3305-notes-fanout.sh       |  22 +-
 t/t3306-notes-prune.sh        |  45 ++---
 t/t3404-rebase-interactive.sh |  22 +-
 t/t3430-rebase-merges.sh      |  23 ++-
 t/t3506-cherry-pick-ff.sh     |   8 +-
 t/t3600-rm.sh                 |   4 +-
 t/t3800-mktag.sh              |  49 ++---
 t/t3903-stash.sh              |  32 ++-
 t/t4000-diff-format.sh        |   2 +-
 t/t4002-diff-basic.sh         | 367 ++++++++++++++++++++++++----------
 t/t4009-diff-rename-4.sh      |  19 +-
 14 files changed, 640 insertions(+), 328 deletions(-)


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

* [PATCH 01/14] t3201: abstract away SHA-1-specific constants
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 02/14] t3206: abstract away hash size constants brian m. carlson
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3201-branch-contains.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 0ea4fc4694..40251c9f8f 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -192,10 +192,10 @@ test_expect_success 'branch --merged with --verbose' '
 	EOF
 	test_cmp expect actual &&
 	git branch --verbose --merged topic >actual &&
-	cat >expect <<-\EOF &&
-	  master c77a0a9 second on master
-	* topic  2c939f4 [ahead 1] foo
-	  zzz    c77a0a9 second on master
+	cat >expect <<-EOF &&
+	  master $(git rev-parse --short master) second on master
+	* topic  $(git rev-parse --short topic ) [ahead 1] foo
+	  zzz    $(git rev-parse --short zzz   ) second on master
 	EOF
 	test_i18ncmp expect actual
 '

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

* [PATCH 02/14] t3206: abstract away hash size constants
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
  2019-08-18 19:16 ` [PATCH 01/14] t3201: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 03/14] t3301: abstract away SHA-1-specific constants brian m. carlson
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

The various short object IDs in the range-diff output differ between
hash algorithms.  Use test_oid_cache to look up values for both SHA-1
and SHA-256.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3206-range-diff.sh | 227 +++++++++++++++++++++++++++++++-----------
 1 file changed, 167 insertions(+), 60 deletions(-)

diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
index ec548654ce..0120f769f1 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -8,17 +8,124 @@ test_description='range-diff tests'
 # harm than good.  We need some real history.
 
 test_expect_success 'setup' '
-	git fast-import < "$TEST_DIRECTORY"/t3206/history.export
+	git fast-import < "$TEST_DIRECTORY"/t3206/history.export &&
+	test_oid_cache <<-EOF
+	# topic
+	t1 sha1:4de457d
+	t2 sha1:fccce22
+	t3 sha1:147e64e
+	t4 sha1:a63e992
+	t1 sha256:b89f8b9
+	t2 sha256:5f12aad
+	t3 sha256:ea8b273
+	t4 sha256:14b7336
+
+	# unmodified
+	u1 sha1:35b9b25
+	u2 sha1:de345ab
+	u3 sha1:9af6654
+	u4 sha1:2901f77
+	u1 sha256:e3731be
+	u2 sha256:14fadf8
+	u3 sha256:736c4bc
+	u4 sha256:673e77d
+
+	# reordered
+	r1 sha1:aca177a
+	r2 sha1:14ad629
+	r3 sha1:ee58208
+	r4 sha1:307b27a
+	r1 sha256:f59d3aa
+	r2 sha256:fb261a8
+	r3 sha256:cb2649b
+	r4 sha256:958577e
+
+	# removed (deleted)
+	d1 sha1:7657159
+	d2 sha1:43d84d3
+	d3 sha1:a740396
+	d1 sha256:e312513
+	d2 sha256:eb19258
+	d3 sha256:1ccb3c1
+
+	# added
+	a1 sha1:2716022
+	a2 sha1:b62accd
+	a3 sha1:df46cfa
+	a4 sha1:3e64548
+	a5 sha1:12b4063
+	a1 sha256:d724f4d
+	a2 sha256:1de7762
+	a3 sha256:e159431
+	a4 sha256:b3e483c
+	a5 sha256:90866a7
+
+	# rebased
+	b1 sha1:cc9c443
+	b2 sha1:c5d9641
+	b3 sha1:28cc2b6
+	b4 sha1:5628ab7
+	b5 sha1:a31b12e
+	b1 sha256:a1a8717
+	b2 sha256:20a5862
+	b3 sha256:587172a
+	b4 sha256:2721c5d
+	b5 sha256:7b57864
+
+	# changed
+	c1 sha1:a4b3333
+	c2 sha1:f51d370
+	c3 sha1:0559556
+	c4 sha1:d966c5c
+	c1 sha256:f8c2b9d
+	c2 sha256:3fb6318
+	c3 sha256:168ab68
+	c4 sha256:3526539
+
+	# changed-message
+	m1 sha1:f686024
+	m2 sha1:4ab067d
+	m3 sha1:b9cb956
+	m4 sha1:8add5f1
+	m1 sha256:31e6281
+	m2 sha256:a06bf1b
+	m3 sha256:82dc654
+	m4 sha256:48470c5
+
+	# renamed
+	n1 sha1:f258d75
+	n2 sha1:017b62d
+	n3 sha1:3ce7af6
+	n4 sha1:1e6226b
+	n1 sha256:ad52114
+	n2 sha256:3b54c8f
+	n3 sha256:3b0a644
+	n4 sha256:e461653
+
+	# added and removed
+	s1 sha1:096b1ba
+	s2 sha1:d92e698
+	s3 sha1:9a1db4d
+	s4 sha1:fea3b5c
+	s1 sha256:a7f9134
+	s2 sha256:b4c2580
+	s3 sha256:1d62aa2
+	s4 sha256:48160e8
+
+	# Empty delimiter (included so lines match neatly)
+	__ sha1:-------
+	__ sha256:-------
+	EOF
 '
 
 test_expect_success 'simple A..B A..C (unmodified)' '
 	git range-diff --no-color master..topic master..unmodified \
 		>actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  35b9b25 s/5/A/
-	2:  fccce22 = 2:  de345ab s/4/A/
-	3:  147e64e = 3:  9af6654 s/11/B/
-	4:  a63e992 = 4:  2901f77 s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid u1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid u2) s/4/A/
+	3:  $(test_oid t3) = 3:  $(test_oid u3) s/11/B/
+	4:  $(test_oid t4) = 4:  $(test_oid u4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -38,10 +145,10 @@ test_expect_success 'simple A B C (unmodified)' '
 test_expect_success 'trivial reordering' '
 	git range-diff --no-color master topic reordered >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  aca177a s/5/A/
-	3:  147e64e = 2:  14ad629 s/11/B/
-	4:  a63e992 = 3:  ee58208 s/12/B/
-	2:  fccce22 = 4:  307b27a s/4/A/
+	1:  $(test_oid t1) = 1:  $(test_oid r1) s/5/A/
+	3:  $(test_oid t3) = 2:  $(test_oid r2) s/11/B/
+	4:  $(test_oid t4) = 3:  $(test_oid r3) s/12/B/
+	2:  $(test_oid t2) = 4:  $(test_oid r4) s/4/A/
 	EOF
 	test_cmp expected actual
 '
@@ -49,10 +156,10 @@ test_expect_success 'trivial reordering' '
 test_expect_success 'removed a commit' '
 	git range-diff --no-color master topic removed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  7657159 s/5/A/
-	2:  fccce22 < -:  ------- s/4/A/
-	3:  147e64e = 2:  43d84d3 s/11/B/
-	4:  a63e992 = 3:  a740396 s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid d1) s/5/A/
+	2:  $(test_oid t2) < -:  $(test_oid __) s/4/A/
+	3:  $(test_oid t3) = 2:  $(test_oid d2) s/11/B/
+	4:  $(test_oid t4) = 3:  $(test_oid d3) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -60,11 +167,11 @@ test_expect_success 'removed a commit' '
 test_expect_success 'added a commit' '
 	git range-diff --no-color master topic added >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  2716022 s/5/A/
-	2:  fccce22 = 2:  b62accd s/4/A/
-	-:  ------- > 3:  df46cfa s/6/A/
-	3:  147e64e = 4:  3e64548 s/11/B/
-	4:  a63e992 = 5:  12b4063 s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid a1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid a2) s/4/A/
+	-:  $(test_oid __) > 3:  $(test_oid a3) s/6/A/
+	3:  $(test_oid t3) = 4:  $(test_oid a4) s/11/B/
+	4:  $(test_oid t4) = 5:  $(test_oid a5) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -72,10 +179,10 @@ test_expect_success 'added a commit' '
 test_expect_success 'new base, A B C' '
 	git range-diff --no-color master topic rebased >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  cc9c443 s/5/A/
-	2:  fccce22 = 2:  c5d9641 s/4/A/
-	3:  147e64e = 3:  28cc2b6 s/11/B/
-	4:  a63e992 = 4:  5628ab7 s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid b1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid b2) s/4/A/
+	3:  $(test_oid t3) = 3:  $(test_oid b3) s/11/B/
+	4:  $(test_oid t4) = 4:  $(test_oid b4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -84,11 +191,11 @@ test_expect_success 'new base, B...C' '
 	# this syntax includes the commits from master!
 	git range-diff --no-color topic...rebased >actual &&
 	cat >expected <<-EOF &&
-	-:  ------- > 1:  a31b12e unrelated
-	1:  4de457d = 2:  cc9c443 s/5/A/
-	2:  fccce22 = 3:  c5d9641 s/4/A/
-	3:  147e64e = 4:  28cc2b6 s/11/B/
-	4:  a63e992 = 5:  5628ab7 s/12/B/
+	-:  $(test_oid __) > 1:  $(test_oid b5) unrelated
+	1:  $(test_oid t1) = 2:  $(test_oid b1) s/5/A/
+	2:  $(test_oid t2) = 3:  $(test_oid b2) s/4/A/
+	3:  $(test_oid t3) = 4:  $(test_oid b3) s/11/B/
+	4:  $(test_oid t4) = 5:  $(test_oid b4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -96,9 +203,9 @@ test_expect_success 'new base, B...C' '
 test_expect_success 'changed commit' '
 	git range-diff --no-color topic...changed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  a4b3333 s/5/A/
-	2:  fccce22 = 2:  f51d370 s/4/A/
-	3:  147e64e ! 3:  0559556 s/11/B/
+	1:  $(test_oid t1) = 1:  $(test_oid c1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid c2) s/4/A/
+	3:  $(test_oid t3) ! 3:  $(test_oid c3) s/11/B/
 	    @@ file: A
 	      9
 	      10
@@ -108,7 +215,7 @@ test_expect_success 'changed commit' '
 	      12
 	      13
 	      14
-	4:  a63e992 ! 4:  d966c5c s/12/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid c4) s/12/B/
 	    @@ file
 	     @@ file: A
 	      9
@@ -125,10 +232,10 @@ test_expect_success 'changed commit' '
 test_expect_success 'changed commit with --no-patch diff option' '
 	git range-diff --no-color --no-patch topic...changed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  a4b3333 s/5/A/
-	2:  fccce22 = 2:  f51d370 s/4/A/
-	3:  147e64e ! 3:  0559556 s/11/B/
-	4:  a63e992 ! 4:  d966c5c s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid c1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid c2) s/4/A/
+	3:  $(test_oid t3) ! 3:  $(test_oid c3) s/11/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid c4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -136,16 +243,16 @@ test_expect_success 'changed commit with --no-patch diff option' '
 test_expect_success 'changed commit with --stat diff option' '
 	git range-diff --no-color --stat topic...changed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  a4b3333 s/5/A/
+	1:  $(test_oid t1) = 1:  $(test_oid c1) s/5/A/
 	     a => b | 0
 	     1 file changed, 0 insertions(+), 0 deletions(-)
-	2:  fccce22 = 2:  f51d370 s/4/A/
+	2:  $(test_oid t2) = 2:  $(test_oid c2) s/4/A/
 	     a => b | 0
 	     1 file changed, 0 insertions(+), 0 deletions(-)
-	3:  147e64e ! 3:  0559556 s/11/B/
+	3:  $(test_oid t3) ! 3:  $(test_oid c3) s/11/B/
 	     a => b | 0
 	     1 file changed, 0 insertions(+), 0 deletions(-)
-	4:  a63e992 ! 4:  d966c5c s/12/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid c4) s/12/B/
 	     a => b | 0
 	     1 file changed, 0 insertions(+), 0 deletions(-)
 	EOF
@@ -155,9 +262,9 @@ test_expect_success 'changed commit with --stat diff option' '
 test_expect_success 'changed commit with sm config' '
 	git range-diff --no-color --submodule=log topic...changed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  a4b3333 s/5/A/
-	2:  fccce22 = 2:  f51d370 s/4/A/
-	3:  147e64e ! 3:  0559556 s/11/B/
+	1:  $(test_oid t1) = 1:  $(test_oid c1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid c2) s/4/A/
+	3:  $(test_oid t3) ! 3:  $(test_oid c3) s/11/B/
 	    @@ file: A
 	      9
 	      10
@@ -167,7 +274,7 @@ test_expect_success 'changed commit with sm config' '
 	      12
 	      13
 	      14
-	4:  a63e992 ! 4:  d966c5c s/12/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid c4) s/12/B/
 	    @@ file
 	     @@ file: A
 	      9
@@ -184,8 +291,8 @@ test_expect_success 'changed commit with sm config' '
 test_expect_success 'renamed file' '
 	git range-diff --no-color --submodule=log topic...renamed-file >actual &&
 	sed s/Z/\ /g >expected <<-EOF &&
-	1:  4de457d = 1:  f258d75 s/5/A/
-	2:  fccce22 ! 2:  017b62d s/4/A/
+	1:  $(test_oid t1) = 1:  $(test_oid n1) s/5/A/
+	2:  $(test_oid t2) ! 2:  $(test_oid n2) s/4/A/
 	    @@ Metadata
 	    ZAuthor: Thomas Rast <trast@inf.ethz.ch>
 	    Z
@@ -198,7 +305,7 @@ test_expect_success 'renamed file' '
 	    Z@@
 	    Z 1
 	    Z 2
-	3:  147e64e ! 3:  3ce7af6 s/11/B/
+	3:  $(test_oid t3) ! 3:  $(test_oid n3) s/11/B/
 	    @@ Metadata
 	    Z ## Commit message ##
 	    Z    s/11/B/
@@ -210,7 +317,7 @@ test_expect_success 'renamed file' '
 	    Z 8
 	    Z 9
 	    Z 10
-	4:  a63e992 ! 4:  1e6226b s/12/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid n4) s/12/B/
 	    @@ Metadata
 	    Z ## Commit message ##
 	    Z    s/12/B/
@@ -229,8 +336,8 @@ test_expect_success 'renamed file' '
 test_expect_success 'file added and later removed' '
 	git range-diff --no-color --submodule=log topic...added-removed >actual &&
 	sed s/Z/\ /g >expected <<-EOF &&
-	1:  4de457d = 1:  096b1ba s/5/A/
-	2:  fccce22 ! 2:  d92e698 s/4/A/
+	1:  $(test_oid t1) = 1:  $(test_oid s1) s/5/A/
+	2:  $(test_oid t2) ! 2:  $(test_oid s2) s/4/A/
 	    @@ Metadata
 	    ZAuthor: Thomas Rast <trast@inf.ethz.ch>
 	    Z
@@ -246,7 +353,7 @@ test_expect_success 'file added and later removed' '
 	    Z 7
 	    +
 	    + ## new-file (new) ##
-	3:  147e64e ! 3:  9a1db4d s/11/B/
+	3:  $(test_oid t3) ! 3:  $(test_oid s3) s/11/B/
 	    @@ Metadata
 	    ZAuthor: Thomas Rast <trast@inf.ethz.ch>
 	    Z
@@ -262,7 +369,7 @@ test_expect_success 'file added and later removed' '
 	    Z 14
 	    +
 	    + ## new-file (deleted) ##
-	4:  a63e992 = 4:  fea3b5c s/12/B/
+	4:  $(test_oid t4) = 4:  $(test_oid s4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -275,8 +382,8 @@ test_expect_success 'no commits on one side' '
 test_expect_success 'changed message' '
 	git range-diff --no-color topic...changed-message >actual &&
 	sed s/Z/\ /g >expected <<-EOF &&
-	1:  4de457d = 1:  f686024 s/5/A/
-	2:  fccce22 ! 2:  4ab067d s/4/A/
+	1:  $(test_oid t1) = 1:  $(test_oid m1) s/5/A/
+	2:  $(test_oid t2) ! 2:  $(test_oid m2) s/4/A/
 	    @@ Metadata
 	    Z ## Commit message ##
 	    Z    s/4/A/
@@ -286,16 +393,16 @@ test_expect_success 'changed message' '
 	    Z ## file ##
 	    Z@@
 	    Z 1
-	3:  147e64e = 3:  b9cb956 s/11/B/
-	4:  a63e992 = 4:  8add5f1 s/12/B/
+	3:  $(test_oid t3) = 3:  $(test_oid m3) s/11/B/
+	4:  $(test_oid t4) = 4:  $(test_oid m4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
 
 test_expect_success 'dual-coloring' '
-	sed -e "s|^:||" >expect <<-\EOF &&
-	:<YELLOW>1:  a4b3333 = 1:  f686024 s/5/A/<RESET>
-	:<RED>2:  f51d370 <RESET><YELLOW>!<RESET><GREEN> 2:  4ab067d<RESET><YELLOW> s/4/A/<RESET>
+	sed -e "s|^:||" >expect <<-EOF &&
+	:<YELLOW>1:  $(test_oid c1) = 1:  $(test_oid m1) s/5/A/<RESET>
+	:<RED>2:  $(test_oid c2) <RESET><YELLOW>!<RESET><GREEN> 2:  $(test_oid m2)<RESET><YELLOW> s/4/A/<RESET>
 	:    <REVERSE><CYAN>@@<RESET> <RESET>Metadata<RESET>
 	:      ## Commit message ##<RESET>
 	:         s/4/A/<RESET>
@@ -305,7 +412,7 @@ test_expect_success 'dual-coloring' '
 	:      ## file ##<RESET>
 	:    <CYAN> @@<RESET>
 	:      1<RESET>
-	:<RED>3:  0559556 <RESET><YELLOW>!<RESET><GREEN> 3:  b9cb956<RESET><YELLOW> s/11/B/<RESET>
+	:<RED>3:  $(test_oid c3) <RESET><YELLOW>!<RESET><GREEN> 3:  $(test_oid m3)<RESET><YELLOW> s/11/B/<RESET>
 	:    <REVERSE><CYAN>@@<RESET> <RESET>file: A<RESET>
 	:      9<RESET>
 	:      10<RESET>
@@ -315,7 +422,7 @@ test_expect_success 'dual-coloring' '
 	:      12<RESET>
 	:      13<RESET>
 	:      14<RESET>
-	:<RED>4:  d966c5c <RESET><YELLOW>!<RESET><GREEN> 4:  8add5f1<RESET><YELLOW> s/12/B/<RESET>
+	:<RED>4:  $(test_oid c4) <RESET><YELLOW>!<RESET><GREEN> 4:  $(test_oid m4)<RESET><YELLOW> s/12/B/<RESET>
 	:    <REVERSE><CYAN>@@<RESET> <RESET>file<RESET>
 	:    <CYAN> @@ file: A<RESET>
 	:      9<RESET>

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

* [PATCH 03/14] t3301: abstract away SHA-1-specific constants
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
  2019-08-18 19:16 ` [PATCH 01/14] t3201: abstract away SHA-1-specific constants brian m. carlson
  2019-08-18 19:16 ` [PATCH 02/14] t3206: abstract away hash size constants brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 04/14] t3305: make hash size independent brian m. carlson
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.  Move some invocations of test_commit around so
that we can compute the object IDs for these commits.

Compute several object IDs in the tests instead of using hard-coded
values so that the test works with any hash algorithm.  Since the actual
values are sorted by the object ID of the object being annotated, sort
the expected values accordingly as well.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3301-notes.sh | 140 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 90 insertions(+), 50 deletions(-)

diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index 704bbc6541..d3fa298c6a 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -66,8 +66,9 @@ test_expect_success 'show notes entry with %N' '
 '
 
 test_expect_success 'create reflog entry' '
+	ref=$(git rev-parse --short refs/notes/commits) &&
 	cat <<-EOF >expect &&
-		a1d8fa6 refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
+		$ref refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
 	EOF
 	git reflog show refs/notes/commits >actual &&
 	test_cmp expect actual
@@ -134,8 +135,9 @@ test_expect_success 'can overwrite existing note with "git notes add -f"' '
 '
 
 test_expect_success 'show notes' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 7a4ca6ee52a974a66cbaa78e33214535dff1d691
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:14:13 2005 -0700
 
@@ -152,8 +154,9 @@ test_expect_success 'show notes' '
 test_expect_success 'show multi-line notes' '
 	test_commit 3rd &&
 	MSG="b3${LF}c3c3c3c3${LF}d3d3d3" git notes add &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-multiline <<-EOF &&
-		commit d07d62e5208f22eb5695e7eb47667dc8b9860290
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:15:13 2005 -0700
 
@@ -174,8 +177,9 @@ test_expect_success 'show -F notes' '
 	test_commit 4th &&
 	echo "xyzzy" >note5 &&
 	git notes add -F note5 &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-F <<-EOF &&
-		commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:16:13 2005 -0700
 
@@ -198,10 +202,13 @@ test_expect_success 'Re-adding -F notes without -f fails' '
 '
 
 test_expect_success 'git log --pretty=raw does not show notes' '
+	commit=$(git rev-parse HEAD) &&
+	tree=$(git rev-parse HEAD^{tree}) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
-		tree 05ac65288c4c4b3b709a020ae94b2ece2f2201ae
-		parent d07d62e5208f22eb5695e7eb47667dc8b9860290
+		commit $commit
+		tree $tree
+		parent $parent
 		author A U Thor <author@example.com> 1112912173 -0700
 		committer C O Mitter <committer@example.com> 1112912173 -0700
 
@@ -291,8 +298,9 @@ test_expect_success 'git log --no-notes resets ref list' '
 test_expect_success 'show -m notes' '
 	test_commit 5th &&
 	git notes add -m spam -m "foo${LF}bar${LF}baz" &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-m <<-EOF &&
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
@@ -313,8 +321,9 @@ test_expect_success 'show -m notes' '
 
 test_expect_success 'remove note with add -f -F /dev/null' '
 	git notes add -f -F /dev/null &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-rm-F <<-EOF &&
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
@@ -356,14 +365,16 @@ test_expect_success 'create note with combination of -m and -F' '
 test_expect_success 'remove note with "git notes remove"' '
 	git notes remove HEAD^ &&
 	git notes remove &&
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect-rm-remove <<-EOF &&
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
 		${indent}5th
 
-		commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:16:13 2005 -0700
 
@@ -459,9 +470,11 @@ test_expect_success 'removing with --stdin --ignore-missing' '
 '
 
 test_expect_success 'list notes with "git notes list"' '
-	cat >expect <<-EOF &&
-		c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691
-		c18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290
+	commit_2=$(git rev-parse 2nd) &&
+	commit_3=$(git rev-parse 3rd) &&
+	sort -t" " -k2 >expect <<-EOF &&
+		$(git rev-parse refs/notes/commits:$commit_2) $commit_2
+		$(git rev-parse refs/notes/commits:$commit_3) $commit_3
 	EOF
 	git notes list >actual &&
 	test_cmp expect actual
@@ -474,7 +487,7 @@ test_expect_success 'list notes with "git notes"' '
 
 test_expect_success 'list specific note with "git notes list <object>"' '
 	cat >expect <<-EOF &&
-		c18dc024e14f08d18d14eea0d747ff692d66d6a3
+		$(git rev-parse refs/notes/commits:$commit_3)
 	EOF
 	git notes list HEAD^^ >actual &&
 	test_cmp expect actual
@@ -498,10 +511,11 @@ test_expect_success 'append to existing note with "git notes append"' '
 '
 
 test_expect_success '"git notes list" does not expand to "git notes list HEAD"' '
-	cat >expect_list <<-EOF &&
-		c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691
-		4b6ad22357cc8a1296720574b8d2fbc22fab0671 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
-		c18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290
+	commit_5=$(git rev-parse 5th) &&
+	sort -t" " -k2 >expect_list <<-EOF &&
+		$(git rev-parse refs/notes/commits:$commit_2) $commit_2
+		$(git rev-parse refs/notes/commits:$commit_3) $commit_3
+		$(git rev-parse refs/notes/commits:$commit_5) $commit_5
 	EOF
 	git notes list >actual &&
 	test_cmp expect_list actual
@@ -531,8 +545,9 @@ test_expect_success 'appending empty string to non-existing note does not create
 test_expect_success 'create other note on a different notes ref (setup)' '
 	test_commit 6th &&
 	GIT_NOTES_REF="refs/notes/other" git notes add -m "other note" &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-not-other <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
@@ -569,8 +584,10 @@ test_expect_success 'Do not show note when core.notesRef is overridden' '
 '
 
 test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect-both <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
@@ -582,7 +599,7 @@ test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
 		Notes (other):
 		${indent}other note
 
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
@@ -616,8 +633,9 @@ test_expect_success 'notes.displayRef can be given more than once' '
 '
 
 test_expect_success 'notes.displayRef respects order' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-both-reversed <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
@@ -642,14 +660,16 @@ test_expect_success 'GIT_NOTES_DISPLAY_REF works' '
 '
 
 test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect-none <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
 		${indent}6th
 
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
@@ -666,8 +686,9 @@ test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
 '
 
 test_expect_success '--no-standard-notes' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-commits <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
@@ -712,8 +733,10 @@ test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
 '
 
 test_expect_success 'create note from other note with "git notes add -C"' '
+	test_commit 7th &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit fb01e0ca8c33b6cc0c6451dde747f97df567cb5c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:19:13 2005 -0700
 
@@ -722,7 +745,6 @@ test_expect_success 'create note from other note with "git notes add -C"' '
 		Notes:
 		${indent}order test
 	EOF
-	test_commit 7th &&
 	git notes add -C $(git notes list HEAD^) &&
 	git log -1 >actual &&
 	test_cmp expect actual &&
@@ -744,8 +766,9 @@ test_expect_success 'create note from non-blob with "git notes add -C" fails' '
 '
 
 test_expect_success 'create note from blob with "git notes add -C" reuses blob id' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 9a4c31c7f722b5d517e92c64e932dd751e1413bf
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:20:13 2005 -0700
 
@@ -762,8 +785,10 @@ test_expect_success 'create note from blob with "git notes add -C" reuses blob i
 '
 
 test_expect_success 'create note from other note with "git notes add -c"' '
+	test_commit 9th &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 2e0db4bc649e174d667a1cde19e725cf897a5bd2
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:21:13 2005 -0700
 
@@ -772,7 +797,6 @@ test_expect_success 'create note from other note with "git notes add -c"' '
 		Notes:
 		${indent}yet another note
 	EOF
-	test_commit 9th &&
 	MSG="yet another note" git notes add -c $(git notes list HEAD^^) &&
 	git log -1 >actual &&
 	test_cmp expect actual
@@ -785,8 +809,9 @@ test_expect_success 'create note from non-existing note with "git notes add -c"
 '
 
 test_expect_success 'append to note from other note with "git notes append -C"' '
+	commit=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit 2e0db4bc649e174d667a1cde19e725cf897a5bd2
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:21:13 2005 -0700
 
@@ -803,8 +828,9 @@ test_expect_success 'append to note from other note with "git notes append -C"'
 '
 
 test_expect_success 'create note from other note with "git notes append -c"' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:22:13 2005 -0700
 
@@ -819,8 +845,9 @@ test_expect_success 'create note from other note with "git notes append -c"' '
 '
 
 test_expect_success 'append to note from other note with "git notes append -c"' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:22:13 2005 -0700
 
@@ -837,8 +864,10 @@ test_expect_success 'append to note from other note with "git notes append -c"'
 '
 
 test_expect_success 'copy note with "git notes copy"' '
+	test_commit 11th &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:23:13 2005 -0700
 
@@ -849,7 +878,6 @@ test_expect_success 'copy note with "git notes copy"' '
 		${indent}
 		${indent}yet another note
 	EOF
-	test_commit 11th &&
 	git notes copy HEAD^ HEAD &&
 	git log -1 >actual &&
 	test_cmp expect actual &&
@@ -864,8 +892,9 @@ test_expect_success 'prevent overwrite with "git notes copy"' '
 '
 
 test_expect_success 'allow overwrite with "git notes copy -f"' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:23:13 2005 -0700
 
@@ -889,8 +918,10 @@ test_expect_success 'cannot copy note from object without notes' '
 '
 
 test_expect_success 'git notes copy --stdin' '
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit e871aa61182b1d95d0a6fb75445d891722863b6b
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:25:13 2005 -0700
 
@@ -901,7 +932,7 @@ test_expect_success 'git notes copy --stdin' '
 		${indent}
 		${indent}yet another note
 
-		commit 65e263ded02ae4e8839bc151095113737579dc12
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:24:13 2005 -0700
 
@@ -922,21 +953,23 @@ test_expect_success 'git notes copy --stdin' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
+	test_commit 14th &&
+	test_commit 15th &&
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
 		${indent}15th
 
-		commit 07c85d77059393ed0154b8c96906547a59dfcddd
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:26:13 2005 -0700
 
 		${indent}14th
 	EOF
-	test_commit 14th &&
-	test_commit 15th &&
 	(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
 	echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
 	git notes copy --for-rewrite=foo &&
@@ -945,8 +978,10 @@ test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (enabled)' '
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -957,7 +992,7 @@ test_expect_success 'git notes copy --for-rewrite (enabled)' '
 		${indent}
 		${indent}yet another note
 
-		commit 07c85d77059393ed0154b8c96906547a59dfcddd
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:26:13 2005 -0700
 
@@ -986,8 +1021,9 @@ test_expect_success 'git notes copy --for-rewrite (disabled)' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (overwrite)' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -1015,8 +1051,9 @@ test_expect_success 'git notes copy --for-rewrite (ignore)' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (append)' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -1037,8 +1074,9 @@ test_expect_success 'git notes copy --for-rewrite (append)' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (append two to one)' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -1075,8 +1113,9 @@ test_expect_success 'git notes copy --for-rewrite (append empty)' '
 '
 
 test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -1095,8 +1134,9 @@ test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
 '
 
 test_expect_success 'GIT_NOTES_REWRITE_REF works' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 

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

* [PATCH 04/14] t3305: make hash size independent
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (2 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 03/14] t3301: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 05/14] t3306: abstract away SHA-1-specific constants brian m. carlson
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Instead of hard-coding 40-character shell patterns, use grep to
determine if all of the paths have either zero or one levels of fanout,
as appropriate.

Note that the final test is implicitly dependent on the hash algorithm.
Depending on the algorithm in use, the fanout may or may not completely
compress.  In its current state, this is not a problem, but it could be
if the hash algorithm changes again.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3305-notes-fanout.sh | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh
index 54460beec4..831f83d211 100755
--- a/t/t3305-notes-fanout.sh
+++ b/t/t3305-notes-fanout.sh
@@ -35,15 +35,10 @@ test_expect_success 'many notes created with git-notes triggers fanout' '
 	git ls-tree -r --name-only refs/notes/commits |
 	while read path
 	do
-		case "$path" in
-		??/??????????????????????????????????????)
-			: true
-			;;
-		*)
+		echo $path | grep "^../[0-9a-f]*$" || {
 			echo "Invalid path \"$path\"" &&
-			return 1
-			;;
-		esac
+			return 1;
+		}
 	done
 '
 
@@ -77,15 +72,10 @@ test_expect_success 'deleting most notes triggers fanout consolidation' '
 	git ls-tree -r --name-only refs/notes/commits |
 	while read path
 	do
-		case "$path" in
-		????????????????????????????????????????)
-			: true
-			;;
-		*)
+		echo $path | grep -v "^../.*" || {
 			echo "Invalid path \"$path\"" &&
-			return 1
-			;;
-		esac
+			return 1;
+		}
 	done
 '
 

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

* [PATCH 05/14] t3306: abstract away SHA-1-specific constants
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (3 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 04/14] t3305: make hash size independent brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 06/14] t3404: " brian m. carlson
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.  Convert some single-line heredocs into inline
uses of echo now that they can be expressed succinctly.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3306-notes-prune.sh | 45 ++++++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh
index 61748088eb..8f4102ff9e 100755
--- a/t/t3306-notes-prune.sh
+++ b/t/t3306-notes-prune.sh
@@ -11,23 +11,26 @@ test_expect_success 'setup: create a few commits with notes' '
 	test_tick &&
 	git commit -m 1st &&
 	git notes add -m "Note #1" &&
+	first=$(git rev-parse HEAD) &&
 	: > file2 &&
 	git add file2 &&
 	test_tick &&
 	git commit -m 2nd &&
 	git notes add -m "Note #2" &&
+	second=$(git rev-parse HEAD) &&
 	: > file3 &&
 	git add file3 &&
 	test_tick &&
 	git commit -m 3rd &&
-	COMMIT_FILE=.git/objects/5e/e1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
+	third=$(git rev-parse HEAD) &&
+	COMMIT_FILE=$(echo $third | sed "s!^..!.git/objects/&/!") &&
 	test -f $COMMIT_FILE &&
 	test-tool chmtime =+0 $COMMIT_FILE &&
 	git notes add -m "Note #3"
 '
 
 cat > expect <<END_OF_LOG
-commit 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
+commit $third
 Author: A U Thor <author@example.com>
 Date:   Thu Apr 7 15:15:13 2005 -0700
 
@@ -36,7 +39,7 @@ Date:   Thu Apr 7 15:15:13 2005 -0700
 Notes:
     Note #3
 
-commit 08341ad9e94faa089d60fd3f523affb25c6da189
+commit $second
 Author: A U Thor <author@example.com>
 Date:   Thu Apr 7 15:14:13 2005 -0700
 
@@ -45,7 +48,7 @@ Date:   Thu Apr 7 15:14:13 2005 -0700
 Notes:
     Note #2
 
-commit ab5f302035f2e7aaf04265f08b42034c23256e1f
+commit $first
 Author: A U Thor <author@example.com>
 Date:   Thu Apr 7 15:13:13 2005 -0700
 
@@ -70,16 +73,16 @@ test_expect_success 'remove some commits' '
 
 test_expect_success 'verify that commits are gone' '
 
-	test_must_fail git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
-	git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 &&
-	git cat-file -p ab5f302035f2e7aaf04265f08b42034c23256e1f
+	test_must_fail git cat-file -p $third &&
+	git cat-file -p $second &&
+	git cat-file -p $first
 '
 
 test_expect_success 'verify that notes are still present' '
 
-	git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
-	git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
-	git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+	git notes show $third &&
+	git notes show $second &&
+	git notes show $first
 '
 
 test_expect_success 'prune -n does not remove notes' '
@@ -90,13 +93,10 @@ test_expect_success 'prune -n does not remove notes' '
 	test_cmp expect actual
 '
 
-cat > expect <<EOF
-5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
-EOF
 
 test_expect_success 'prune -n lists prunable notes' '
 
-
+	echo $third >expect &&
 	git notes prune -n > actual &&
 	test_cmp expect actual
 '
@@ -109,9 +109,9 @@ test_expect_success 'prune notes' '
 
 test_expect_success 'verify that notes are gone' '
 
-	test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
-	git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
-	git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+	test_must_fail git notes show $third &&
+	git notes show $second &&
+	git notes show $first
 '
 
 test_expect_success 'remove some commits' '
@@ -121,21 +121,18 @@ test_expect_success 'remove some commits' '
 	git gc --prune=now
 '
 
-cat > expect <<EOF
-08341ad9e94faa089d60fd3f523affb25c6da189
-EOF
-
 test_expect_success 'prune -v notes' '
 
+	echo $second >expect &&
 	git notes prune -v > actual &&
 	test_cmp expect actual
 '
 
 test_expect_success 'verify that notes are gone' '
 
-	test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
-	test_must_fail git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
-	git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+	test_must_fail git notes show $third &&
+	test_must_fail git notes show $second &&
+	git notes show $first
 '
 
 test_done

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

* [PATCH 06/14] t3404: abstract away SHA-1-specific constants
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (4 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 05/14] t3306: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 07/14] t3430: avoid hard-coded object IDs brian m. carlson
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.  Add a use of $EMPTY_TREE instead of a
hard-coded value.  Remove a comment about hard-coded hashes which is no
longer applicable.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3404-rebase-interactive.sh | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 461dd539ff..87ee69f78e 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -29,9 +29,6 @@ Initial setup:
 
 . "$TEST_DIRECTORY"/lib-rebase.sh
 
-# WARNING: Modifications to the initial repository can change the SHA ID used
-# in the expect2 file for the 'stop on conflicting pick' test.
-
 test_expect_success 'setup' '
 	test_commit A file1 &&
 	test_commit B file1 &&
@@ -233,25 +230,28 @@ test_expect_success 'exchange two commits' '
 	set_fake_editor &&
 	FAKE_LINES="2 1" git rebase -i HEAD~2 &&
 	test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
-	test G = $(git cat-file commit HEAD | sed -ne \$p)
+	test G = $(git cat-file commit HEAD | sed -ne \$p) &&
+	blob1=$(git rev-parse --short HEAD^:file1) &&
+	blob2=$(git rev-parse --short HEAD:file1) &&
+	commit=$(git rev-parse --short HEAD)
 '
 
 test_expect_success 'stop on conflicting pick' '
-	cat >expect <<-\EOF &&
+	cat >expect <<-EOF &&
 	diff --git a/file1 b/file1
-	index f70f10e..fd79235 100644
+	index $blob1..$blob2 100644
 	--- a/file1
 	+++ b/file1
 	@@ -1 +1 @@
 	-A
 	+G
 	EOF
-	cat >expect2 <<-\EOF &&
+	cat >expect2 <<-EOF &&
 	<<<<<<< HEAD
 	D
 	=======
 	G
-	>>>>>>> 5d18e54... G
+	>>>>>>> $commit... G
 	EOF
 	git tag new-branch1 &&
 	set_fake_editor &&
@@ -1003,7 +1003,7 @@ test_expect_success 'rebase -i --root temporary sentinel commit' '
 	git checkout B &&
 	set_fake_editor &&
 	test_must_fail env FAKE_LINES="2" git rebase -i --root &&
-	git cat-file commit HEAD | grep "^tree 4b825dc642cb" &&
+	git cat-file commit HEAD | grep "^tree $EMPTY_TREE" &&
 	git rebase --abort
 '
 
@@ -1161,7 +1161,7 @@ test_expect_success 'rebase -i error on commits with \ in message' '
 	test_expect_code 1 grep  "	emp" error
 '
 
-test_expect_success 'short SHA-1 setup' '
+test_expect_success SHA1 'short SHA-1 setup' '
 	test_when_finished "git checkout master" &&
 	git checkout --orphan collide &&
 	git rm -rf . &&
@@ -1173,7 +1173,7 @@ test_expect_success 'short SHA-1 setup' '
 	)
 '
 
-test_expect_success 'short SHA-1 collide' '
+test_expect_success SHA1 'short SHA-1 collide' '
 	test_when_finished "reset_rebase && git checkout master" &&
 	git checkout collide &&
 	(

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

* [PATCH 07/14] t3430: avoid hard-coded object IDs
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (5 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 06/14] t3404: " brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 08/14] t3506: make hash independent brian m. carlson
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Compute the object IDs used in the todo list instead of hard-coding
them.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3430-rebase-merges.sh | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 7b6c4847ad..c1ea2ee297 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -37,20 +37,27 @@ test_expect_success 'setup' '
 	test_commit A &&
 	git checkout -b first &&
 	test_commit B &&
+	b=$(git rev-parse --short HEAD) &&
 	git checkout master &&
 	test_commit C &&
+	c=$(git rev-parse --short HEAD) &&
 	test_commit D &&
+	d=$(git rev-parse --short HEAD) &&
 	git merge --no-commit B &&
 	test_tick &&
 	git commit -m E &&
 	git tag -m E E &&
+	e=$(git rev-parse --short HEAD) &&
 	git checkout -b second C &&
 	test_commit F &&
+	f=$(git rev-parse --short HEAD) &&
 	test_commit G &&
+	g=$(git rev-parse --short HEAD) &&
 	git checkout master &&
 	git merge --no-commit G &&
 	test_tick &&
 	git commit -m H &&
+	h=$(git rev-parse --short HEAD) &&
 	git tag -m H H &&
 	git checkout A &&
 	test_commit conflicting-G G.t
@@ -93,24 +100,24 @@ test_expect_success 'create completely different structure' '
 '
 
 test_expect_success 'generate correct todo list' '
-	cat >expect <<-\EOF &&
+	cat >expect <<-EOF &&
 	label onto
 
 	reset onto
-	pick d9df450 B
+	pick $b B
 	label E
 
 	reset onto
-	pick 5dee784 C
+	pick $c C
 	label branch-point
-	pick ca2c861 F
-	pick 088b00a G
+	pick $f F
+	pick $g G
 	label H
 
 	reset branch-point # C
-	pick 12bd07b D
-	merge -C 2051b56 E # E
-	merge -C 233d48a H # H
+	pick $d D
+	merge -C $e E # E
+	merge -C $h H # H
 
 	EOF
 

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

* [PATCH 08/14] t3506: make hash independent
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (6 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 07/14] t3430: avoid hard-coded object IDs brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 09/14] t3600: make hash size independent brian m. carlson
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

This test uses a hard-coded object ID to ensure that the result of
cherry-pick --ff is correct.  Use test_oid to make this work for both
SHA-1 and SHA-256.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3506-cherry-pick-ff.sh | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
index 127dd0082f..9d5adbc130 100755
--- a/t/t3506-cherry-pick-ff.sh
+++ b/t/t3506-cherry-pick-ff.sh
@@ -16,7 +16,11 @@ test_expect_success setup '
 	git add file1 &&
 	test_tick &&
 	git commit -m "second" &&
-	git tag second
+	git tag second &&
+	test_oid_cache <<-EOF
+	cp_ff sha1:1df192cd8bc58a2b275d842cede4d221ad9000d1
+	cp_ff sha256:e70d6b7fc064bddb516b8d512c9057094b96ce6ff08e12080acc4fe7f1d60a1d
+	EOF
 '
 
 test_expect_success 'cherry-pick using --ff fast forwards' '
@@ -102,7 +106,7 @@ test_expect_success 'cherry pick a root commit with --ff' '
 	git add file2 &&
 	git commit --amend -m "file2" &&
 	git cherry-pick --ff first &&
-	test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
+	test "$(git rev-parse --verify HEAD)" = "$(test_oid cp_ff)"
 '
 
 test_expect_success 'cherry-pick --ff on unborn branch' '

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

* [PATCH 09/14] t3600: make hash size independent
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (7 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 08/14] t3506: make hash independent brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 10/14] t3800: make hash-size independent brian m. carlson
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Instead of hard-coding a fixed length invalid object ID in the test,
compute one using the lookup tables.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3600-rm.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 66282a720e..8c8cca5bfb 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -240,12 +240,14 @@ test_expect_success 'refresh index before checking if it is up-to-date' '
 '
 
 test_expect_success 'choking "git rm" should not let it die with cruft' '
+	test_oid_init &&
 	git reset -q --hard &&
 	test_when_finished "rm -f .git/index.lock && git reset -q --hard" &&
 	i=0 &&
+	hash=$(test_oid deadbeef) &&
 	while test $i -lt 12000
 	do
-		echo "100644 1234567890123456789012345678901234567890 0	some-file-$i"
+		echo "100644 $hash 0	some-file-$i"
 		i=$(( $i + 1 ))
 	done | git update-index --index-info &&
 	git rm -n "some-file-*" | : &&

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

* [PATCH 10/14] t3800: make hash-size independent
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (8 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 09/14] t3600: make hash size independent brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 11/14] t3903: abstract away SHA-1-specific constants brian m. carlson
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Replace references to several hard-coded object IDs with a variable
referring to the generated commit.  Avoid matching on exact character
positions, which will be different depending on the hash in use.  In the
test for a valid object ID, use an obviously invalid one from the lookup
table.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3800-mktag.sh | 49 ++++++++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 8eb47942e2..64dcc5ec28 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -23,6 +23,7 @@ check_verify_failure () {
 # first create a commit, so we have a valid object/type
 # for the tag.
 test_expect_success 'setup' '
+	test_oid_init &&
 	echo Hello >A &&
 	git update-index --add A &&
 	git commit -m "Initial commit" &&
@@ -69,28 +70,28 @@ check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
 #  4. type line label check
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
 xxxx tag
 tag mytag
 tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"type" line label check' '^error: char47: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
 
 ############################################################
 #  5. type line eol check
 
-echo "object 779e9b33986b1c2670fff52c5067603117b3e895" >tag.sig
+echo "object $head" >tag.sig
 printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
 
-check_verify_failure '"type" line eol check' '^error: char48: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
 
 ############################################################
 #  6. tag line label check #1
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
 type tag
 xxx mytag
 tagger . <> 0 +0000
@@ -98,37 +99,37 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure '"tag" line label check #1' \
-	'^error: char57: no "tag " found$'
+	'^error: char.*: no "tag " found$'
 
 ############################################################
 #  7. tag line label check #2
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
 type taggggggggggggggggggggggggggggggg
 tag
 EOF
 
 check_verify_failure '"tag" line label check #2' \
-	'^error: char87: no "tag " found$'
+	'^error: char.*: no "tag " found$'
 
 ############################################################
 #  8. type line type-name length check
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
 type taggggggggggggggggggggggggggggggg
 tag mytag
 EOF
 
 check_verify_failure '"type" line type-name length check' \
-	'^error: char53: type too long$'
+	'^error: char.*: type too long$'
 
 ############################################################
 #  9. verify object (SHA1/type) check
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $(test_oid deadbeef)
 type tagggg
 tag mytag
 tagger . <> 0 +0000
@@ -150,7 +151,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error: char67: could not verify tag name$'
+	'^error: char.*: could not verify tag name$'
 
 ############################################################
 # 11. tagger line label check #1
@@ -164,7 +165,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error: char70: could not find "tagger "$'
+	'^error: char.*: could not find "tagger "$'
 
 ############################################################
 # 12. tagger line label check #2
@@ -179,7 +180,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error: char70: could not find "tagger "$'
+	'^error: char.*: could not find "tagger "$'
 
 ############################################################
 # 13. disallow missing tag author name
@@ -194,7 +195,7 @@ This is filler
 EOF
 
 check_verify_failure 'disallow missing tag author name' \
-	'^error: char77: missing tagger name$'
+	'^error: char.*: missing tagger name$'
 
 ############################################################
 # 14. disallow missing tag author name
@@ -209,7 +210,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error: char77: malformed tagger field$'
+	'^error: char.*: malformed tagger field$'
 
 ############################################################
 # 15. allow empty tag email
@@ -238,7 +239,7 @@ tagger T A Gger <tag ger@example.com> 0 +0000
 EOF
 
 check_verify_failure 'disallow spaces in tag email' \
-	'^error: char77: malformed tagger field$'
+	'^error: char.*: malformed tagger field$'
 
 ############################################################
 # 17. disallow missing tag timestamp
@@ -252,7 +253,7 @@ tagger T A Gger <tagger@example.com>__
 EOF
 
 check_verify_failure 'disallow missing tag timestamp' \
-	'^error: char107: missing tag timestamp$'
+	'^error: char.*: missing tag timestamp$'
 
 ############################################################
 # 18. detect invalid tag timestamp1
@@ -266,7 +267,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
 EOF
 
 check_verify_failure 'detect invalid tag timestamp1' \
-	'^error: char107: missing tag timestamp$'
+	'^error: char.*: missing tag timestamp$'
 
 ############################################################
 # 19. detect invalid tag timestamp2
@@ -280,7 +281,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
 EOF
 
 check_verify_failure 'detect invalid tag timestamp2' \
-	'^error: char111: malformed tag timestamp$'
+	'^error: char.*: malformed tag timestamp$'
 
 ############################################################
 # 20. detect invalid tag timezone1
@@ -294,7 +295,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
 EOF
 
 check_verify_failure 'detect invalid tag timezone1' \
-	'^error: char118: malformed tag timezone$'
+	'^error: char.*: malformed tag timezone$'
 
 ############################################################
 # 21. detect invalid tag timezone2
@@ -308,7 +309,7 @@ tagger T A Gger <tagger@example.com> 1206478233 +  30
 EOF
 
 check_verify_failure 'detect invalid tag timezone2' \
-	'^error: char118: malformed tag timezone$'
+	'^error: char.*: malformed tag timezone$'
 
 ############################################################
 # 22. detect invalid tag timezone3
@@ -322,7 +323,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
 EOF
 
 check_verify_failure 'detect invalid tag timezone3' \
-	'^error: char118: malformed tag timezone$'
+	'^error: char.*: malformed tag timezone$'
 
 ############################################################
 # 23. detect invalid header entry
@@ -337,7 +338,7 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error: char124: trailing garbage in tag header$'
+	'^error: char.*: trailing garbage in tag header$'
 
 ############################################################
 # 24. create valid tag

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

* [PATCH 11/14] t3903: abstract away SHA-1-specific constants
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (9 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 10/14] t3800: make hash-size independent brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 20:27   ` Eric Sunshine
  2019-08-18 19:16 ` [PATCH 12/14] t4000: make hash size independent brian m. carlson
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Abstract away the SHA-1-specific constants by sanitizing diff output to
remove the index lines, since it's clear from the assertions in question
that we are not interested in the specific object IDs.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3903-stash.sh | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index b8e337893f..8e3e0992df 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -7,6 +7,18 @@ test_description='Test git stash'
 
 . ./test-lib.sh
 
+diff_cmp () {
+	for i in "$1" "$2"
+	do
+		sed -e 's/^index 0000000\.\.[0-9a-f]*/index 0000000..1234567/' \
+		-e 's/^index [0-9a-f]*\.\.[0-9a-f]*/index 1234567..89abcde/' \
+		-e 's/^index [0-9a-f]*,[0-9a-f]*\.\.[0-9a-f]*/index 1234567,7654321..89abcde/' \
+		"$i" > "$i.compare"
+	done &&
+	test_cmp "$1.compare" "$2.compare" &&
+	rm -f "$1.compare" "$2.compare"
+}
+
 test_expect_success 'stash some dirty working directory' '
 	echo 1 >file &&
 	git add file &&
@@ -36,7 +48,7 @@ EOF
 test_expect_success 'parents of stash' '
 	test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
 	git diff stash^2..stash >output &&
-	test_cmp expect output
+	diff_cmp expect output
 '
 
 test_expect_success 'applying bogus stash does nothing' '
@@ -210,13 +222,13 @@ test_expect_success 'stash branch' '
 	test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
 	test $(git rev-parse HEAD) = $(git rev-parse master^) &&
 	git diff --cached >output &&
-	test_cmp expect output &&
+	diff_cmp expect output &&
 	git diff >output &&
-	test_cmp expect1 output &&
+	diff_cmp expect1 output &&
 	git add file &&
 	git commit -m alternate\ second &&
 	git diff master..stashbranch >output &&
-	test_cmp output expect2 &&
+	diff_cmp output expect2 &&
 	test 0 = $(git stash list | wc -l)
 '
 
@@ -577,7 +589,7 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
 	+bar
 	EOF
 	git stash show -p ${STASH_ID} >actual &&
-	test_cmp expected actual
+	diff_cmp expected actual
 '
 
 test_expect_success 'stash show - no stashes on stack, stash-like argument' '
@@ -609,7 +621,7 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
 	+foo
 	EOF
 	git stash show -p ${STASH_ID} >actual &&
-	test_cmp expected actual
+	diff_cmp expected actual
 '
 
 test_expect_success 'stash show --patience shows diff' '
@@ -627,7 +639,7 @@ test_expect_success 'stash show --patience shows diff' '
 	+foo
 	EOF
 	git stash show --patience ${STASH_ID} >actual &&
-	test_cmp expected actual
+	diff_cmp expected actual
 '
 
 test_expect_success 'drop: fail early if specified stash is not a stash ref' '
@@ -791,7 +803,7 @@ test_expect_success 'stash where working directory contains "HEAD" file' '
 	git diff-index --cached --quiet HEAD &&
 	test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
 	git diff stash^..stash >output &&
-	test_cmp expect output
+	diff_cmp expect output
 '
 
 test_expect_success 'store called with invalid commit' '
@@ -847,7 +859,7 @@ test_expect_success 'stash list implies --first-parent -m' '
 	+working
 	EOF
 	git stash list --format=%gd -p >actual &&
-	test_cmp expect actual
+	diff_cmp expect actual
 '
 
 test_expect_success 'stash list --cc shows combined diff' '
@@ -864,7 +876,7 @@ test_expect_success 'stash list --cc shows combined diff' '
 	++working
 	EOF
 	git stash list --format=%gd -p --cc >actual &&
-	test_cmp expect actual
+	diff_cmp expect actual
 '
 
 test_expect_success 'stash is not confused by partial renames' '

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

* [PATCH 12/14] t4000: make hash size independent
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (10 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 11/14] t3903: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 19:16 ` [PATCH 13/14] t4002: make hash independent brian m. carlson
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Use $ZERO_OID instead of hard-coding a fixed size all-zeros object ID.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t4000-diff-format.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh
index 8de36b7d12..e5116a76a1 100755
--- a/t/t4000-diff-format.sh
+++ b/t/t4000-diff-format.sh
@@ -78,7 +78,7 @@ test_expect_success 'git diff-files --no-patch --patch shows the patch' '
 
 test_expect_success 'git diff-files --no-patch --patch-with-raw shows the patch and raw data' '
 	git diff-files --no-patch --patch-with-raw >actual &&
-	grep -q "^:100644 100755 .* 0000000000000000000000000000000000000000 M	path0\$" actual &&
+	grep -q "^:100644 100755 .* $ZERO_OID M	path0\$" actual &&
 	tail -n +4 actual >actual-patch &&
 	compare_diff_patch expected actual-patch
 '

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

* [PATCH 13/14] t4002: make hash independent
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (11 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 12/14] t4000: make hash size independent brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-18 20:29   ` Eric Sunshine
  2019-08-18 19:16 ` [PATCH 14/14] t4009: make hash size independent brian m. carlson
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
  14 siblings, 1 reply; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Refactor out the hard-coded object IDs and use test_oid to provide
values for both SHA-1 and SHA-256.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t4002-diff-basic.sh | 367 +++++++++++++++++++++++++++++-------------
 1 file changed, 258 insertions(+), 109 deletions(-)

diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh
index 3a6c21e825..cbcdd10464 100755
--- a/t/t4002-diff-basic.sh
+++ b/t/t4002-diff-basic.sh
@@ -7,123 +7,272 @@ test_description='Test diff raw-output.
 
 '
 . ./test-lib.sh
+
 . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh
 
-cat >.test-plain-OA <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A	AA
-:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A	AN
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D	DD
-:000000 040000 0000000000000000000000000000000000000000 6d50f65d3bdab91c63444294d38f08aeff328e42 A	DF
-:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D	DM
-:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D	DN
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A	LL
-:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M	MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M	MM
-:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M	MN
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M	SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M	TT
-:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 5e5f22072bb39f6e12cf663a57cb634c76eefb49 M	Z
+test_oid_init
+
+test_oid_cache <<\EOF
+aa_1 sha1:ccba72ad3888a3520b39efcf780b9ee64167535d
+aa_1 sha256:9febfbf18197819b2735c45291f138525d2476d59470f98239647544586ba403
+
+aa_2 sha1:6aa2b5335b16431a0ef71e5c0a28be69183cf6a2
+aa_2 sha256:6eaa3437de83f145a4aaa6ba355303075ade547b128ec6a2cd00a81ff7ce7a56
+
+an_1 sha1:7e426fb079479fd67f6d81f984e4ec649a44bc25
+an_1 sha256:8f92a0bec99e399a38e3bd0e1bf19fbf121e0160efb29b857df79d439f1c4536
+
+dd_1 sha1:bcc68ef997017466d5c9094bcf7692295f588c9a
+dd_1 sha256:07e17428b00639b85485d2b01083d219e2f3e3ba8579e9ca44e9cc8dd554d952
+
+df_1 sha1:6d50f65d3bdab91c63444294d38f08aeff328e42
+df_1 sha256:e367cecc27e9bf5451b1c65828cb21938d36a5f8e39c1b03ad6509cc36bb8e9d
+
+df_2 sha1:71420ab81e254145d26d6fc0cddee64c1acd4787
+df_2 sha256:0f0a86d10347ff6921d03a3c954679f3f1d14fa3d5cd82f57b32c09755f3a47d
+
+dfd1 sha1:68a6d8b91da11045cf4aa3a5ab9f2a781c701249
+dfd1 sha256:f3bd3265b02b6978ce86490d8ad026c573639c974b3de1d9faf30d8d5a77d3d5
+
+dm_1 sha1:141c1f1642328e4bc46a7d801a71da392e66791e
+dm_1 sha256:c89f8656e7b94e21ee5fbaf0e2149bbf783c51edbe2ce110349cac13059ee7ed
+
+dm_2 sha1:3c4d8de5fbad08572bab8e10eef8dbb264cf0231
+dm_2 sha256:83a572e37e0c94086294dae2cecc43d9131afd6f6c906e495c78972230b54988
+
+dn_1 sha1:35abde1506ddf806572ff4d407bd06885d0f8ee9
+dn_1 sha256:775d5852582070e620be63327bfa515fab8f71c7ac3e4f0c3cd6267b4377ba28
+
+ll_2 sha1:1d41122ebdd7a640f29d3c9cc4f9d70094374762
+ll_2 sha256:7917b4948a883cfed0a77d3d5a625dc8577d6ddcc3c6c3bbc56c4d4226a2246d
+
+md_1 sha1:03f24c8c4700babccfd28b654e7e8eac402ad6cd
+md_1 sha256:fc9f30369b978595ad685ba11ca9a17de0af16d79cd4b629975f4f1590033902
+
+md_2 sha1:103d9f89b50b9aad03054b579be5e7aa665f2d57
+md_2 sha256:fc78ec75275628762fe520479a6b2398dec295ce7aabcb1d15e5963c7b4e9317
+
+mm_1 sha1:b258508afb7ceb449981bd9d63d2d3e971bf8d34
+mm_1 sha256:a4b7847d228e900e3000285e240c20fd96f9dd41ce1445305f6eada126d4a04a
+
+mm_2 sha1:b431b272d829ff3aa4d1a5085f4394ab4d3305b6
+mm_2 sha256:3f8b83ea36aacf689bcf1a1290a9a8ed341564d32682ea6f76fea9a979186782
+
+mm_3 sha1:19989d4559aae417fedee240ccf2ba315ea4dc2b
+mm_3 sha256:71b3bfc5747ac033fff9ea0ab39ee453a3af2969890e75d6ef547b87544e2681
+
+mn_1 sha1:bd084b0c27c7b6cc34f11d6d0509a29be3caf970
+mn_1 sha256:47a67450583d7a329eb01a7c4ba644945af72c0ed2c7c95eb5a00d6e46d4d483
+
+mn_2 sha1:a716d58de4a570e0038f5c307bd8db34daea021f
+mn_2 sha256:f95104c1ebe27acb84bac25a7be98c71f6b8d3054b21f357a5be0c524ad97e08
+
+nm_1 sha1:c8f25781e8f1792e3e40b74225e20553041b5226
+nm_1 sha256:09baddc7afaa62e62e152c23c9c3ab94bf15a3894031e227e9be7fe68e1f4e49
+
+nm_2 sha1:cdb9a8c3da571502ac30225e9c17beccb8387983
+nm_2 sha256:58b5227956ac2d2a08d0efa513c0ae37430948b16791ea3869a1308dbf05536d
+
+na_1 sha1:15885881ea69115351c09b38371f0348a3fb8c67
+na_1 sha256:18e4fdd1670cd7968ee23d35bfd29e5418d56fb190c840094c1c57ceee0aad8f
+
+nd_1 sha1:a4e179e4291e5536a5e1c82e091052772d2c5a93
+nd_1 sha256:07dac9b01d00956ea0c65bd993d7de4864aeef2ed3cbb1255d9f1d949fcd6df6
+
+ss_1 sha1:40c959f984c8b89a2b02520d17f00d717f024397
+ss_1 sha256:50fc1b5df74d9910db2f9270993484235f15b69b75b01bcfb53e059289d14af9
+
+ss_2 sha1:2ac547ae9614a00d1b28275de608131f7a0e259f
+ss_2 sha256:a90f02e6044f1497d13db587d22ab12f90150a7d1e084afcf96065fab35ae2bc
+
+tt_1 sha1:4ac13458899ab908ef3b1128fa378daefc88d356
+tt_1 sha256:c53113c7dd5060e86b5b251428bd058f6726f66273c6a24bff1c61a04f498dd3
+
+tt_2 sha1:4c86f9a85fbc5e6804ee2e17a797538fbe785bca
+tt_2 sha256:0775f2a296129a7cf2862b46bc0e88c14d593f2773a3e3fb1c5193db6f5a7e77
+
+tt_3 sha1:c4e4a12231b9fa79a0053cb6077fcb21bb5b135a
+tt_3 sha256:47860f93cdd211f96443e0560f21c57ab6c2f4b0ac27ff03651a352e53fe8484
+
+z__1 sha1:7d670fdcdb9929f6c7dac196ff78689cd1c566a1
+z__1 sha256:44d0f37aff5e51cfcfdd1134c93a6419bcca7b9964f792ffcd5f9b4fcba1ee63
+
+z__2 sha1:5e5f22072bb39f6e12cf663a57cb634c76eefb49
+z__2 sha256:d29de162113190fed104eb5f010820cef4e315f89b9326e8497f7219fb737894
+
+z__3 sha1:1ba523955d5160681af65cb776411f574c1e8155
+z__3 sha256:07422d772b07794ab4369a5648e617719f89c2d2212cbeab05d97214b6471636
+
+zaa1 sha1:8acb8e9750e3f644bf323fcf3d338849db106c77
+zaa1 sha256:e79b029282c8abec2d9f3f7faceaf2a1405e02d1f368e66450ae66cf5b68d1f4
+
+zaa2 sha1:6c0b99286d0bce551ac4a7b3dff8b706edff3715
+zaa2 sha256:c82bd78c3e69ea1796e6b1a7a3ba45bb106c50e819296475b862123d3f5cc5a0
+
+zan1 sha1:087494262084cefee7ed484d20c8dc0580791272
+zan1 sha256:4b159eb3804d05599023dd074f771d06d02870f4ab24a7165add8ac3d703b8d3
+
+zdd1 sha1:879007efae624d2b1307214b24a956f0a8d686a8
+zdd1 sha256:eecfdd4d8092dd0363fb6d4548b54c6afc8982c3ed9b34e393f1d6a921d8eaa3
+
+zdm1 sha1:9b541b2275c06e3a7b13f28badf5294e2ae63df4
+zdm1 sha256:ab136e88e19a843c4bf7713d2090d5a2186ba16a6a80dacc12eeddd256a8e556
+
+zdm2 sha1:d77371d15817fcaa57eeec27f770c505ba974ec1
+zdm2 sha256:1c1a5f57363f46a15d95ce8527b3c2c158d88d16853b4acbf81bd20fd2c89a46
+
+zdn1 sha1:beb5d38c55283d280685ea21a0e50cfcc0ca064a
+zdn1 sha256:0f0eca66183617b0aa5ad74b256540329f841470922ca6760263c996d825eb18
+
+zmd1 sha1:d41fda41b7ec4de46b43cb7ea42a45001ae393d5
+zmd1 sha256:1ed32d481852eddf31a0ce12652a0ad14bf5b7a842667b5dbb0b50f35bf1c80a
+
+zmd2 sha1:a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9
+zmd2 sha256:b238da211b404f8917df2d9c6f7030535e904b2186131007a3c292ec6902f933
+
+zmm1 sha1:4ca22bae2527d3d9e1676498a0fba3b355bd1278
+zmm1 sha256:072b1d85b5f34fabc99dfa46008c5418df68302d3e317430006f49b32d244226
+
+zmm2 sha1:61422ba9c2c873416061a88cd40a59a35b576474
+zmm2 sha256:81dd5d2b3c5cda16fef552256aed4e2ea0802a8450a08f308a92142112ff6dda
+
+zmm3 sha1:697aad7715a1e7306ca76290a3dd4208fbaeddfa
+zmm3 sha256:8b10fab49e9be3414aa5e9a93d0e46f9569053440138a7c19a5eb5536d8e95bf
+
+zmn1 sha1:b16d7b25b869f2beb124efa53467d8a1550ad694
+zmn1 sha256:609e4f75d1295e844c826feeba213acb0b6cfc609adfe8ff705b19e3829ae3e9
+
+zmn2 sha1:a5c544c21cfcb07eb80a4d89a5b7d1570002edfd
+zmn2 sha256:d6d03edf2dc1a3b267a8205de5f41a2ff4b03def8c7ae02052b543fb09d589fc
+
+zna1 sha1:d12979c22fff69c59ca9409e7a8fe3ee25eaee80
+zna1 sha256:b37b80e789e8ea32aa323f004628f02013f632124b0282c7fe00a127d3c64c3c
+
+znd1 sha1:a18393c636b98e9bd7296b8b437ea4992b72440c
+znd1 sha256:af92a22eee8c38410a0c9d2b5135a10aeb052cbc7cf675541ed9a67bfcaf7cf9
+
+znm1 sha1:3fdbe17fd013303a2e981e1ca1c6cd6e72789087
+znm1 sha256:f75aeaa0c11e76918e381c105f0752932c6150e941fec565d24fa31098a13dc1
+
+znm2 sha1:7e09d6a3a14bd630913e8c75693cea32157b606d
+znm2 sha256:938d73cfbaa1c902a84fb5b3afd9736aa0590367fb9bd59c6c4d072ce70fcd6d
+EOF
+
+cat >.test-plain-OA <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_1) A	AA
+:000000 100644 $(test_oid zero) $(test_oid an_1) A	AN
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D	DD
+:000000 040000 $(test_oid zero) $(test_oid df_1) A	DF
+:100644 000000 $(test_oid dm_1) $(test_oid zero) D	DM
+:100644 000000 $(test_oid dn_1) $(test_oid zero) D	DN
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A	LL
+:100644 100644 $(test_oid md_1) $(test_oid md_2) M	MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_2) M	MM
+:100644 100644 $(test_oid mn_1) $(test_oid mn_2) M	MN
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M	SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_2) M	TT
+:040000 040000 $(test_oid z__1) $(test_oid z__2) M	Z
 EOF
 
-cat >.test-recursive-OA <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A	AA
-:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A	AN
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D	DD
-:000000 100644 0000000000000000000000000000000000000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 A	DF/DF
-:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D	DM
-:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D	DN
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A	LL
-:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M	MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M	MM
-:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M	MN
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M	SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M	TT
-:000000 100644 0000000000000000000000000000000000000000 8acb8e9750e3f644bf323fcf3d338849db106c77 A	Z/AA
-:000000 100644 0000000000000000000000000000000000000000 087494262084cefee7ed484d20c8dc0580791272 A	Z/AN
-:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D	Z/DD
-:100644 000000 9b541b2275c06e3a7b13f28badf5294e2ae63df4 0000000000000000000000000000000000000000 D	Z/DM
-:100644 000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a 0000000000000000000000000000000000000000 D	Z/DN
-:100644 100644 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 M	Z/MD
-:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 61422ba9c2c873416061a88cd40a59a35b576474 M	Z/MM
-:100644 100644 b16d7b25b869f2beb124efa53467d8a1550ad694 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd M	Z/MN
+cat >.test-recursive-OA <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_1) A	AA
+:000000 100644 $(test_oid zero) $(test_oid an_1) A	AN
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D	DD
+:000000 100644 $(test_oid zero) $(test_oid dfd1) A	DF/DF
+:100644 000000 $(test_oid dm_1) $(test_oid zero) D	DM
+:100644 000000 $(test_oid dn_1) $(test_oid zero) D	DN
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A	LL
+:100644 100644 $(test_oid md_1) $(test_oid md_2) M	MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_2) M	MM
+:100644 100644 $(test_oid mn_1) $(test_oid mn_2) M	MN
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M	SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_2) M	TT
+:000000 100644 $(test_oid zero) $(test_oid zaa1) A	Z/AA
+:000000 100644 $(test_oid zero) $(test_oid zan1) A	Z/AN
+:100644 000000 $(test_oid zdd1) $(test_oid zero) D	Z/DD
+:100644 000000 $(test_oid zdm1) $(test_oid zero) D	Z/DM
+:100644 000000 $(test_oid zdn1) $(test_oid zero) D	Z/DN
+:100644 100644 $(test_oid zmd1) $(test_oid zmd2) M	Z/MD
+:100644 100644 $(test_oid zmm1) $(test_oid zmm2) M	Z/MM
+:100644 100644 $(test_oid zmn1) $(test_oid zmn2) M	Z/MN
 EOF
-cat >.test-plain-OB <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A	AA
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D	DD
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A	DF
-:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M	DM
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A	LL
-:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D	MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M	MM
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A	NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D	ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M	NM
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M	SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M	TT
-:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 1ba523955d5160681af65cb776411f574c1e8155 M	Z
+cat >.test-plain-OB <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_2) A	AA
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D	DD
+:000000 100644 $(test_oid zero) $(test_oid df_2) A	DF
+:100644 100644 $(test_oid dm_1) $(test_oid dm_2) M	DM
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A	LL
+:100644 000000 $(test_oid md_1) $(test_oid zero) D	MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_3) M	MM
+:000000 100644 $(test_oid zero) $(test_oid na_1) A	NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D	ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M	NM
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M	SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_3) M	TT
+:040000 040000 $(test_oid z__1) $(test_oid z__3) M	Z
 EOF
-cat >.test-recursive-OB <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A	AA
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D	DD
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A	DF
-:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M	DM
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A	LL
-:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D	MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M	MM
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A	NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D	ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M	NM
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M	SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M	TT
-:000000 100644 0000000000000000000000000000000000000000 6c0b99286d0bce551ac4a7b3dff8b706edff3715 A	Z/AA
-:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D	Z/DD
-:100644 100644 9b541b2275c06e3a7b13f28badf5294e2ae63df4 d77371d15817fcaa57eeec27f770c505ba974ec1 M	Z/DM
-:100644 000000 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 0000000000000000000000000000000000000000 D	Z/MD
-:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 697aad7715a1e7306ca76290a3dd4208fbaeddfa M	Z/MM
-:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A	Z/NA
-:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D	Z/ND
-:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M	Z/NM
+cat >.test-recursive-OB <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_2) A	AA
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D	DD
+:000000 100644 $(test_oid zero) $(test_oid df_2) A	DF
+:100644 100644 $(test_oid dm_1) $(test_oid dm_2) M	DM
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A	LL
+:100644 000000 $(test_oid md_1) $(test_oid zero) D	MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_3) M	MM
+:000000 100644 $(test_oid zero) $(test_oid na_1) A	NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D	ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M	NM
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M	SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_3) M	TT
+:000000 100644 $(test_oid zero) $(test_oid zaa2) A	Z/AA
+:100644 000000 $(test_oid zdd1) $(test_oid zero) D	Z/DD
+:100644 100644 $(test_oid zdm1) $(test_oid zdm2) M	Z/DM
+:100644 000000 $(test_oid zmd1) $(test_oid zero) D	Z/MD
+:100644 100644 $(test_oid zmm1) $(test_oid zmm3) M	Z/MM
+:000000 100644 $(test_oid zero) $(test_oid zna1) A	Z/NA
+:100644 000000 $(test_oid znd1) $(test_oid zero) D	Z/ND
+:100644 100644 $(test_oid znm1) $(test_oid znm2) M	Z/NM
 EOF
-cat >.test-plain-AB <<\EOF
-:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M	AA
-:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D	AN
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A	DF
-:040000 000000 6d50f65d3bdab91c63444294d38f08aeff328e42 0000000000000000000000000000000000000000 D	DF
-:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A	DM
-:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A	DN
-:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D	MD
-:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M	MM
-:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M	MN
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A	NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D	ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M	NM
-:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M	TT
-:040000 040000 5e5f22072bb39f6e12cf663a57cb634c76eefb49 1ba523955d5160681af65cb776411f574c1e8155 M	Z
+cat >.test-plain-AB <<EOF
+:100644 100644 $(test_oid aa_1) $(test_oid aa_2) M	AA
+:100644 000000 $(test_oid an_1) $(test_oid zero) D	AN
+:000000 100644 $(test_oid zero) $(test_oid df_2) A	DF
+:040000 000000 $(test_oid df_1) $(test_oid zero) D	DF
+:000000 100644 $(test_oid zero) $(test_oid dm_2) A	DM
+:000000 100644 $(test_oid zero) $(test_oid dn_1) A	DN
+:100644 000000 $(test_oid md_2) $(test_oid zero) D	MD
+:100644 100644 $(test_oid mm_2) $(test_oid mm_3) M	MM
+:100644 100644 $(test_oid mn_2) $(test_oid mn_1) M	MN
+:000000 100644 $(test_oid zero) $(test_oid na_1) A	NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D	ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M	NM
+:100644 100644 $(test_oid tt_2) $(test_oid tt_3) M	TT
+:040000 040000 $(test_oid z__2) $(test_oid z__3) M	Z
 EOF
-cat >.test-recursive-AB <<\EOF
-:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M	AA
-:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D	AN
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A	DF
-:100644 000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 0000000000000000000000000000000000000000 D	DF/DF
-:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A	DM
-:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A	DN
-:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D	MD
-:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M	MM
-:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M	MN
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A	NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D	ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M	NM
-:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M	TT
-:100644 100644 8acb8e9750e3f644bf323fcf3d338849db106c77 6c0b99286d0bce551ac4a7b3dff8b706edff3715 M	Z/AA
-:100644 000000 087494262084cefee7ed484d20c8dc0580791272 0000000000000000000000000000000000000000 D	Z/AN
-:000000 100644 0000000000000000000000000000000000000000 d77371d15817fcaa57eeec27f770c505ba974ec1 A	Z/DM
-:000000 100644 0000000000000000000000000000000000000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a A	Z/DN
-:100644 000000 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 0000000000000000000000000000000000000000 D	Z/MD
-:100644 100644 61422ba9c2c873416061a88cd40a59a35b576474 697aad7715a1e7306ca76290a3dd4208fbaeddfa M	Z/MM
-:100644 100644 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd b16d7b25b869f2beb124efa53467d8a1550ad694 M	Z/MN
-:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A	Z/NA
-:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D	Z/ND
-:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M	Z/NM
+cat >.test-recursive-AB <<EOF
+:100644 100644 $(test_oid aa_1) $(test_oid aa_2) M	AA
+:100644 000000 $(test_oid an_1) $(test_oid zero) D	AN
+:000000 100644 $(test_oid zero) $(test_oid df_2) A	DF
+:100644 000000 $(test_oid dfd1) $(test_oid zero) D	DF/DF
+:000000 100644 $(test_oid zero) $(test_oid dm_2) A	DM
+:000000 100644 $(test_oid zero) $(test_oid dn_1) A	DN
+:100644 000000 $(test_oid md_2) $(test_oid zero) D	MD
+:100644 100644 $(test_oid mm_2) $(test_oid mm_3) M	MM
+:100644 100644 $(test_oid mn_2) $(test_oid mn_1) M	MN
+:000000 100644 $(test_oid zero) $(test_oid na_1) A	NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D	ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M	NM
+:100644 100644 $(test_oid tt_2) $(test_oid tt_3) M	TT
+:100644 100644 $(test_oid zaa1) $(test_oid zaa2) M	Z/AA
+:100644 000000 $(test_oid zan1) $(test_oid zero) D	Z/AN
+:000000 100644 $(test_oid zero) $(test_oid zdm2) A	Z/DM
+:000000 100644 $(test_oid zero) $(test_oid zdn1) A	Z/DN
+:100644 000000 $(test_oid zmd2) $(test_oid zero) D	Z/MD
+:100644 100644 $(test_oid zmm2) $(test_oid zmm3) M	Z/MM
+:100644 100644 $(test_oid zmn2) $(test_oid zmn1) M	Z/MN
+:000000 100644 $(test_oid zero) $(test_oid zna1) A	Z/NA
+:100644 000000 $(test_oid znd1) $(test_oid zero) D	Z/ND
+:100644 100644 $(test_oid znm1) $(test_oid znm2) M	Z/NM
 EOF
 
 cmp_diff_files_output () {

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

* [PATCH 14/14] t4009: make hash size independent
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (12 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 13/14] t4002: make hash independent brian m. carlson
@ 2019-08-18 19:16 ` brian m. carlson
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
  14 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 19:16 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

Instead of hard-coding object IDs, compute them and use those in the
comparison.  Note that the comparison code ignores the actual object
IDs, but does check that they're the right size, so computing them is
the easiest way to ensure that they are.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t4009-diff-rename-4.sh | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh
index 3641fd84d6..b63bdf031f 100755
--- a/t/t4009-diff-rename-4.sh
+++ b/t/t4009-diff-rename-4.sh
@@ -14,6 +14,7 @@ test_expect_success \
     'cat "$TEST_DIRECTORY"/diff-lib/COPYING >COPYING &&
      echo frotz >rezrov &&
     git update-index --add COPYING rezrov &&
+    orig=$(git hash-object COPYING) &&
     tree=$(git write-tree) &&
     echo $tree'
 
@@ -22,6 +23,8 @@ test_expect_success \
     'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 &&
     sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 &&
     rm -f COPYING &&
+    c1=$(git hash-object COPYING.1) &&
+    c2=$(git hash-object COPYING.2) &&
     git update-index --add --remove COPYING COPYING.?'
 
 # tree has COPYING and rezrov.  work tree has COPYING.1 and COPYING.2,
@@ -31,11 +34,11 @@ test_expect_success \
 
 git diff-index -z -C $tree >current
 
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+cat >expected <<EOF
+:100644 100644 $orig $c1 C1234
 COPYING
 COPYING.1
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 R1234
+:100644 100644 $orig $c2 R1234
 COPYING
 COPYING.2
 EOF
@@ -57,10 +60,10 @@ test_expect_success \
 # about rezrov.
 
 git diff-index -z -C $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M
+cat >expected <<EOF
+:100644 100644 $orig $c2 M
 COPYING
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+:100644 100644 $orig $c1 C1234
 COPYING
 COPYING.1
 EOF
@@ -82,8 +85,8 @@ test_expect_success \
      git update-index --add --remove COPYING COPYING.1'
 
 git diff-index -z -C --find-copies-harder $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+cat >expected <<EOF
+:100644 100644 $orig $c1 C1234
 COPYING
 COPYING.1
 EOF

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

* Re: [PATCH 11/14] t3903: abstract away SHA-1-specific constants
  2019-08-18 19:16 ` [PATCH 11/14] t3903: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-18 20:27   ` Eric Sunshine
  2019-08-18 20:34     ` brian m. carlson
  0 siblings, 1 reply; 229+ messages in thread
From: Eric Sunshine @ 2019-08-18 20:27 UTC (permalink / raw)
  To: brian m. carlson
  Cc: Git List, Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

On Sun, Aug 18, 2019 at 3:21 PM brian m. carlson
<sandals@crustytoothpaste.net> wrote:
> Abstract away the SHA-1-specific constants by sanitizing diff output to
> remove the index lines, since it's clear from the assertions in question
> that we are not interested in the specific object IDs.
>
> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
> ---
> diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
> @@ -7,6 +7,18 @@ test_description='Test git stash'
> +diff_cmp () {
> +       for i in "$1" "$2"
> +       do
> +               sed -e 's/^index 0000000\.\.[0-9a-f]*/index 0000000..1234567/' \
> +               -e 's/^index [0-9a-f]*\.\.[0-9a-f]*/index 1234567..89abcde/' \
> +               -e 's/^index [0-9a-f]*,[0-9a-f]*\.\.[0-9a-f]*/index 1234567,7654321..89abcde/' \
> +               "$i" > "$i.compare"
> +       done &&
> +       test_cmp "$1.compare" "$2.compare" &&
> +       rm -f "$1.compare" "$2.compare"
> +}

For safety, it would probably be a good idea to check the exit status
of the 'sed' invocation in the for-loop:

    for i in "$1" "$2"
    do
        sed -e ... "$i" >"$i.compare" || return 1
    done &&
    ...

(Note, also, that I dropped the whitespace after the '>' operator.)

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

* Re: [PATCH 13/14] t4002: make hash independent
  2019-08-18 19:16 ` [PATCH 13/14] t4002: make hash independent brian m. carlson
@ 2019-08-18 20:29   ` Eric Sunshine
  0 siblings, 0 replies; 229+ messages in thread
From: Eric Sunshine @ 2019-08-18 20:29 UTC (permalink / raw)
  To: brian m. carlson
  Cc: Git List, Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

On Sun, Aug 18, 2019 at 3:21 PM brian m. carlson
<sandals@crustytoothpaste.net> wrote:
> Refactor out the hard-coded object IDs and use test_oid to provide
> values for both SHA-1 and SHA-256.

s/Refactor out/Factor out/

> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>

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

* Re: [PATCH 11/14] t3903: abstract away SHA-1-specific constants
  2019-08-18 20:27   ` Eric Sunshine
@ 2019-08-18 20:34     ` brian m. carlson
  0 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-18 20:34 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Git List, Jeff King, Taylor Blau, Thomas Gummerer, Johannes Schindelin

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

On 2019-08-18 at 20:27:41, Eric Sunshine wrote:
> For safety, it would probably be a good idea to check the exit status
> of the 'sed' invocation in the for-loop:
> 
>     for i in "$1" "$2"
>     do
>         sed -e ... "$i" >"$i.compare" || return 1
>     done &&
>     ...

I'll do that.

> (Note, also, that I dropped the whitespace after the '>' operator.)

Ah, good catch.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 868 bytes --]

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

* [PATCH v2 00/14] Hash-independent tests, part 5
  2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
                   ` (13 preceding siblings ...)
  2019-08-18 19:16 ` [PATCH 14/14] t4009: make hash size independent brian m. carlson
@ 2019-08-26  1:43 ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 01/14] t3201: abstract away SHA-1-specific constants brian m. carlson
                     ` (13 more replies)
  14 siblings, 14 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

This is the fifth series of test fixes for SHA-256 compatibility.  It
consists of 15 patches fixing various tests from t3201 through t4009 and
has only test fixes: no test helper changes are included.

Changes from v1:
* Add sanity-checking to the sed invocation.
* Remove whitespace between redirection operator and file name.
* Change "Refactor out" to "Factor out".

brian m. carlson (14):
  t3201: abstract away SHA-1-specific constants
  t3206: abstract away hash size constants
  t3301: abstract away SHA-1-specific constants
  t3305: make hash size independent
  t3306: abstract away SHA-1-specific constants
  t3404: abstract away SHA-1-specific constants
  t3430: avoid hard-coded object IDs
  t3506: make hash independent
  t3600: make hash size independent
  t3800: make hash-size independent
  t3903: abstract away SHA-1-specific constants
  t4000: make hash size independent
  t4002: make hash independent
  t4009: make hash size independent

 t/t3201-branch-contains.sh    |   8 +-
 t/t3206-range-diff.sh         | 227 +++++++++++++++------
 t/t3301-notes.sh              | 140 ++++++++-----
 t/t3305-notes-fanout.sh       |  22 +-
 t/t3306-notes-prune.sh        |  45 ++---
 t/t3404-rebase-interactive.sh |  22 +-
 t/t3430-rebase-merges.sh      |  23 ++-
 t/t3506-cherry-pick-ff.sh     |   8 +-
 t/t3600-rm.sh                 |   4 +-
 t/t3800-mktag.sh              |  49 ++---
 t/t3903-stash.sh              |  32 ++-
 t/t4000-diff-format.sh        |   2 +-
 t/t4002-diff-basic.sh         | 367 ++++++++++++++++++++++++----------
 t/t4009-diff-rename-4.sh      |  19 +-
 14 files changed, 640 insertions(+), 328 deletions(-)

Range-diff against v1:
1:  bfc39503dc ! 1:  1a0bda61ca t3903: abstract away SHA-1-specific constants
    @@ t/t3903-stash.sh: test_description='Test git stash'
     +		sed -e 's/^index 0000000\.\.[0-9a-f]*/index 0000000..1234567/' \
     +		-e 's/^index [0-9a-f]*\.\.[0-9a-f]*/index 1234567..89abcde/' \
     +		-e 's/^index [0-9a-f]*,[0-9a-f]*\.\.[0-9a-f]*/index 1234567,7654321..89abcde/' \
    -+		"$i" > "$i.compare"
    ++		"$i" >"$i.compare" || return 1
     +	done &&
     +	test_cmp "$1.compare" "$2.compare" &&
     +	rm -f "$1.compare" "$2.compare"
2:  2da09f10f4 = 2:  64b2fc645b t4000: make hash size independent
3:  239d6de517 ! 3:  a8f0255ea0 t4002: make hash independent
    @@ Metadata
      ## Commit message ##
         t4002: make hash independent
     
    -    Refactor out the hard-coded object IDs and use test_oid to provide
    -    values for both SHA-1 and SHA-256.
    +    Factor out the hard-coded object IDs and use test_oid to provide values
    +    for both SHA-1 and SHA-256.
     
         Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
     
4:  7cb314ec8a = 4:  837d185fa6 t4009: make hash size independent

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

* [PATCH v2 01/14] t3201: abstract away SHA-1-specific constants
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 02/14] t3206: abstract away hash size constants brian m. carlson
                     ` (12 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3201-branch-contains.sh | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 0ea4fc4694..40251c9f8f 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -192,10 +192,10 @@ test_expect_success 'branch --merged with --verbose' '
 	EOF
 	test_cmp expect actual &&
 	git branch --verbose --merged topic >actual &&
-	cat >expect <<-\EOF &&
-	  master c77a0a9 second on master
-	* topic  2c939f4 [ahead 1] foo
-	  zzz    c77a0a9 second on master
+	cat >expect <<-EOF &&
+	  master $(git rev-parse --short master) second on master
+	* topic  $(git rev-parse --short topic ) [ahead 1] foo
+	  zzz    $(git rev-parse --short zzz   ) second on master
 	EOF
 	test_i18ncmp expect actual
 '

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

* [PATCH v2 02/14] t3206: abstract away hash size constants
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 01/14] t3201: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 03/14] t3301: abstract away SHA-1-specific constants brian m. carlson
                     ` (11 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

The various short object IDs in the range-diff output differ between
hash algorithms.  Use test_oid_cache to look up values for both SHA-1
and SHA-256.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3206-range-diff.sh | 227 +++++++++++++++++++++++++++++++-----------
 1 file changed, 167 insertions(+), 60 deletions(-)

diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
index ec548654ce..0120f769f1 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -8,17 +8,124 @@ test_description='range-diff tests'
 # harm than good.  We need some real history.
 
 test_expect_success 'setup' '
-	git fast-import < "$TEST_DIRECTORY"/t3206/history.export
+	git fast-import < "$TEST_DIRECTORY"/t3206/history.export &&
+	test_oid_cache <<-EOF
+	# topic
+	t1 sha1:4de457d
+	t2 sha1:fccce22
+	t3 sha1:147e64e
+	t4 sha1:a63e992
+	t1 sha256:b89f8b9
+	t2 sha256:5f12aad
+	t3 sha256:ea8b273
+	t4 sha256:14b7336
+
+	# unmodified
+	u1 sha1:35b9b25
+	u2 sha1:de345ab
+	u3 sha1:9af6654
+	u4 sha1:2901f77
+	u1 sha256:e3731be
+	u2 sha256:14fadf8
+	u3 sha256:736c4bc
+	u4 sha256:673e77d
+
+	# reordered
+	r1 sha1:aca177a
+	r2 sha1:14ad629
+	r3 sha1:ee58208
+	r4 sha1:307b27a
+	r1 sha256:f59d3aa
+	r2 sha256:fb261a8
+	r3 sha256:cb2649b
+	r4 sha256:958577e
+
+	# removed (deleted)
+	d1 sha1:7657159
+	d2 sha1:43d84d3
+	d3 sha1:a740396
+	d1 sha256:e312513
+	d2 sha256:eb19258
+	d3 sha256:1ccb3c1
+
+	# added
+	a1 sha1:2716022
+	a2 sha1:b62accd
+	a3 sha1:df46cfa
+	a4 sha1:3e64548
+	a5 sha1:12b4063
+	a1 sha256:d724f4d
+	a2 sha256:1de7762
+	a3 sha256:e159431
+	a4 sha256:b3e483c
+	a5 sha256:90866a7
+
+	# rebased
+	b1 sha1:cc9c443
+	b2 sha1:c5d9641
+	b3 sha1:28cc2b6
+	b4 sha1:5628ab7
+	b5 sha1:a31b12e
+	b1 sha256:a1a8717
+	b2 sha256:20a5862
+	b3 sha256:587172a
+	b4 sha256:2721c5d
+	b5 sha256:7b57864
+
+	# changed
+	c1 sha1:a4b3333
+	c2 sha1:f51d370
+	c3 sha1:0559556
+	c4 sha1:d966c5c
+	c1 sha256:f8c2b9d
+	c2 sha256:3fb6318
+	c3 sha256:168ab68
+	c4 sha256:3526539
+
+	# changed-message
+	m1 sha1:f686024
+	m2 sha1:4ab067d
+	m3 sha1:b9cb956
+	m4 sha1:8add5f1
+	m1 sha256:31e6281
+	m2 sha256:a06bf1b
+	m3 sha256:82dc654
+	m4 sha256:48470c5
+
+	# renamed
+	n1 sha1:f258d75
+	n2 sha1:017b62d
+	n3 sha1:3ce7af6
+	n4 sha1:1e6226b
+	n1 sha256:ad52114
+	n2 sha256:3b54c8f
+	n3 sha256:3b0a644
+	n4 sha256:e461653
+
+	# added and removed
+	s1 sha1:096b1ba
+	s2 sha1:d92e698
+	s3 sha1:9a1db4d
+	s4 sha1:fea3b5c
+	s1 sha256:a7f9134
+	s2 sha256:b4c2580
+	s3 sha256:1d62aa2
+	s4 sha256:48160e8
+
+	# Empty delimiter (included so lines match neatly)
+	__ sha1:-------
+	__ sha256:-------
+	EOF
 '
 
 test_expect_success 'simple A..B A..C (unmodified)' '
 	git range-diff --no-color master..topic master..unmodified \
 		>actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  35b9b25 s/5/A/
-	2:  fccce22 = 2:  de345ab s/4/A/
-	3:  147e64e = 3:  9af6654 s/11/B/
-	4:  a63e992 = 4:  2901f77 s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid u1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid u2) s/4/A/
+	3:  $(test_oid t3) = 3:  $(test_oid u3) s/11/B/
+	4:  $(test_oid t4) = 4:  $(test_oid u4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -38,10 +145,10 @@ test_expect_success 'simple A B C (unmodified)' '
 test_expect_success 'trivial reordering' '
 	git range-diff --no-color master topic reordered >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  aca177a s/5/A/
-	3:  147e64e = 2:  14ad629 s/11/B/
-	4:  a63e992 = 3:  ee58208 s/12/B/
-	2:  fccce22 = 4:  307b27a s/4/A/
+	1:  $(test_oid t1) = 1:  $(test_oid r1) s/5/A/
+	3:  $(test_oid t3) = 2:  $(test_oid r2) s/11/B/
+	4:  $(test_oid t4) = 3:  $(test_oid r3) s/12/B/
+	2:  $(test_oid t2) = 4:  $(test_oid r4) s/4/A/
 	EOF
 	test_cmp expected actual
 '
@@ -49,10 +156,10 @@ test_expect_success 'trivial reordering' '
 test_expect_success 'removed a commit' '
 	git range-diff --no-color master topic removed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  7657159 s/5/A/
-	2:  fccce22 < -:  ------- s/4/A/
-	3:  147e64e = 2:  43d84d3 s/11/B/
-	4:  a63e992 = 3:  a740396 s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid d1) s/5/A/
+	2:  $(test_oid t2) < -:  $(test_oid __) s/4/A/
+	3:  $(test_oid t3) = 2:  $(test_oid d2) s/11/B/
+	4:  $(test_oid t4) = 3:  $(test_oid d3) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -60,11 +167,11 @@ test_expect_success 'removed a commit' '
 test_expect_success 'added a commit' '
 	git range-diff --no-color master topic added >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  2716022 s/5/A/
-	2:  fccce22 = 2:  b62accd s/4/A/
-	-:  ------- > 3:  df46cfa s/6/A/
-	3:  147e64e = 4:  3e64548 s/11/B/
-	4:  a63e992 = 5:  12b4063 s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid a1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid a2) s/4/A/
+	-:  $(test_oid __) > 3:  $(test_oid a3) s/6/A/
+	3:  $(test_oid t3) = 4:  $(test_oid a4) s/11/B/
+	4:  $(test_oid t4) = 5:  $(test_oid a5) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -72,10 +179,10 @@ test_expect_success 'added a commit' '
 test_expect_success 'new base, A B C' '
 	git range-diff --no-color master topic rebased >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  cc9c443 s/5/A/
-	2:  fccce22 = 2:  c5d9641 s/4/A/
-	3:  147e64e = 3:  28cc2b6 s/11/B/
-	4:  a63e992 = 4:  5628ab7 s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid b1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid b2) s/4/A/
+	3:  $(test_oid t3) = 3:  $(test_oid b3) s/11/B/
+	4:  $(test_oid t4) = 4:  $(test_oid b4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -84,11 +191,11 @@ test_expect_success 'new base, B...C' '
 	# this syntax includes the commits from master!
 	git range-diff --no-color topic...rebased >actual &&
 	cat >expected <<-EOF &&
-	-:  ------- > 1:  a31b12e unrelated
-	1:  4de457d = 2:  cc9c443 s/5/A/
-	2:  fccce22 = 3:  c5d9641 s/4/A/
-	3:  147e64e = 4:  28cc2b6 s/11/B/
-	4:  a63e992 = 5:  5628ab7 s/12/B/
+	-:  $(test_oid __) > 1:  $(test_oid b5) unrelated
+	1:  $(test_oid t1) = 2:  $(test_oid b1) s/5/A/
+	2:  $(test_oid t2) = 3:  $(test_oid b2) s/4/A/
+	3:  $(test_oid t3) = 4:  $(test_oid b3) s/11/B/
+	4:  $(test_oid t4) = 5:  $(test_oid b4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -96,9 +203,9 @@ test_expect_success 'new base, B...C' '
 test_expect_success 'changed commit' '
 	git range-diff --no-color topic...changed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  a4b3333 s/5/A/
-	2:  fccce22 = 2:  f51d370 s/4/A/
-	3:  147e64e ! 3:  0559556 s/11/B/
+	1:  $(test_oid t1) = 1:  $(test_oid c1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid c2) s/4/A/
+	3:  $(test_oid t3) ! 3:  $(test_oid c3) s/11/B/
 	    @@ file: A
 	      9
 	      10
@@ -108,7 +215,7 @@ test_expect_success 'changed commit' '
 	      12
 	      13
 	      14
-	4:  a63e992 ! 4:  d966c5c s/12/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid c4) s/12/B/
 	    @@ file
 	     @@ file: A
 	      9
@@ -125,10 +232,10 @@ test_expect_success 'changed commit' '
 test_expect_success 'changed commit with --no-patch diff option' '
 	git range-diff --no-color --no-patch topic...changed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  a4b3333 s/5/A/
-	2:  fccce22 = 2:  f51d370 s/4/A/
-	3:  147e64e ! 3:  0559556 s/11/B/
-	4:  a63e992 ! 4:  d966c5c s/12/B/
+	1:  $(test_oid t1) = 1:  $(test_oid c1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid c2) s/4/A/
+	3:  $(test_oid t3) ! 3:  $(test_oid c3) s/11/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid c4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -136,16 +243,16 @@ test_expect_success 'changed commit with --no-patch diff option' '
 test_expect_success 'changed commit with --stat diff option' '
 	git range-diff --no-color --stat topic...changed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  a4b3333 s/5/A/
+	1:  $(test_oid t1) = 1:  $(test_oid c1) s/5/A/
 	     a => b | 0
 	     1 file changed, 0 insertions(+), 0 deletions(-)
-	2:  fccce22 = 2:  f51d370 s/4/A/
+	2:  $(test_oid t2) = 2:  $(test_oid c2) s/4/A/
 	     a => b | 0
 	     1 file changed, 0 insertions(+), 0 deletions(-)
-	3:  147e64e ! 3:  0559556 s/11/B/
+	3:  $(test_oid t3) ! 3:  $(test_oid c3) s/11/B/
 	     a => b | 0
 	     1 file changed, 0 insertions(+), 0 deletions(-)
-	4:  a63e992 ! 4:  d966c5c s/12/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid c4) s/12/B/
 	     a => b | 0
 	     1 file changed, 0 insertions(+), 0 deletions(-)
 	EOF
@@ -155,9 +262,9 @@ test_expect_success 'changed commit with --stat diff option' '
 test_expect_success 'changed commit with sm config' '
 	git range-diff --no-color --submodule=log topic...changed >actual &&
 	cat >expected <<-EOF &&
-	1:  4de457d = 1:  a4b3333 s/5/A/
-	2:  fccce22 = 2:  f51d370 s/4/A/
-	3:  147e64e ! 3:  0559556 s/11/B/
+	1:  $(test_oid t1) = 1:  $(test_oid c1) s/5/A/
+	2:  $(test_oid t2) = 2:  $(test_oid c2) s/4/A/
+	3:  $(test_oid t3) ! 3:  $(test_oid c3) s/11/B/
 	    @@ file: A
 	      9
 	      10
@@ -167,7 +274,7 @@ test_expect_success 'changed commit with sm config' '
 	      12
 	      13
 	      14
-	4:  a63e992 ! 4:  d966c5c s/12/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid c4) s/12/B/
 	    @@ file
 	     @@ file: A
 	      9
@@ -184,8 +291,8 @@ test_expect_success 'changed commit with sm config' '
 test_expect_success 'renamed file' '
 	git range-diff --no-color --submodule=log topic...renamed-file >actual &&
 	sed s/Z/\ /g >expected <<-EOF &&
-	1:  4de457d = 1:  f258d75 s/5/A/
-	2:  fccce22 ! 2:  017b62d s/4/A/
+	1:  $(test_oid t1) = 1:  $(test_oid n1) s/5/A/
+	2:  $(test_oid t2) ! 2:  $(test_oid n2) s/4/A/
 	    @@ Metadata
 	    ZAuthor: Thomas Rast <trast@inf.ethz.ch>
 	    Z
@@ -198,7 +305,7 @@ test_expect_success 'renamed file' '
 	    Z@@
 	    Z 1
 	    Z 2
-	3:  147e64e ! 3:  3ce7af6 s/11/B/
+	3:  $(test_oid t3) ! 3:  $(test_oid n3) s/11/B/
 	    @@ Metadata
 	    Z ## Commit message ##
 	    Z    s/11/B/
@@ -210,7 +317,7 @@ test_expect_success 'renamed file' '
 	    Z 8
 	    Z 9
 	    Z 10
-	4:  a63e992 ! 4:  1e6226b s/12/B/
+	4:  $(test_oid t4) ! 4:  $(test_oid n4) s/12/B/
 	    @@ Metadata
 	    Z ## Commit message ##
 	    Z    s/12/B/
@@ -229,8 +336,8 @@ test_expect_success 'renamed file' '
 test_expect_success 'file added and later removed' '
 	git range-diff --no-color --submodule=log topic...added-removed >actual &&
 	sed s/Z/\ /g >expected <<-EOF &&
-	1:  4de457d = 1:  096b1ba s/5/A/
-	2:  fccce22 ! 2:  d92e698 s/4/A/
+	1:  $(test_oid t1) = 1:  $(test_oid s1) s/5/A/
+	2:  $(test_oid t2) ! 2:  $(test_oid s2) s/4/A/
 	    @@ Metadata
 	    ZAuthor: Thomas Rast <trast@inf.ethz.ch>
 	    Z
@@ -246,7 +353,7 @@ test_expect_success 'file added and later removed' '
 	    Z 7
 	    +
 	    + ## new-file (new) ##
-	3:  147e64e ! 3:  9a1db4d s/11/B/
+	3:  $(test_oid t3) ! 3:  $(test_oid s3) s/11/B/
 	    @@ Metadata
 	    ZAuthor: Thomas Rast <trast@inf.ethz.ch>
 	    Z
@@ -262,7 +369,7 @@ test_expect_success 'file added and later removed' '
 	    Z 14
 	    +
 	    + ## new-file (deleted) ##
-	4:  a63e992 = 4:  fea3b5c s/12/B/
+	4:  $(test_oid t4) = 4:  $(test_oid s4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
@@ -275,8 +382,8 @@ test_expect_success 'no commits on one side' '
 test_expect_success 'changed message' '
 	git range-diff --no-color topic...changed-message >actual &&
 	sed s/Z/\ /g >expected <<-EOF &&
-	1:  4de457d = 1:  f686024 s/5/A/
-	2:  fccce22 ! 2:  4ab067d s/4/A/
+	1:  $(test_oid t1) = 1:  $(test_oid m1) s/5/A/
+	2:  $(test_oid t2) ! 2:  $(test_oid m2) s/4/A/
 	    @@ Metadata
 	    Z ## Commit message ##
 	    Z    s/4/A/
@@ -286,16 +393,16 @@ test_expect_success 'changed message' '
 	    Z ## file ##
 	    Z@@
 	    Z 1
-	3:  147e64e = 3:  b9cb956 s/11/B/
-	4:  a63e992 = 4:  8add5f1 s/12/B/
+	3:  $(test_oid t3) = 3:  $(test_oid m3) s/11/B/
+	4:  $(test_oid t4) = 4:  $(test_oid m4) s/12/B/
 	EOF
 	test_cmp expected actual
 '
 
 test_expect_success 'dual-coloring' '
-	sed -e "s|^:||" >expect <<-\EOF &&
-	:<YELLOW>1:  a4b3333 = 1:  f686024 s/5/A/<RESET>
-	:<RED>2:  f51d370 <RESET><YELLOW>!<RESET><GREEN> 2:  4ab067d<RESET><YELLOW> s/4/A/<RESET>
+	sed -e "s|^:||" >expect <<-EOF &&
+	:<YELLOW>1:  $(test_oid c1) = 1:  $(test_oid m1) s/5/A/<RESET>
+	:<RED>2:  $(test_oid c2) <RESET><YELLOW>!<RESET><GREEN> 2:  $(test_oid m2)<RESET><YELLOW> s/4/A/<RESET>
 	:    <REVERSE><CYAN>@@<RESET> <RESET>Metadata<RESET>
 	:      ## Commit message ##<RESET>
 	:         s/4/A/<RESET>
@@ -305,7 +412,7 @@ test_expect_success 'dual-coloring' '
 	:      ## file ##<RESET>
 	:    <CYAN> @@<RESET>
 	:      1<RESET>
-	:<RED>3:  0559556 <RESET><YELLOW>!<RESET><GREEN> 3:  b9cb956<RESET><YELLOW> s/11/B/<RESET>
+	:<RED>3:  $(test_oid c3) <RESET><YELLOW>!<RESET><GREEN> 3:  $(test_oid m3)<RESET><YELLOW> s/11/B/<RESET>
 	:    <REVERSE><CYAN>@@<RESET> <RESET>file: A<RESET>
 	:      9<RESET>
 	:      10<RESET>
@@ -315,7 +422,7 @@ test_expect_success 'dual-coloring' '
 	:      12<RESET>
 	:      13<RESET>
 	:      14<RESET>
-	:<RED>4:  d966c5c <RESET><YELLOW>!<RESET><GREEN> 4:  8add5f1<RESET><YELLOW> s/12/B/<RESET>
+	:<RED>4:  $(test_oid c4) <RESET><YELLOW>!<RESET><GREEN> 4:  $(test_oid m4)<RESET><YELLOW> s/12/B/<RESET>
 	:    <REVERSE><CYAN>@@<RESET> <RESET>file<RESET>
 	:    <CYAN> @@ file: A<RESET>
 	:      9<RESET>

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

* [PATCH v2 03/14] t3301: abstract away SHA-1-specific constants
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 01/14] t3201: abstract away SHA-1-specific constants brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 02/14] t3206: abstract away hash size constants brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 04/14] t3305: make hash size independent brian m. carlson
                     ` (10 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.  Move some invocations of test_commit around so
that we can compute the object IDs for these commits.

Compute several object IDs in the tests instead of using hard-coded
values so that the test works with any hash algorithm.  Since the actual
values are sorted by the object ID of the object being annotated, sort
the expected values accordingly as well.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3301-notes.sh | 140 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 90 insertions(+), 50 deletions(-)

diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index 704bbc6541..d3fa298c6a 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -66,8 +66,9 @@ test_expect_success 'show notes entry with %N' '
 '
 
 test_expect_success 'create reflog entry' '
+	ref=$(git rev-parse --short refs/notes/commits) &&
 	cat <<-EOF >expect &&
-		a1d8fa6 refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
+		$ref refs/notes/commits@{0}: notes: Notes added by '\''git notes add'\''
 	EOF
 	git reflog show refs/notes/commits >actual &&
 	test_cmp expect actual
@@ -134,8 +135,9 @@ test_expect_success 'can overwrite existing note with "git notes add -f"' '
 '
 
 test_expect_success 'show notes' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 7a4ca6ee52a974a66cbaa78e33214535dff1d691
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:14:13 2005 -0700
 
@@ -152,8 +154,9 @@ test_expect_success 'show notes' '
 test_expect_success 'show multi-line notes' '
 	test_commit 3rd &&
 	MSG="b3${LF}c3c3c3c3${LF}d3d3d3" git notes add &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-multiline <<-EOF &&
-		commit d07d62e5208f22eb5695e7eb47667dc8b9860290
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:15:13 2005 -0700
 
@@ -174,8 +177,9 @@ test_expect_success 'show -F notes' '
 	test_commit 4th &&
 	echo "xyzzy" >note5 &&
 	git notes add -F note5 &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-F <<-EOF &&
-		commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:16:13 2005 -0700
 
@@ -198,10 +202,13 @@ test_expect_success 'Re-adding -F notes without -f fails' '
 '
 
 test_expect_success 'git log --pretty=raw does not show notes' '
+	commit=$(git rev-parse HEAD) &&
+	tree=$(git rev-parse HEAD^{tree}) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
-		tree 05ac65288c4c4b3b709a020ae94b2ece2f2201ae
-		parent d07d62e5208f22eb5695e7eb47667dc8b9860290
+		commit $commit
+		tree $tree
+		parent $parent
 		author A U Thor <author@example.com> 1112912173 -0700
 		committer C O Mitter <committer@example.com> 1112912173 -0700
 
@@ -291,8 +298,9 @@ test_expect_success 'git log --no-notes resets ref list' '
 test_expect_success 'show -m notes' '
 	test_commit 5th &&
 	git notes add -m spam -m "foo${LF}bar${LF}baz" &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-m <<-EOF &&
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
@@ -313,8 +321,9 @@ test_expect_success 'show -m notes' '
 
 test_expect_success 'remove note with add -f -F /dev/null' '
 	git notes add -f -F /dev/null &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-rm-F <<-EOF &&
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
@@ -356,14 +365,16 @@ test_expect_success 'create note with combination of -m and -F' '
 test_expect_success 'remove note with "git notes remove"' '
 	git notes remove HEAD^ &&
 	git notes remove &&
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect-rm-remove <<-EOF &&
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
 		${indent}5th
 
-		commit 0f7aa3ec6325aeb88b910453bb3eb37c49d75c11
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:16:13 2005 -0700
 
@@ -459,9 +470,11 @@ test_expect_success 'removing with --stdin --ignore-missing' '
 '
 
 test_expect_success 'list notes with "git notes list"' '
-	cat >expect <<-EOF &&
-		c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691
-		c18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290
+	commit_2=$(git rev-parse 2nd) &&
+	commit_3=$(git rev-parse 3rd) &&
+	sort -t" " -k2 >expect <<-EOF &&
+		$(git rev-parse refs/notes/commits:$commit_2) $commit_2
+		$(git rev-parse refs/notes/commits:$commit_3) $commit_3
 	EOF
 	git notes list >actual &&
 	test_cmp expect actual
@@ -474,7 +487,7 @@ test_expect_success 'list notes with "git notes"' '
 
 test_expect_success 'list specific note with "git notes list <object>"' '
 	cat >expect <<-EOF &&
-		c18dc024e14f08d18d14eea0d747ff692d66d6a3
+		$(git rev-parse refs/notes/commits:$commit_3)
 	EOF
 	git notes list HEAD^^ >actual &&
 	test_cmp expect actual
@@ -498,10 +511,11 @@ test_expect_success 'append to existing note with "git notes append"' '
 '
 
 test_expect_success '"git notes list" does not expand to "git notes list HEAD"' '
-	cat >expect_list <<-EOF &&
-		c9c6af7f78bc47490dbf3e822cf2f3c24d4b9061 7a4ca6ee52a974a66cbaa78e33214535dff1d691
-		4b6ad22357cc8a1296720574b8d2fbc22fab0671 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
-		c18dc024e14f08d18d14eea0d747ff692d66d6a3 d07d62e5208f22eb5695e7eb47667dc8b9860290
+	commit_5=$(git rev-parse 5th) &&
+	sort -t" " -k2 >expect_list <<-EOF &&
+		$(git rev-parse refs/notes/commits:$commit_2) $commit_2
+		$(git rev-parse refs/notes/commits:$commit_3) $commit_3
+		$(git rev-parse refs/notes/commits:$commit_5) $commit_5
 	EOF
 	git notes list >actual &&
 	test_cmp expect_list actual
@@ -531,8 +545,9 @@ test_expect_success 'appending empty string to non-existing note does not create
 test_expect_success 'create other note on a different notes ref (setup)' '
 	test_commit 6th &&
 	GIT_NOTES_REF="refs/notes/other" git notes add -m "other note" &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-not-other <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
@@ -569,8 +584,10 @@ test_expect_success 'Do not show note when core.notesRef is overridden' '
 '
 
 test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect-both <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
@@ -582,7 +599,7 @@ test_expect_success 'Show all notes when notes.displayRef=refs/notes/*' '
 		Notes (other):
 		${indent}other note
 
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
@@ -616,8 +633,9 @@ test_expect_success 'notes.displayRef can be given more than once' '
 '
 
 test_expect_success 'notes.displayRef respects order' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-both-reversed <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
@@ -642,14 +660,16 @@ test_expect_success 'GIT_NOTES_DISPLAY_REF works' '
 '
 
 test_expect_success 'GIT_NOTES_DISPLAY_REF overrides config' '
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect-none <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
 		${indent}6th
 
-		commit 7f9ad8836c775acb134c0a055fc55fb4cd1ba361
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:17:13 2005 -0700
 
@@ -666,8 +686,9 @@ test_expect_success '--show-notes=* adds to GIT_NOTES_DISPLAY_REF' '
 '
 
 test_expect_success '--no-standard-notes' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect-commits <<-EOF &&
-		commit 2c125331118caba0ff8238b7f4958ac6e93fe39c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:18:13 2005 -0700
 
@@ -712,8 +733,10 @@ test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' '
 '
 
 test_expect_success 'create note from other note with "git notes add -C"' '
+	test_commit 7th &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit fb01e0ca8c33b6cc0c6451dde747f97df567cb5c
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:19:13 2005 -0700
 
@@ -722,7 +745,6 @@ test_expect_success 'create note from other note with "git notes add -C"' '
 		Notes:
 		${indent}order test
 	EOF
-	test_commit 7th &&
 	git notes add -C $(git notes list HEAD^) &&
 	git log -1 >actual &&
 	test_cmp expect actual &&
@@ -744,8 +766,9 @@ test_expect_success 'create note from non-blob with "git notes add -C" fails' '
 '
 
 test_expect_success 'create note from blob with "git notes add -C" reuses blob id' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 9a4c31c7f722b5d517e92c64e932dd751e1413bf
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:20:13 2005 -0700
 
@@ -762,8 +785,10 @@ test_expect_success 'create note from blob with "git notes add -C" reuses blob i
 '
 
 test_expect_success 'create note from other note with "git notes add -c"' '
+	test_commit 9th &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 2e0db4bc649e174d667a1cde19e725cf897a5bd2
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:21:13 2005 -0700
 
@@ -772,7 +797,6 @@ test_expect_success 'create note from other note with "git notes add -c"' '
 		Notes:
 		${indent}yet another note
 	EOF
-	test_commit 9th &&
 	MSG="yet another note" git notes add -c $(git notes list HEAD^^) &&
 	git log -1 >actual &&
 	test_cmp expect actual
@@ -785,8 +809,9 @@ test_expect_success 'create note from non-existing note with "git notes add -c"
 '
 
 test_expect_success 'append to note from other note with "git notes append -C"' '
+	commit=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit 2e0db4bc649e174d667a1cde19e725cf897a5bd2
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:21:13 2005 -0700
 
@@ -803,8 +828,9 @@ test_expect_success 'append to note from other note with "git notes append -C"'
 '
 
 test_expect_success 'create note from other note with "git notes append -c"' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:22:13 2005 -0700
 
@@ -819,8 +845,9 @@ test_expect_success 'create note from other note with "git notes append -c"' '
 '
 
 test_expect_success 'append to note from other note with "git notes append -c"' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 7c3b87ab368f81e11b1ea87b2ab99a71ccd25406
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:22:13 2005 -0700
 
@@ -837,8 +864,10 @@ test_expect_success 'append to note from other note with "git notes append -c"'
 '
 
 test_expect_success 'copy note with "git notes copy"' '
+	test_commit 11th &&
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:23:13 2005 -0700
 
@@ -849,7 +878,6 @@ test_expect_success 'copy note with "git notes copy"' '
 		${indent}
 		${indent}yet another note
 	EOF
-	test_commit 11th &&
 	git notes copy HEAD^ HEAD &&
 	git log -1 >actual &&
 	test_cmp expect actual &&
@@ -864,8 +892,9 @@ test_expect_success 'prevent overwrite with "git notes copy"' '
 '
 
 test_expect_success 'allow overwrite with "git notes copy -f"' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit a446fff8777efdc6eb8f4b7c8a5ff699484df0d5
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:23:13 2005 -0700
 
@@ -889,8 +918,10 @@ test_expect_success 'cannot copy note from object without notes' '
 '
 
 test_expect_success 'git notes copy --stdin' '
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit e871aa61182b1d95d0a6fb75445d891722863b6b
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:25:13 2005 -0700
 
@@ -901,7 +932,7 @@ test_expect_success 'git notes copy --stdin' '
 		${indent}
 		${indent}yet another note
 
-		commit 65e263ded02ae4e8839bc151095113737579dc12
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:24:13 2005 -0700
 
@@ -922,21 +953,23 @@ test_expect_success 'git notes copy --stdin' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
+	test_commit 14th &&
+	test_commit 15th &&
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
 		${indent}15th
 
-		commit 07c85d77059393ed0154b8c96906547a59dfcddd
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:26:13 2005 -0700
 
 		${indent}14th
 	EOF
-	test_commit 14th &&
-	test_commit 15th &&
 	(echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) &&
 	echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) |
 	git notes copy --for-rewrite=foo &&
@@ -945,8 +978,10 @@ test_expect_success 'git notes copy --for-rewrite (unconfigured)' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (enabled)' '
+	commit=$(git rev-parse HEAD) &&
+	parent=$(git rev-parse HEAD^) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -957,7 +992,7 @@ test_expect_success 'git notes copy --for-rewrite (enabled)' '
 		${indent}
 		${indent}yet another note
 
-		commit 07c85d77059393ed0154b8c96906547a59dfcddd
+		commit $parent
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:26:13 2005 -0700
 
@@ -986,8 +1021,9 @@ test_expect_success 'git notes copy --for-rewrite (disabled)' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (overwrite)' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -1015,8 +1051,9 @@ test_expect_success 'git notes copy --for-rewrite (ignore)' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (append)' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -1037,8 +1074,9 @@ test_expect_success 'git notes copy --for-rewrite (append)' '
 '
 
 test_expect_success 'git notes copy --for-rewrite (append two to one)' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -1075,8 +1113,9 @@ test_expect_success 'git notes copy --for-rewrite (append empty)' '
 '
 
 test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 
@@ -1095,8 +1134,9 @@ test_expect_success 'GIT_NOTES_REWRITE_MODE works' '
 '
 
 test_expect_success 'GIT_NOTES_REWRITE_REF works' '
+	commit=$(git rev-parse HEAD) &&
 	cat >expect <<-EOF &&
-		commit 4acf42e847e7fffbbf89ee365c20ac7caf40de89
+		commit $commit
 		Author: A U Thor <author@example.com>
 		Date:   Thu Apr 7 15:27:13 2005 -0700
 

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

* [PATCH v2 04/14] t3305: make hash size independent
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (2 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 03/14] t3301: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 05/14] t3306: abstract away SHA-1-specific constants brian m. carlson
                     ` (9 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Instead of hard-coding 40-character shell patterns, use grep to
determine if all of the paths have either zero or one levels of fanout,
as appropriate.

Note that the final test is implicitly dependent on the hash algorithm.
Depending on the algorithm in use, the fanout may or may not completely
compress.  In its current state, this is not a problem, but it could be
if the hash algorithm changes again.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3305-notes-fanout.sh | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh
index 54460beec4..831f83d211 100755
--- a/t/t3305-notes-fanout.sh
+++ b/t/t3305-notes-fanout.sh
@@ -35,15 +35,10 @@ test_expect_success 'many notes created with git-notes triggers fanout' '
 	git ls-tree -r --name-only refs/notes/commits |
 	while read path
 	do
-		case "$path" in
-		??/??????????????????????????????????????)
-			: true
-			;;
-		*)
+		echo $path | grep "^../[0-9a-f]*$" || {
 			echo "Invalid path \"$path\"" &&
-			return 1
-			;;
-		esac
+			return 1;
+		}
 	done
 '
 
@@ -77,15 +72,10 @@ test_expect_success 'deleting most notes triggers fanout consolidation' '
 	git ls-tree -r --name-only refs/notes/commits |
 	while read path
 	do
-		case "$path" in
-		????????????????????????????????????????)
-			: true
-			;;
-		*)
+		echo $path | grep -v "^../.*" || {
 			echo "Invalid path \"$path\"" &&
-			return 1
-			;;
-		esac
+			return 1;
+		}
 	done
 '
 

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

* [PATCH v2 05/14] t3306: abstract away SHA-1-specific constants
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (3 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 04/14] t3305: make hash size independent brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 06/14] t3404: " brian m. carlson
                     ` (8 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.  Convert some single-line heredocs into inline
uses of echo now that they can be expressed succinctly.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3306-notes-prune.sh | 45 ++++++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh
index 61748088eb..8f4102ff9e 100755
--- a/t/t3306-notes-prune.sh
+++ b/t/t3306-notes-prune.sh
@@ -11,23 +11,26 @@ test_expect_success 'setup: create a few commits with notes' '
 	test_tick &&
 	git commit -m 1st &&
 	git notes add -m "Note #1" &&
+	first=$(git rev-parse HEAD) &&
 	: > file2 &&
 	git add file2 &&
 	test_tick &&
 	git commit -m 2nd &&
 	git notes add -m "Note #2" &&
+	second=$(git rev-parse HEAD) &&
 	: > file3 &&
 	git add file3 &&
 	test_tick &&
 	git commit -m 3rd &&
-	COMMIT_FILE=.git/objects/5e/e1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
+	third=$(git rev-parse HEAD) &&
+	COMMIT_FILE=$(echo $third | sed "s!^..!.git/objects/&/!") &&
 	test -f $COMMIT_FILE &&
 	test-tool chmtime =+0 $COMMIT_FILE &&
 	git notes add -m "Note #3"
 '
 
 cat > expect <<END_OF_LOG
-commit 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
+commit $third
 Author: A U Thor <author@example.com>
 Date:   Thu Apr 7 15:15:13 2005 -0700
 
@@ -36,7 +39,7 @@ Date:   Thu Apr 7 15:15:13 2005 -0700
 Notes:
     Note #3
 
-commit 08341ad9e94faa089d60fd3f523affb25c6da189
+commit $second
 Author: A U Thor <author@example.com>
 Date:   Thu Apr 7 15:14:13 2005 -0700
 
@@ -45,7 +48,7 @@ Date:   Thu Apr 7 15:14:13 2005 -0700
 Notes:
     Note #2
 
-commit ab5f302035f2e7aaf04265f08b42034c23256e1f
+commit $first
 Author: A U Thor <author@example.com>
 Date:   Thu Apr 7 15:13:13 2005 -0700
 
@@ -70,16 +73,16 @@ test_expect_success 'remove some commits' '
 
 test_expect_success 'verify that commits are gone' '
 
-	test_must_fail git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
-	git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 &&
-	git cat-file -p ab5f302035f2e7aaf04265f08b42034c23256e1f
+	test_must_fail git cat-file -p $third &&
+	git cat-file -p $second &&
+	git cat-file -p $first
 '
 
 test_expect_success 'verify that notes are still present' '
 
-	git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
-	git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
-	git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+	git notes show $third &&
+	git notes show $second &&
+	git notes show $first
 '
 
 test_expect_success 'prune -n does not remove notes' '
@@ -90,13 +93,10 @@ test_expect_success 'prune -n does not remove notes' '
 	test_cmp expect actual
 '
 
-cat > expect <<EOF
-5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29
-EOF
 
 test_expect_success 'prune -n lists prunable notes' '
 
-
+	echo $third >expect &&
 	git notes prune -n > actual &&
 	test_cmp expect actual
 '
@@ -109,9 +109,9 @@ test_expect_success 'prune notes' '
 
 test_expect_success 'verify that notes are gone' '
 
-	test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
-	git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
-	git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+	test_must_fail git notes show $third &&
+	git notes show $second &&
+	git notes show $first
 '
 
 test_expect_success 'remove some commits' '
@@ -121,21 +121,18 @@ test_expect_success 'remove some commits' '
 	git gc --prune=now
 '
 
-cat > expect <<EOF
-08341ad9e94faa089d60fd3f523affb25c6da189
-EOF
-
 test_expect_success 'prune -v notes' '
 
+	echo $second >expect &&
 	git notes prune -v > actual &&
 	test_cmp expect actual
 '
 
 test_expect_success 'verify that notes are gone' '
 
-	test_must_fail git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
-	test_must_fail git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 &&
-	git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f
+	test_must_fail git notes show $third &&
+	test_must_fail git notes show $second &&
+	git notes show $first
 '
 
 test_done

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

* [PATCH v2 06/14] t3404: abstract away SHA-1-specific constants
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (4 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 05/14] t3306: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 07/14] t3430: avoid hard-coded object IDs brian m. carlson
                     ` (7 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.  Add a use of $EMPTY_TREE instead of a
hard-coded value.  Remove a comment about hard-coded hashes which is no
longer applicable.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3404-rebase-interactive.sh | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 461dd539ff..87ee69f78e 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -29,9 +29,6 @@ Initial setup:
 
 . "$TEST_DIRECTORY"/lib-rebase.sh
 
-# WARNING: Modifications to the initial repository can change the SHA ID used
-# in the expect2 file for the 'stop on conflicting pick' test.
-
 test_expect_success 'setup' '
 	test_commit A file1 &&
 	test_commit B file1 &&
@@ -233,25 +230,28 @@ test_expect_success 'exchange two commits' '
 	set_fake_editor &&
 	FAKE_LINES="2 1" git rebase -i HEAD~2 &&
 	test H = $(git cat-file commit HEAD^ | sed -ne \$p) &&
-	test G = $(git cat-file commit HEAD | sed -ne \$p)
+	test G = $(git cat-file commit HEAD | sed -ne \$p) &&
+	blob1=$(git rev-parse --short HEAD^:file1) &&
+	blob2=$(git rev-parse --short HEAD:file1) &&
+	commit=$(git rev-parse --short HEAD)
 '
 
 test_expect_success 'stop on conflicting pick' '
-	cat >expect <<-\EOF &&
+	cat >expect <<-EOF &&
 	diff --git a/file1 b/file1
-	index f70f10e..fd79235 100644
+	index $blob1..$blob2 100644
 	--- a/file1
 	+++ b/file1
 	@@ -1 +1 @@
 	-A
 	+G
 	EOF
-	cat >expect2 <<-\EOF &&
+	cat >expect2 <<-EOF &&
 	<<<<<<< HEAD
 	D
 	=======
 	G
-	>>>>>>> 5d18e54... G
+	>>>>>>> $commit... G
 	EOF
 	git tag new-branch1 &&
 	set_fake_editor &&
@@ -1003,7 +1003,7 @@ test_expect_success 'rebase -i --root temporary sentinel commit' '
 	git checkout B &&
 	set_fake_editor &&
 	test_must_fail env FAKE_LINES="2" git rebase -i --root &&
-	git cat-file commit HEAD | grep "^tree 4b825dc642cb" &&
+	git cat-file commit HEAD | grep "^tree $EMPTY_TREE" &&
 	git rebase --abort
 '
 
@@ -1161,7 +1161,7 @@ test_expect_success 'rebase -i error on commits with \ in message' '
 	test_expect_code 1 grep  "	emp" error
 '
 
-test_expect_success 'short SHA-1 setup' '
+test_expect_success SHA1 'short SHA-1 setup' '
 	test_when_finished "git checkout master" &&
 	git checkout --orphan collide &&
 	git rm -rf . &&
@@ -1173,7 +1173,7 @@ test_expect_success 'short SHA-1 setup' '
 	)
 '
 
-test_expect_success 'short SHA-1 collide' '
+test_expect_success SHA1 'short SHA-1 collide' '
 	test_when_finished "reset_rebase && git checkout master" &&
 	git checkout collide &&
 	(

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

* [PATCH v2 07/14] t3430: avoid hard-coded object IDs
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (5 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 06/14] t3404: " brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 08/14] t3506: make hash independent brian m. carlson
                     ` (6 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Compute the object IDs used in the todo list instead of hard-coding
them.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3430-rebase-merges.sh | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 7b6c4847ad..c1ea2ee297 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -37,20 +37,27 @@ test_expect_success 'setup' '
 	test_commit A &&
 	git checkout -b first &&
 	test_commit B &&
+	b=$(git rev-parse --short HEAD) &&
 	git checkout master &&
 	test_commit C &&
+	c=$(git rev-parse --short HEAD) &&
 	test_commit D &&
+	d=$(git rev-parse --short HEAD) &&
 	git merge --no-commit B &&
 	test_tick &&
 	git commit -m E &&
 	git tag -m E E &&
+	e=$(git rev-parse --short HEAD) &&
 	git checkout -b second C &&
 	test_commit F &&
+	f=$(git rev-parse --short HEAD) &&
 	test_commit G &&
+	g=$(git rev-parse --short HEAD) &&
 	git checkout master &&
 	git merge --no-commit G &&
 	test_tick &&
 	git commit -m H &&
+	h=$(git rev-parse --short HEAD) &&
 	git tag -m H H &&
 	git checkout A &&
 	test_commit conflicting-G G.t
@@ -93,24 +100,24 @@ test_expect_success 'create completely different structure' '
 '
 
 test_expect_success 'generate correct todo list' '
-	cat >expect <<-\EOF &&
+	cat >expect <<-EOF &&
 	label onto
 
 	reset onto
-	pick d9df450 B
+	pick $b B
 	label E
 
 	reset onto
-	pick 5dee784 C
+	pick $c C
 	label branch-point
-	pick ca2c861 F
-	pick 088b00a G
+	pick $f F
+	pick $g G
 	label H
 
 	reset branch-point # C
-	pick 12bd07b D
-	merge -C 2051b56 E # E
-	merge -C 233d48a H # H
+	pick $d D
+	merge -C $e E # E
+	merge -C $h H # H
 
 	EOF
 

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

* [PATCH v2 08/14] t3506: make hash independent
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (6 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 07/14] t3430: avoid hard-coded object IDs brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 09/14] t3600: make hash size independent brian m. carlson
                     ` (5 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

This test uses a hard-coded object ID to ensure that the result of
cherry-pick --ff is correct.  Use test_oid to make this work for both
SHA-1 and SHA-256.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3506-cherry-pick-ff.sh | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
index 127dd0082f..9d5adbc130 100755
--- a/t/t3506-cherry-pick-ff.sh
+++ b/t/t3506-cherry-pick-ff.sh
@@ -16,7 +16,11 @@ test_expect_success setup '
 	git add file1 &&
 	test_tick &&
 	git commit -m "second" &&
-	git tag second
+	git tag second &&
+	test_oid_cache <<-EOF
+	cp_ff sha1:1df192cd8bc58a2b275d842cede4d221ad9000d1
+	cp_ff sha256:e70d6b7fc064bddb516b8d512c9057094b96ce6ff08e12080acc4fe7f1d60a1d
+	EOF
 '
 
 test_expect_success 'cherry-pick using --ff fast forwards' '
@@ -102,7 +106,7 @@ test_expect_success 'cherry pick a root commit with --ff' '
 	git add file2 &&
 	git commit --amend -m "file2" &&
 	git cherry-pick --ff first &&
-	test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
+	test "$(git rev-parse --verify HEAD)" = "$(test_oid cp_ff)"
 '
 
 test_expect_success 'cherry-pick --ff on unborn branch' '

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

* [PATCH v2 09/14] t3600: make hash size independent
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (7 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 08/14] t3506: make hash independent brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 10/14] t3800: make hash-size independent brian m. carlson
                     ` (4 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Instead of hard-coding a fixed length invalid object ID in the test,
compute one using the lookup tables.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3600-rm.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 66282a720e..8c8cca5bfb 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -240,12 +240,14 @@ test_expect_success 'refresh index before checking if it is up-to-date' '
 '
 
 test_expect_success 'choking "git rm" should not let it die with cruft' '
+	test_oid_init &&
 	git reset -q --hard &&
 	test_when_finished "rm -f .git/index.lock && git reset -q --hard" &&
 	i=0 &&
+	hash=$(test_oid deadbeef) &&
 	while test $i -lt 12000
 	do
-		echo "100644 1234567890123456789012345678901234567890 0	some-file-$i"
+		echo "100644 $hash 0	some-file-$i"
 		i=$(( $i + 1 ))
 	done | git update-index --index-info &&
 	git rm -n "some-file-*" | : &&

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

* [PATCH v2 10/14] t3800: make hash-size independent
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (8 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 09/14] t3600: make hash size independent brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2020-11-23 12:01     ` [PATCH] mktag: don't check SHA-1 object length under SHA-256 Ævar Arnfjörð Bjarmason
  2019-08-26  1:43   ` [PATCH v2 11/14] t3903: abstract away SHA-1-specific constants brian m. carlson
                     ` (3 subsequent siblings)
  13 siblings, 1 reply; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Replace references to several hard-coded object IDs with a variable
referring to the generated commit.  Avoid matching on exact character
positions, which will be different depending on the hash in use.  In the
test for a valid object ID, use an obviously invalid one from the lookup
table.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3800-mktag.sh | 49 ++++++++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 8eb47942e2..64dcc5ec28 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -23,6 +23,7 @@ check_verify_failure () {
 # first create a commit, so we have a valid object/type
 # for the tag.
 test_expect_success 'setup' '
+	test_oid_init &&
 	echo Hello >A &&
 	git update-index --add A &&
 	git commit -m "Initial commit" &&
@@ -69,28 +70,28 @@ check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
 #  4. type line label check
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
 xxxx tag
 tag mytag
 tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"type" line label check' '^error: char47: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
 
 ############################################################
 #  5. type line eol check
 
-echo "object 779e9b33986b1c2670fff52c5067603117b3e895" >tag.sig
+echo "object $head" >tag.sig
 printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
 
-check_verify_failure '"type" line eol check' '^error: char48: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
 
 ############################################################
 #  6. tag line label check #1
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
 type tag
 xxx mytag
 tagger . <> 0 +0000
@@ -98,37 +99,37 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure '"tag" line label check #1' \
-	'^error: char57: no "tag " found$'
+	'^error: char.*: no "tag " found$'
 
 ############################################################
 #  7. tag line label check #2
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
 type taggggggggggggggggggggggggggggggg
 tag
 EOF
 
 check_verify_failure '"tag" line label check #2' \
-	'^error: char87: no "tag " found$'
+	'^error: char.*: no "tag " found$'
 
 ############################################################
 #  8. type line type-name length check
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $head
 type taggggggggggggggggggggggggggggggg
 tag mytag
 EOF
 
 check_verify_failure '"type" line type-name length check' \
-	'^error: char53: type too long$'
+	'^error: char.*: type too long$'
 
 ############################################################
 #  9. verify object (SHA1/type) check
 
 cat >tag.sig <<EOF
-object 779e9b33986b1c2670fff52c5067603117b3e895
+object $(test_oid deadbeef)
 type tagggg
 tag mytag
 tagger . <> 0 +0000
@@ -150,7 +151,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error: char67: could not verify tag name$'
+	'^error: char.*: could not verify tag name$'
 
 ############################################################
 # 11. tagger line label check #1
@@ -164,7 +165,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error: char70: could not find "tagger "$'
+	'^error: char.*: could not find "tagger "$'
 
 ############################################################
 # 12. tagger line label check #2
@@ -179,7 +180,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error: char70: could not find "tagger "$'
+	'^error: char.*: could not find "tagger "$'
 
 ############################################################
 # 13. disallow missing tag author name
@@ -194,7 +195,7 @@ This is filler
 EOF
 
 check_verify_failure 'disallow missing tag author name' \
-	'^error: char77: missing tagger name$'
+	'^error: char.*: missing tagger name$'
 
 ############################################################
 # 14. disallow missing tag author name
@@ -209,7 +210,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error: char77: malformed tagger field$'
+	'^error: char.*: malformed tagger field$'
 
 ############################################################
 # 15. allow empty tag email
@@ -238,7 +239,7 @@ tagger T A Gger <tag ger@example.com> 0 +0000
 EOF
 
 check_verify_failure 'disallow spaces in tag email' \
-	'^error: char77: malformed tagger field$'
+	'^error: char.*: malformed tagger field$'
 
 ############################################################
 # 17. disallow missing tag timestamp
@@ -252,7 +253,7 @@ tagger T A Gger <tagger@example.com>__
 EOF
 
 check_verify_failure 'disallow missing tag timestamp' \
-	'^error: char107: missing tag timestamp$'
+	'^error: char.*: missing tag timestamp$'
 
 ############################################################
 # 18. detect invalid tag timestamp1
@@ -266,7 +267,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
 EOF
 
 check_verify_failure 'detect invalid tag timestamp1' \
-	'^error: char107: missing tag timestamp$'
+	'^error: char.*: missing tag timestamp$'
 
 ############################################################
 # 19. detect invalid tag timestamp2
@@ -280,7 +281,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
 EOF
 
 check_verify_failure 'detect invalid tag timestamp2' \
-	'^error: char111: malformed tag timestamp$'
+	'^error: char.*: malformed tag timestamp$'
 
 ############################################################
 # 20. detect invalid tag timezone1
@@ -294,7 +295,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
 EOF
 
 check_verify_failure 'detect invalid tag timezone1' \
-	'^error: char118: malformed tag timezone$'
+	'^error: char.*: malformed tag timezone$'
 
 ############################################################
 # 21. detect invalid tag timezone2
@@ -308,7 +309,7 @@ tagger T A Gger <tagger@example.com> 1206478233 +  30
 EOF
 
 check_verify_failure 'detect invalid tag timezone2' \
-	'^error: char118: malformed tag timezone$'
+	'^error: char.*: malformed tag timezone$'
 
 ############################################################
 # 22. detect invalid tag timezone3
@@ -322,7 +323,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
 EOF
 
 check_verify_failure 'detect invalid tag timezone3' \
-	'^error: char118: malformed tag timezone$'
+	'^error: char.*: malformed tag timezone$'
 
 ############################################################
 # 23. detect invalid header entry
@@ -337,7 +338,7 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error: char124: trailing garbage in tag header$'
+	'^error: char.*: trailing garbage in tag header$'
 
 ############################################################
 # 24. create valid tag

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

* [PATCH v2 11/14] t3903: abstract away SHA-1-specific constants
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (9 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 10/14] t3800: make hash-size independent brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 12/14] t4000: make hash size independent brian m. carlson
                     ` (2 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Abstract away the SHA-1-specific constants by sanitizing diff output to
remove the index lines, since it's clear from the assertions in question
that we are not interested in the specific object IDs.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t3903-stash.sh | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index b8e337893f..820b350aeb 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -7,6 +7,18 @@ test_description='Test git stash'
 
 . ./test-lib.sh
 
+diff_cmp () {
+	for i in "$1" "$2"
+	do
+		sed -e 's/^index 0000000\.\.[0-9a-f]*/index 0000000..1234567/' \
+		-e 's/^index [0-9a-f]*\.\.[0-9a-f]*/index 1234567..89abcde/' \
+		-e 's/^index [0-9a-f]*,[0-9a-f]*\.\.[0-9a-f]*/index 1234567,7654321..89abcde/' \
+		"$i" >"$i.compare" || return 1
+	done &&
+	test_cmp "$1.compare" "$2.compare" &&
+	rm -f "$1.compare" "$2.compare"
+}
+
 test_expect_success 'stash some dirty working directory' '
 	echo 1 >file &&
 	git add file &&
@@ -36,7 +48,7 @@ EOF
 test_expect_success 'parents of stash' '
 	test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
 	git diff stash^2..stash >output &&
-	test_cmp expect output
+	diff_cmp expect output
 '
 
 test_expect_success 'applying bogus stash does nothing' '
@@ -210,13 +222,13 @@ test_expect_success 'stash branch' '
 	test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
 	test $(git rev-parse HEAD) = $(git rev-parse master^) &&
 	git diff --cached >output &&
-	test_cmp expect output &&
+	diff_cmp expect output &&
 	git diff >output &&
-	test_cmp expect1 output &&
+	diff_cmp expect1 output &&
 	git add file &&
 	git commit -m alternate\ second &&
 	git diff master..stashbranch >output &&
-	test_cmp output expect2 &&
+	diff_cmp output expect2 &&
 	test 0 = $(git stash list | wc -l)
 '
 
@@ -577,7 +589,7 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
 	+bar
 	EOF
 	git stash show -p ${STASH_ID} >actual &&
-	test_cmp expected actual
+	diff_cmp expected actual
 '
 
 test_expect_success 'stash show - no stashes on stack, stash-like argument' '
@@ -609,7 +621,7 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
 	+foo
 	EOF
 	git stash show -p ${STASH_ID} >actual &&
-	test_cmp expected actual
+	diff_cmp expected actual
 '
 
 test_expect_success 'stash show --patience shows diff' '
@@ -627,7 +639,7 @@ test_expect_success 'stash show --patience shows diff' '
 	+foo
 	EOF
 	git stash show --patience ${STASH_ID} >actual &&
-	test_cmp expected actual
+	diff_cmp expected actual
 '
 
 test_expect_success 'drop: fail early if specified stash is not a stash ref' '
@@ -791,7 +803,7 @@ test_expect_success 'stash where working directory contains "HEAD" file' '
 	git diff-index --cached --quiet HEAD &&
 	test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
 	git diff stash^..stash >output &&
-	test_cmp expect output
+	diff_cmp expect output
 '
 
 test_expect_success 'store called with invalid commit' '
@@ -847,7 +859,7 @@ test_expect_success 'stash list implies --first-parent -m' '
 	+working
 	EOF
 	git stash list --format=%gd -p >actual &&
-	test_cmp expect actual
+	diff_cmp expect actual
 '
 
 test_expect_success 'stash list --cc shows combined diff' '
@@ -864,7 +876,7 @@ test_expect_success 'stash list --cc shows combined diff' '
 	++working
 	EOF
 	git stash list --format=%gd -p --cc >actual &&
-	test_cmp expect actual
+	diff_cmp expect actual
 '
 
 test_expect_success 'stash is not confused by partial renames' '

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

* [PATCH v2 12/14] t4000: make hash size independent
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (10 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 11/14] t3903: abstract away SHA-1-specific constants brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 13/14] t4002: make hash independent brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 14/14] t4009: make hash size independent brian m. carlson
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Use $ZERO_OID instead of hard-coding a fixed size all-zeros object ID.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t4000-diff-format.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh
index 8de36b7d12..e5116a76a1 100755
--- a/t/t4000-diff-format.sh
+++ b/t/t4000-diff-format.sh
@@ -78,7 +78,7 @@ test_expect_success 'git diff-files --no-patch --patch shows the patch' '
 
 test_expect_success 'git diff-files --no-patch --patch-with-raw shows the patch and raw data' '
 	git diff-files --no-patch --patch-with-raw >actual &&
-	grep -q "^:100644 100755 .* 0000000000000000000000000000000000000000 M	path0\$" actual &&
+	grep -q "^:100644 100755 .* $ZERO_OID M	path0\$" actual &&
 	tail -n +4 actual >actual-patch &&
 	compare_diff_patch expected actual-patch
 '

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

* [PATCH v2 13/14] t4002: make hash independent
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (11 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 12/14] t4000: make hash size independent brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  2019-08-26  1:43   ` [PATCH v2 14/14] t4009: make hash size independent brian m. carlson
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Factor out the hard-coded object IDs and use test_oid to provide values
for both SHA-1 and SHA-256.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t4002-diff-basic.sh | 367 +++++++++++++++++++++++++++++-------------
 1 file changed, 258 insertions(+), 109 deletions(-)

diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh
index 3a6c21e825..cbcdd10464 100755
--- a/t/t4002-diff-basic.sh
+++ b/t/t4002-diff-basic.sh
@@ -7,123 +7,272 @@ test_description='Test diff raw-output.
 
 '
 . ./test-lib.sh
+
 . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh
 
-cat >.test-plain-OA <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A	AA
-:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A	AN
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D	DD
-:000000 040000 0000000000000000000000000000000000000000 6d50f65d3bdab91c63444294d38f08aeff328e42 A	DF
-:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D	DM
-:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D	DN
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A	LL
-:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M	MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M	MM
-:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M	MN
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M	SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M	TT
-:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 5e5f22072bb39f6e12cf663a57cb634c76eefb49 M	Z
+test_oid_init
+
+test_oid_cache <<\EOF
+aa_1 sha1:ccba72ad3888a3520b39efcf780b9ee64167535d
+aa_1 sha256:9febfbf18197819b2735c45291f138525d2476d59470f98239647544586ba403
+
+aa_2 sha1:6aa2b5335b16431a0ef71e5c0a28be69183cf6a2
+aa_2 sha256:6eaa3437de83f145a4aaa6ba355303075ade547b128ec6a2cd00a81ff7ce7a56
+
+an_1 sha1:7e426fb079479fd67f6d81f984e4ec649a44bc25
+an_1 sha256:8f92a0bec99e399a38e3bd0e1bf19fbf121e0160efb29b857df79d439f1c4536
+
+dd_1 sha1:bcc68ef997017466d5c9094bcf7692295f588c9a
+dd_1 sha256:07e17428b00639b85485d2b01083d219e2f3e3ba8579e9ca44e9cc8dd554d952
+
+df_1 sha1:6d50f65d3bdab91c63444294d38f08aeff328e42
+df_1 sha256:e367cecc27e9bf5451b1c65828cb21938d36a5f8e39c1b03ad6509cc36bb8e9d
+
+df_2 sha1:71420ab81e254145d26d6fc0cddee64c1acd4787
+df_2 sha256:0f0a86d10347ff6921d03a3c954679f3f1d14fa3d5cd82f57b32c09755f3a47d
+
+dfd1 sha1:68a6d8b91da11045cf4aa3a5ab9f2a781c701249
+dfd1 sha256:f3bd3265b02b6978ce86490d8ad026c573639c974b3de1d9faf30d8d5a77d3d5
+
+dm_1 sha1:141c1f1642328e4bc46a7d801a71da392e66791e
+dm_1 sha256:c89f8656e7b94e21ee5fbaf0e2149bbf783c51edbe2ce110349cac13059ee7ed
+
+dm_2 sha1:3c4d8de5fbad08572bab8e10eef8dbb264cf0231
+dm_2 sha256:83a572e37e0c94086294dae2cecc43d9131afd6f6c906e495c78972230b54988
+
+dn_1 sha1:35abde1506ddf806572ff4d407bd06885d0f8ee9
+dn_1 sha256:775d5852582070e620be63327bfa515fab8f71c7ac3e4f0c3cd6267b4377ba28
+
+ll_2 sha1:1d41122ebdd7a640f29d3c9cc4f9d70094374762
+ll_2 sha256:7917b4948a883cfed0a77d3d5a625dc8577d6ddcc3c6c3bbc56c4d4226a2246d
+
+md_1 sha1:03f24c8c4700babccfd28b654e7e8eac402ad6cd
+md_1 sha256:fc9f30369b978595ad685ba11ca9a17de0af16d79cd4b629975f4f1590033902
+
+md_2 sha1:103d9f89b50b9aad03054b579be5e7aa665f2d57
+md_2 sha256:fc78ec75275628762fe520479a6b2398dec295ce7aabcb1d15e5963c7b4e9317
+
+mm_1 sha1:b258508afb7ceb449981bd9d63d2d3e971bf8d34
+mm_1 sha256:a4b7847d228e900e3000285e240c20fd96f9dd41ce1445305f6eada126d4a04a
+
+mm_2 sha1:b431b272d829ff3aa4d1a5085f4394ab4d3305b6
+mm_2 sha256:3f8b83ea36aacf689bcf1a1290a9a8ed341564d32682ea6f76fea9a979186782
+
+mm_3 sha1:19989d4559aae417fedee240ccf2ba315ea4dc2b
+mm_3 sha256:71b3bfc5747ac033fff9ea0ab39ee453a3af2969890e75d6ef547b87544e2681
+
+mn_1 sha1:bd084b0c27c7b6cc34f11d6d0509a29be3caf970
+mn_1 sha256:47a67450583d7a329eb01a7c4ba644945af72c0ed2c7c95eb5a00d6e46d4d483
+
+mn_2 sha1:a716d58de4a570e0038f5c307bd8db34daea021f
+mn_2 sha256:f95104c1ebe27acb84bac25a7be98c71f6b8d3054b21f357a5be0c524ad97e08
+
+nm_1 sha1:c8f25781e8f1792e3e40b74225e20553041b5226
+nm_1 sha256:09baddc7afaa62e62e152c23c9c3ab94bf15a3894031e227e9be7fe68e1f4e49
+
+nm_2 sha1:cdb9a8c3da571502ac30225e9c17beccb8387983
+nm_2 sha256:58b5227956ac2d2a08d0efa513c0ae37430948b16791ea3869a1308dbf05536d
+
+na_1 sha1:15885881ea69115351c09b38371f0348a3fb8c67
+na_1 sha256:18e4fdd1670cd7968ee23d35bfd29e5418d56fb190c840094c1c57ceee0aad8f
+
+nd_1 sha1:a4e179e4291e5536a5e1c82e091052772d2c5a93
+nd_1 sha256:07dac9b01d00956ea0c65bd993d7de4864aeef2ed3cbb1255d9f1d949fcd6df6
+
+ss_1 sha1:40c959f984c8b89a2b02520d17f00d717f024397
+ss_1 sha256:50fc1b5df74d9910db2f9270993484235f15b69b75b01bcfb53e059289d14af9
+
+ss_2 sha1:2ac547ae9614a00d1b28275de608131f7a0e259f
+ss_2 sha256:a90f02e6044f1497d13db587d22ab12f90150a7d1e084afcf96065fab35ae2bc
+
+tt_1 sha1:4ac13458899ab908ef3b1128fa378daefc88d356
+tt_1 sha256:c53113c7dd5060e86b5b251428bd058f6726f66273c6a24bff1c61a04f498dd3
+
+tt_2 sha1:4c86f9a85fbc5e6804ee2e17a797538fbe785bca
+tt_2 sha256:0775f2a296129a7cf2862b46bc0e88c14d593f2773a3e3fb1c5193db6f5a7e77
+
+tt_3 sha1:c4e4a12231b9fa79a0053cb6077fcb21bb5b135a
+tt_3 sha256:47860f93cdd211f96443e0560f21c57ab6c2f4b0ac27ff03651a352e53fe8484
+
+z__1 sha1:7d670fdcdb9929f6c7dac196ff78689cd1c566a1
+z__1 sha256:44d0f37aff5e51cfcfdd1134c93a6419bcca7b9964f792ffcd5f9b4fcba1ee63
+
+z__2 sha1:5e5f22072bb39f6e12cf663a57cb634c76eefb49
+z__2 sha256:d29de162113190fed104eb5f010820cef4e315f89b9326e8497f7219fb737894
+
+z__3 sha1:1ba523955d5160681af65cb776411f574c1e8155
+z__3 sha256:07422d772b07794ab4369a5648e617719f89c2d2212cbeab05d97214b6471636
+
+zaa1 sha1:8acb8e9750e3f644bf323fcf3d338849db106c77
+zaa1 sha256:e79b029282c8abec2d9f3f7faceaf2a1405e02d1f368e66450ae66cf5b68d1f4
+
+zaa2 sha1:6c0b99286d0bce551ac4a7b3dff8b706edff3715
+zaa2 sha256:c82bd78c3e69ea1796e6b1a7a3ba45bb106c50e819296475b862123d3f5cc5a0
+
+zan1 sha1:087494262084cefee7ed484d20c8dc0580791272
+zan1 sha256:4b159eb3804d05599023dd074f771d06d02870f4ab24a7165add8ac3d703b8d3
+
+zdd1 sha1:879007efae624d2b1307214b24a956f0a8d686a8
+zdd1 sha256:eecfdd4d8092dd0363fb6d4548b54c6afc8982c3ed9b34e393f1d6a921d8eaa3
+
+zdm1 sha1:9b541b2275c06e3a7b13f28badf5294e2ae63df4
+zdm1 sha256:ab136e88e19a843c4bf7713d2090d5a2186ba16a6a80dacc12eeddd256a8e556
+
+zdm2 sha1:d77371d15817fcaa57eeec27f770c505ba974ec1
+zdm2 sha256:1c1a5f57363f46a15d95ce8527b3c2c158d88d16853b4acbf81bd20fd2c89a46
+
+zdn1 sha1:beb5d38c55283d280685ea21a0e50cfcc0ca064a
+zdn1 sha256:0f0eca66183617b0aa5ad74b256540329f841470922ca6760263c996d825eb18
+
+zmd1 sha1:d41fda41b7ec4de46b43cb7ea42a45001ae393d5
+zmd1 sha256:1ed32d481852eddf31a0ce12652a0ad14bf5b7a842667b5dbb0b50f35bf1c80a
+
+zmd2 sha1:a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9
+zmd2 sha256:b238da211b404f8917df2d9c6f7030535e904b2186131007a3c292ec6902f933
+
+zmm1 sha1:4ca22bae2527d3d9e1676498a0fba3b355bd1278
+zmm1 sha256:072b1d85b5f34fabc99dfa46008c5418df68302d3e317430006f49b32d244226
+
+zmm2 sha1:61422ba9c2c873416061a88cd40a59a35b576474
+zmm2 sha256:81dd5d2b3c5cda16fef552256aed4e2ea0802a8450a08f308a92142112ff6dda
+
+zmm3 sha1:697aad7715a1e7306ca76290a3dd4208fbaeddfa
+zmm3 sha256:8b10fab49e9be3414aa5e9a93d0e46f9569053440138a7c19a5eb5536d8e95bf
+
+zmn1 sha1:b16d7b25b869f2beb124efa53467d8a1550ad694
+zmn1 sha256:609e4f75d1295e844c826feeba213acb0b6cfc609adfe8ff705b19e3829ae3e9
+
+zmn2 sha1:a5c544c21cfcb07eb80a4d89a5b7d1570002edfd
+zmn2 sha256:d6d03edf2dc1a3b267a8205de5f41a2ff4b03def8c7ae02052b543fb09d589fc
+
+zna1 sha1:d12979c22fff69c59ca9409e7a8fe3ee25eaee80
+zna1 sha256:b37b80e789e8ea32aa323f004628f02013f632124b0282c7fe00a127d3c64c3c
+
+znd1 sha1:a18393c636b98e9bd7296b8b437ea4992b72440c
+znd1 sha256:af92a22eee8c38410a0c9d2b5135a10aeb052cbc7cf675541ed9a67bfcaf7cf9
+
+znm1 sha1:3fdbe17fd013303a2e981e1ca1c6cd6e72789087
+znm1 sha256:f75aeaa0c11e76918e381c105f0752932c6150e941fec565d24fa31098a13dc1
+
+znm2 sha1:7e09d6a3a14bd630913e8c75693cea32157b606d
+znm2 sha256:938d73cfbaa1c902a84fb5b3afd9736aa0590367fb9bd59c6c4d072ce70fcd6d
+EOF
+
+cat >.test-plain-OA <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_1) A	AA
+:000000 100644 $(test_oid zero) $(test_oid an_1) A	AN
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D	DD
+:000000 040000 $(test_oid zero) $(test_oid df_1) A	DF
+:100644 000000 $(test_oid dm_1) $(test_oid zero) D	DM
+:100644 000000 $(test_oid dn_1) $(test_oid zero) D	DN
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A	LL
+:100644 100644 $(test_oid md_1) $(test_oid md_2) M	MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_2) M	MM
+:100644 100644 $(test_oid mn_1) $(test_oid mn_2) M	MN
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M	SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_2) M	TT
+:040000 040000 $(test_oid z__1) $(test_oid z__2) M	Z
 EOF
 
-cat >.test-recursive-OA <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 ccba72ad3888a3520b39efcf780b9ee64167535d A	AA
-:000000 100644 0000000000000000000000000000000000000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 A	AN
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D	DD
-:000000 100644 0000000000000000000000000000000000000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 A	DF/DF
-:100644 000000 141c1f1642328e4bc46a7d801a71da392e66791e 0000000000000000000000000000000000000000 D	DM
-:100644 000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 0000000000000000000000000000000000000000 D	DN
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A	LL
-:100644 100644 03f24c8c4700babccfd28b654e7e8eac402ad6cd 103d9f89b50b9aad03054b579be5e7aa665f2d57 M	MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 M	MM
-:100644 100644 bd084b0c27c7b6cc34f11d6d0509a29be3caf970 a716d58de4a570e0038f5c307bd8db34daea021f M	MN
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M	SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 4c86f9a85fbc5e6804ee2e17a797538fbe785bca M	TT
-:000000 100644 0000000000000000000000000000000000000000 8acb8e9750e3f644bf323fcf3d338849db106c77 A	Z/AA
-:000000 100644 0000000000000000000000000000000000000000 087494262084cefee7ed484d20c8dc0580791272 A	Z/AN
-:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D	Z/DD
-:100644 000000 9b541b2275c06e3a7b13f28badf5294e2ae63df4 0000000000000000000000000000000000000000 D	Z/DM
-:100644 000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a 0000000000000000000000000000000000000000 D	Z/DN
-:100644 100644 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 M	Z/MD
-:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 61422ba9c2c873416061a88cd40a59a35b576474 M	Z/MM
-:100644 100644 b16d7b25b869f2beb124efa53467d8a1550ad694 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd M	Z/MN
+cat >.test-recursive-OA <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_1) A	AA
+:000000 100644 $(test_oid zero) $(test_oid an_1) A	AN
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D	DD
+:000000 100644 $(test_oid zero) $(test_oid dfd1) A	DF/DF
+:100644 000000 $(test_oid dm_1) $(test_oid zero) D	DM
+:100644 000000 $(test_oid dn_1) $(test_oid zero) D	DN
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A	LL
+:100644 100644 $(test_oid md_1) $(test_oid md_2) M	MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_2) M	MM
+:100644 100644 $(test_oid mn_1) $(test_oid mn_2) M	MN
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M	SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_2) M	TT
+:000000 100644 $(test_oid zero) $(test_oid zaa1) A	Z/AA
+:000000 100644 $(test_oid zero) $(test_oid zan1) A	Z/AN
+:100644 000000 $(test_oid zdd1) $(test_oid zero) D	Z/DD
+:100644 000000 $(test_oid zdm1) $(test_oid zero) D	Z/DM
+:100644 000000 $(test_oid zdn1) $(test_oid zero) D	Z/DN
+:100644 100644 $(test_oid zmd1) $(test_oid zmd2) M	Z/MD
+:100644 100644 $(test_oid zmm1) $(test_oid zmm2) M	Z/MM
+:100644 100644 $(test_oid zmn1) $(test_oid zmn2) M	Z/MN
 EOF
-cat >.test-plain-OB <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A	AA
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D	DD
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A	DF
-:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M	DM
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A	LL
-:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D	MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M	MM
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A	NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D	ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M	NM
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M	SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M	TT
-:040000 040000 7d670fdcdb9929f6c7dac196ff78689cd1c566a1 1ba523955d5160681af65cb776411f574c1e8155 M	Z
+cat >.test-plain-OB <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_2) A	AA
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D	DD
+:000000 100644 $(test_oid zero) $(test_oid df_2) A	DF
+:100644 100644 $(test_oid dm_1) $(test_oid dm_2) M	DM
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A	LL
+:100644 000000 $(test_oid md_1) $(test_oid zero) D	MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_3) M	MM
+:000000 100644 $(test_oid zero) $(test_oid na_1) A	NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D	ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M	NM
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M	SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_3) M	TT
+:040000 040000 $(test_oid z__1) $(test_oid z__3) M	Z
 EOF
-cat >.test-recursive-OB <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 A	AA
-:100644 000000 bcc68ef997017466d5c9094bcf7692295f588c9a 0000000000000000000000000000000000000000 D	DD
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A	DF
-:100644 100644 141c1f1642328e4bc46a7d801a71da392e66791e 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 M	DM
-:000000 100644 0000000000000000000000000000000000000000 1d41122ebdd7a640f29d3c9cc4f9d70094374762 A	LL
-:100644 000000 03f24c8c4700babccfd28b654e7e8eac402ad6cd 0000000000000000000000000000000000000000 D	MD
-:100644 100644 b258508afb7ceb449981bd9d63d2d3e971bf8d34 19989d4559aae417fedee240ccf2ba315ea4dc2b M	MM
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A	NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D	ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M	NM
-:100644 100644 40c959f984c8b89a2b02520d17f00d717f024397 2ac547ae9614a00d1b28275de608131f7a0e259f M	SS
-:100644 100644 4ac13458899ab908ef3b1128fa378daefc88d356 c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M	TT
-:000000 100644 0000000000000000000000000000000000000000 6c0b99286d0bce551ac4a7b3dff8b706edff3715 A	Z/AA
-:100644 000000 879007efae624d2b1307214b24a956f0a8d686a8 0000000000000000000000000000000000000000 D	Z/DD
-:100644 100644 9b541b2275c06e3a7b13f28badf5294e2ae63df4 d77371d15817fcaa57eeec27f770c505ba974ec1 M	Z/DM
-:100644 000000 d41fda41b7ec4de46b43cb7ea42a45001ae393d5 0000000000000000000000000000000000000000 D	Z/MD
-:100644 100644 4ca22bae2527d3d9e1676498a0fba3b355bd1278 697aad7715a1e7306ca76290a3dd4208fbaeddfa M	Z/MM
-:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A	Z/NA
-:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D	Z/ND
-:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M	Z/NM
+cat >.test-recursive-OB <<EOF
+:000000 100644 $(test_oid zero) $(test_oid aa_2) A	AA
+:100644 000000 $(test_oid dd_1) $(test_oid zero) D	DD
+:000000 100644 $(test_oid zero) $(test_oid df_2) A	DF
+:100644 100644 $(test_oid dm_1) $(test_oid dm_2) M	DM
+:000000 100644 $(test_oid zero) $(test_oid ll_2) A	LL
+:100644 000000 $(test_oid md_1) $(test_oid zero) D	MD
+:100644 100644 $(test_oid mm_1) $(test_oid mm_3) M	MM
+:000000 100644 $(test_oid zero) $(test_oid na_1) A	NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D	ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M	NM
+:100644 100644 $(test_oid ss_1) $(test_oid ss_2) M	SS
+:100644 100644 $(test_oid tt_1) $(test_oid tt_3) M	TT
+:000000 100644 $(test_oid zero) $(test_oid zaa2) A	Z/AA
+:100644 000000 $(test_oid zdd1) $(test_oid zero) D	Z/DD
+:100644 100644 $(test_oid zdm1) $(test_oid zdm2) M	Z/DM
+:100644 000000 $(test_oid zmd1) $(test_oid zero) D	Z/MD
+:100644 100644 $(test_oid zmm1) $(test_oid zmm3) M	Z/MM
+:000000 100644 $(test_oid zero) $(test_oid zna1) A	Z/NA
+:100644 000000 $(test_oid znd1) $(test_oid zero) D	Z/ND
+:100644 100644 $(test_oid znm1) $(test_oid znm2) M	Z/NM
 EOF
-cat >.test-plain-AB <<\EOF
-:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M	AA
-:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D	AN
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A	DF
-:040000 000000 6d50f65d3bdab91c63444294d38f08aeff328e42 0000000000000000000000000000000000000000 D	DF
-:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A	DM
-:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A	DN
-:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D	MD
-:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M	MM
-:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M	MN
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A	NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D	ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M	NM
-:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M	TT
-:040000 040000 5e5f22072bb39f6e12cf663a57cb634c76eefb49 1ba523955d5160681af65cb776411f574c1e8155 M	Z
+cat >.test-plain-AB <<EOF
+:100644 100644 $(test_oid aa_1) $(test_oid aa_2) M	AA
+:100644 000000 $(test_oid an_1) $(test_oid zero) D	AN
+:000000 100644 $(test_oid zero) $(test_oid df_2) A	DF
+:040000 000000 $(test_oid df_1) $(test_oid zero) D	DF
+:000000 100644 $(test_oid zero) $(test_oid dm_2) A	DM
+:000000 100644 $(test_oid zero) $(test_oid dn_1) A	DN
+:100644 000000 $(test_oid md_2) $(test_oid zero) D	MD
+:100644 100644 $(test_oid mm_2) $(test_oid mm_3) M	MM
+:100644 100644 $(test_oid mn_2) $(test_oid mn_1) M	MN
+:000000 100644 $(test_oid zero) $(test_oid na_1) A	NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D	ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M	NM
+:100644 100644 $(test_oid tt_2) $(test_oid tt_3) M	TT
+:040000 040000 $(test_oid z__2) $(test_oid z__3) M	Z
 EOF
-cat >.test-recursive-AB <<\EOF
-:100644 100644 ccba72ad3888a3520b39efcf780b9ee64167535d 6aa2b5335b16431a0ef71e5c0a28be69183cf6a2 M	AA
-:100644 000000 7e426fb079479fd67f6d81f984e4ec649a44bc25 0000000000000000000000000000000000000000 D	AN
-:000000 100644 0000000000000000000000000000000000000000 71420ab81e254145d26d6fc0cddee64c1acd4787 A	DF
-:100644 000000 68a6d8b91da11045cf4aa3a5ab9f2a781c701249 0000000000000000000000000000000000000000 D	DF/DF
-:000000 100644 0000000000000000000000000000000000000000 3c4d8de5fbad08572bab8e10eef8dbb264cf0231 A	DM
-:000000 100644 0000000000000000000000000000000000000000 35abde1506ddf806572ff4d407bd06885d0f8ee9 A	DN
-:100644 000000 103d9f89b50b9aad03054b579be5e7aa665f2d57 0000000000000000000000000000000000000000 D	MD
-:100644 100644 b431b272d829ff3aa4d1a5085f4394ab4d3305b6 19989d4559aae417fedee240ccf2ba315ea4dc2b M	MM
-:100644 100644 a716d58de4a570e0038f5c307bd8db34daea021f bd084b0c27c7b6cc34f11d6d0509a29be3caf970 M	MN
-:000000 100644 0000000000000000000000000000000000000000 15885881ea69115351c09b38371f0348a3fb8c67 A	NA
-:100644 000000 a4e179e4291e5536a5e1c82e091052772d2c5a93 0000000000000000000000000000000000000000 D	ND
-:100644 100644 c8f25781e8f1792e3e40b74225e20553041b5226 cdb9a8c3da571502ac30225e9c17beccb8387983 M	NM
-:100644 100644 4c86f9a85fbc5e6804ee2e17a797538fbe785bca c4e4a12231b9fa79a0053cb6077fcb21bb5b135a M	TT
-:100644 100644 8acb8e9750e3f644bf323fcf3d338849db106c77 6c0b99286d0bce551ac4a7b3dff8b706edff3715 M	Z/AA
-:100644 000000 087494262084cefee7ed484d20c8dc0580791272 0000000000000000000000000000000000000000 D	Z/AN
-:000000 100644 0000000000000000000000000000000000000000 d77371d15817fcaa57eeec27f770c505ba974ec1 A	Z/DM
-:000000 100644 0000000000000000000000000000000000000000 beb5d38c55283d280685ea21a0e50cfcc0ca064a A	Z/DN
-:100644 000000 a79ac3be9377639e1c7d1edf1ae1b3a5f0ccd8a9 0000000000000000000000000000000000000000 D	Z/MD
-:100644 100644 61422ba9c2c873416061a88cd40a59a35b576474 697aad7715a1e7306ca76290a3dd4208fbaeddfa M	Z/MM
-:100644 100644 a5c544c21cfcb07eb80a4d89a5b7d1570002edfd b16d7b25b869f2beb124efa53467d8a1550ad694 M	Z/MN
-:000000 100644 0000000000000000000000000000000000000000 d12979c22fff69c59ca9409e7a8fe3ee25eaee80 A	Z/NA
-:100644 000000 a18393c636b98e9bd7296b8b437ea4992b72440c 0000000000000000000000000000000000000000 D	Z/ND
-:100644 100644 3fdbe17fd013303a2e981e1ca1c6cd6e72789087 7e09d6a3a14bd630913e8c75693cea32157b606d M	Z/NM
+cat >.test-recursive-AB <<EOF
+:100644 100644 $(test_oid aa_1) $(test_oid aa_2) M	AA
+:100644 000000 $(test_oid an_1) $(test_oid zero) D	AN
+:000000 100644 $(test_oid zero) $(test_oid df_2) A	DF
+:100644 000000 $(test_oid dfd1) $(test_oid zero) D	DF/DF
+:000000 100644 $(test_oid zero) $(test_oid dm_2) A	DM
+:000000 100644 $(test_oid zero) $(test_oid dn_1) A	DN
+:100644 000000 $(test_oid md_2) $(test_oid zero) D	MD
+:100644 100644 $(test_oid mm_2) $(test_oid mm_3) M	MM
+:100644 100644 $(test_oid mn_2) $(test_oid mn_1) M	MN
+:000000 100644 $(test_oid zero) $(test_oid na_1) A	NA
+:100644 000000 $(test_oid nd_1) $(test_oid zero) D	ND
+:100644 100644 $(test_oid nm_1) $(test_oid nm_2) M	NM
+:100644 100644 $(test_oid tt_2) $(test_oid tt_3) M	TT
+:100644 100644 $(test_oid zaa1) $(test_oid zaa2) M	Z/AA
+:100644 000000 $(test_oid zan1) $(test_oid zero) D	Z/AN
+:000000 100644 $(test_oid zero) $(test_oid zdm2) A	Z/DM
+:000000 100644 $(test_oid zero) $(test_oid zdn1) A	Z/DN
+:100644 000000 $(test_oid zmd2) $(test_oid zero) D	Z/MD
+:100644 100644 $(test_oid zmm2) $(test_oid zmm3) M	Z/MM
+:100644 100644 $(test_oid zmn2) $(test_oid zmn1) M	Z/MN
+:000000 100644 $(test_oid zero) $(test_oid zna1) A	Z/NA
+:100644 000000 $(test_oid znd1) $(test_oid zero) D	Z/ND
+:100644 100644 $(test_oid znm1) $(test_oid znm2) M	Z/NM
 EOF
 
 cmp_diff_files_output () {

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

* [PATCH v2 14/14] t4009: make hash size independent
  2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
                     ` (12 preceding siblings ...)
  2019-08-26  1:43   ` [PATCH v2 13/14] t4002: make hash independent brian m. carlson
@ 2019-08-26  1:43   ` brian m. carlson
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2019-08-26  1:43 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Eric Sunshine, Johannes Schindelin

Instead of hard-coding object IDs, compute them and use those in the
comparison.  Note that the comparison code ignores the actual object
IDs, but does check that they're the right size, so computing them is
the easiest way to ensure that they are.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 t/t4009-diff-rename-4.sh | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh
index 3641fd84d6..b63bdf031f 100755
--- a/t/t4009-diff-rename-4.sh
+++ b/t/t4009-diff-rename-4.sh
@@ -14,6 +14,7 @@ test_expect_success \
     'cat "$TEST_DIRECTORY"/diff-lib/COPYING >COPYING &&
      echo frotz >rezrov &&
     git update-index --add COPYING rezrov &&
+    orig=$(git hash-object COPYING) &&
     tree=$(git write-tree) &&
     echo $tree'
 
@@ -22,6 +23,8 @@ test_expect_success \
     'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 &&
     sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 &&
     rm -f COPYING &&
+    c1=$(git hash-object COPYING.1) &&
+    c2=$(git hash-object COPYING.2) &&
     git update-index --add --remove COPYING COPYING.?'
 
 # tree has COPYING and rezrov.  work tree has COPYING.1 and COPYING.2,
@@ -31,11 +34,11 @@ test_expect_success \
 
 git diff-index -z -C $tree >current
 
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+cat >expected <<EOF
+:100644 100644 $orig $c1 C1234
 COPYING
 COPYING.1
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 R1234
+:100644 100644 $orig $c2 R1234
 COPYING
 COPYING.2
 EOF
@@ -57,10 +60,10 @@ test_expect_success \
 # about rezrov.
 
 git diff-index -z -C $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 06c67961bbaed34a127f76d261f4c0bf73eda471 M
+cat >expected <<EOF
+:100644 100644 $orig $c2 M
 COPYING
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+:100644 100644 $orig $c1 C1234
 COPYING
 COPYING.1
 EOF
@@ -82,8 +85,8 @@ test_expect_success \
      git update-index --add --remove COPYING COPYING.1'
 
 git diff-index -z -C --find-copies-harder $tree >current
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234
+cat >expected <<EOF
+:100644 100644 $orig $c1 C1234
 COPYING
 COPYING.1
 EOF

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

* [PATCH] mktag: don't check SHA-1 object length under SHA-256
  2019-08-26  1:43   ` [PATCH v2 10/14] t3800: make hash-size independent brian m. carlson
@ 2020-11-23 12:01     ` Ævar Arnfjörð Bjarmason
  2020-11-23 19:01       ` Junio C Hamano
  2020-11-23 21:34       ` Jeff King
  0 siblings, 2 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-23 12:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the hardcoded minimum tag length size to vary based on whether
we're operating in the SHA-1 or SHA-256 mode, and update the "mktag"
documentation, tests and code comments to reflect that this command
can take either SHA-1 or SHA-256 input.

Let's make the code more self-documenting by verbosely inlining what a
minimum tag looks like. The fixed-string strlen() will be optimized
away by any modern compiler. This also future-proofs us for any future
hash function transition.

Then change the tests amended in acb49d1cc8b (t3800: make hash-size
independent, 2019-08-18) even more for SHA-256. Some of the tests were
failing for the wrong reasons. E.g. yes <some sha-1 length garbage> is
an invalid SHA-1, but we should test <some sha256 length garbage> when
under SHA-256. For testing an invalid non-hexadecimal object ID let's
use ROT13.

For the "object line label check" test the "139e9b339..." SHA-1 didn't
exist, but what's actually being tested there is getting "xxxxxx"
instead of "object", so let's provide a valid SHA there
instead. There's no need to make or hardcode a nonexisting object ID.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt |  2 +-
 builtin/mktag.c             | 26 +++++++++++++-------
 t/t3800-mktag.sh            | 47 ++++++++++++++++++++++++++-----------
 3 files changed, 52 insertions(+), 23 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index fa6a7561236..bbcc0a086bf 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -23,7 +23,7 @@ Tag Format
 A tag signature file, to be fed to this command's standard input,
 has a very simple fixed format: four lines of
 
-  object <sha1>
+  object <sha>
   type <typename>
   tag <tagname>
   tagger <tagger>
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4982d3a93ef..3fa17243e34 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -5,13 +5,15 @@
 
 /*
  * A signature file has a very simple fixed format: four lines
- * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
+ * of "object <sha>" + "type <typename>" + "tag <tagname>" +
  * "tagger <committer>", followed by a blank line, a free-form tag
  * message and a signature block that git itself doesn't care about,
  * but that can be verified with gpg or similar.
  *
- * The first four lines are guaranteed to be at least 83 bytes:
- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
+ * The first four lines are guaranteed to be either 83 or 107 bytes;
+ * depending on whether we're referencing a SHA-1 or SHA-256 tag.
+ *
+ * "object <sha1>\n" is 48 or a 72 bytes, "type tag\n" at 9 bytes is the
  * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
  * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
  * the shortest possible tagger-line.
@@ -46,9 +48,17 @@ static int verify_tag(char *buffer, unsigned long size)
 	struct object_id oid;
 	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
 	size_t len;
-
-	if (size < 84)
-		return error("wanna fool me ? you obviously got the size wrong !");
+	int minimum_size =
+		/* Minimum possible input, see t/t3800-mktag.sh */
+		strlen("object ") + the_hash_algo->hexsz + strlen("\n") +
+		strlen("type tag\n") +
+		strlen("tag x\n") +
+		strlen("tagger . <> 0 +0000\n") +
+		strlen("\n");
+
+	if (size < minimum_size)
+		return error("got %"PRIuMAX" bytes of input, need at least %d bytes",
+			     size, minimum_size);
 
 	buffer[size] = 0;
 
@@ -58,7 +68,7 @@ static int verify_tag(char *buffer, unsigned long size)
 		return error("char%d: does not start with \"object \"", 0);
 
 	if (parse_oid_hex(object + 7, &oid, &p))
-		return error("char%d: could not get SHA1 hash", 7);
+		return error("char%d: expected object ID, got garbage", 7);
 
 	/* Verify type line */
 	type_line = p + 1;
@@ -166,7 +176,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	}
 
 	/* Verify it for some basic sanity: it needs to start with
-	   "object <sha1>\ntype\ntagger " */
+	   "object <sha>\ntype\ntagger " */
 	if (verify_tag(buf.buf, buf.len) < 0)
 		die("invalid tag signature file");
 
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index d696aa4e52e..93a19bb8df9 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -26,24 +26,42 @@ test_expect_success 'setup' '
 	echo Hello >A &&
 	git update-index --add A &&
 	git commit -m "Initial commit" &&
-	head=$(git rev-parse --verify HEAD)
+	head=$(git rev-parse --verify HEAD) &&
+
+	git tag -m"some tag" annotated &&
+	annotated=$(git rev-parse --verify annotated)
 '
 
 ############################################################
 #  1. length check
-
-cat >tag.sig <<EOF
-too short for a tag
-EOF
-
-check_verify_failure 'Tag object length check' \
-	'^error: .*size wrong.*$'
+for objType in t ta tag
+do
+	cat >tag.sig <<-EOF
+	object $annotated
+	type $objType
+	tag x
+	tagger . <> 0 +0000
+
+	EOF
+	len=$(wc -c tag.sig)
+
+	if test $objType = "tag"
+	then
+		test_expect_success "Tag object length check $len passed" '
+			git mktag <tag.sig >.git/refs/tags/x 2>message &&
+			git rev-parse refs/tags/x
+		'
+	else
+		check_verify_failure "Tag object length check on length $len" \
+			'^error: got .* bytes of input, need at least'
+	fi
+done
 
 ############################################################
 #  2. object line label check
 
 cat >tag.sig <<EOF
-xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
+xxxxxx $head
 type tag
 tag mytag
 tagger . <> 0 +0000
@@ -53,17 +71,18 @@ EOF
 check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
 
 ############################################################
-#  3. object line SHA1 check
+#  3. object line SHA check
 
+invalid_sha=$(echo $head | tr A-Za-z N-ZA-Mn-za-m)
 cat >tag.sig <<EOF
-object zz9e9b33986b1c2670fff52c5067603117b3e895
+object $invalid_sha
 type tag
 tag mytag
 tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
+check_verify_failure '"object" line object check' '^error: char7: .*expected object ID, got garbage'
 
 ############################################################
 #  4. type line label check
@@ -125,7 +144,7 @@ check_verify_failure '"type" line type-name length check' \
 	'^error: char.*: type too long$'
 
 ############################################################
-#  9. verify object (SHA1/type) check
+#  9. verify object (SHA/type) check
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
@@ -135,7 +154,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure 'verify object (SHA1/type) check' \
+check_verify_failure 'verify object (SHA/type) check' \
 	'^error: char7: could not verify object.*$'
 
 ############################################################
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: [PATCH] mktag: don't check SHA-1 object length under SHA-256
  2020-11-23 12:01     ` [PATCH] mktag: don't check SHA-1 object length under SHA-256 Ævar Arnfjörð Bjarmason
@ 2020-11-23 19:01       ` Junio C Hamano
  2020-11-23 21:36         ` Jeff King
  2020-11-23 21:34       ` Jeff King
  1 sibling, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2020-11-23 19:01 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
> index fa6a7561236..bbcc0a086bf 100644
> --- a/Documentation/git-mktag.txt
> +++ b/Documentation/git-mktag.txt
> @@ -23,7 +23,7 @@ Tag Format
>  A tag signature file, to be fed to this command's standard input,
>  has a very simple fixed format: four lines of
>  
> -  object <sha1>
> +  object <sha>

Perhaps <hash>? or <objectname>.

> diff --git a/builtin/mktag.c b/builtin/mktag.c
> index 4982d3a93ef..3fa17243e34 100644
> --- a/builtin/mktag.c
> +++ b/builtin/mktag.c
> @@ -5,13 +5,15 @@
>  
>  /*
>   * A signature file has a very simple fixed format: four lines
> - * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
> + * of "object <sha>" + "type <typename>" + "tag <tagname>" +

Ditto.

>   * "tagger <committer>", followed by a blank line, a free-form tag
>   * message and a signature block that git itself doesn't care about,
>   * but that can be verified with gpg or similar.
>   *
> + * The first four lines are guaranteed to be either 83 or 107 bytes;
> + * depending on whether we're referencing a SHA-1 or SHA-256 tag.
> + *
> + * "object <sha1>\n" is 48 or a 72 bytes, "type tag\n" at 9 bytes is the

At least <sha> to be consistent with the above, or <hash>.

>   * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
>   * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
>   * the shortest possible tagger-line.
> @@ -46,9 +48,17 @@ static int verify_tag(char *buffer, unsigned long size)
>  	struct object_id oid;
>  	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
>  	size_t len;
> -
> -	if (size < 84)
> -		return error("wanna fool me ? you obviously got the size wrong !");
> +	int minimum_size =
> +		/* Minimum possible input, see t/t3800-mktag.sh */
> +		strlen("object ") + the_hash_algo->hexsz + strlen("\n") +
> +		strlen("type tag\n") +
> +		strlen("tag x\n") +
> +		strlen("tagger . <> 0 +0000\n") +
> +		strlen("\n");
> +
> +	if (size < minimum_size)
> +		return error("got %"PRIuMAX" bytes of input, need at least %d bytes",
> +			     size, minimum_size);

I agree with the patch that this message is not _("marked for
translation"), as it is output from a plumbing.

You need to cast "size" as "(uintmax_t)size" here, probably.  


> @@ -58,7 +68,7 @@ static int verify_tag(char *buffer, unsigned long size)
>  		return error("char%d: does not start with \"object \"", 0);
>  
>  	if (parse_oid_hex(object + 7, &oid, &p))
> -		return error("char%d: could not get SHA1 hash", 7);
> +		return error("char%d: expected object ID, got garbage", 7);

Here you say object ID, which is better than <hash> or <sha>.  Let's
be consistent (I'd say "object name" if I were choosing which to
use).

>  	/* Verify it for some basic sanity: it needs to start with
> -	   "object <sha1>\ntype\ntagger " */
> +	   "object <sha>\ntype\ntagger " */

Here it is <sha>.

> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index d696aa4e52e..93a19bb8df9 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -26,24 +26,42 @@ test_expect_success 'setup' '
>  	echo Hello >A &&
>  	git update-index --add A &&
>  	git commit -m "Initial commit" &&
> -	head=$(git rev-parse --verify HEAD)
> +	head=$(git rev-parse --verify HEAD) &&
> +
> +	git tag -m"some tag" annotated &&

A SP between -m and its argument, like four lines above?

> +	annotated=$(git rev-parse --verify annotated)
>  '
>  
>  ############################################################
>  #  1. length check
> +for objType in t ta tag

cute ;-)

> +do
> +	cat >tag.sig <<-EOF
> +	object $annotated
> +	type $objType
> +	tag x
> +	tagger . <> 0 +0000
> +
> +	EOF
> +	len=$(wc -c tag.sig)
> +
> +	if test $objType = "tag"
> +	then
> +		test_expect_success "Tag object length check $len passed" '

Here $len may see excess leading whitespace depending on what "wc
-c" on the platform does, but the only effect of that is a bit
uglier test title, so it would be oK.

> +			git mktag <tag.sig >.git/refs/tags/x 2>message &&

Do we use "message" in any way?  

Let's not write directly into filesystem; instead do

			tagobj=$(git mktag <tag.sig) &&
			git update-ref refs/tags/x $tagobj &&

or something like that.

> +			git rev-parse refs/tags/x
> +		'
> +	else
> +		check_verify_failure "Tag object length check on length $len" \
> +			'^error: got .* bytes of input, need at least'

OK.  This is not an issue with this patch, but I do not know why we
want a subshell in check_verify_failure.  May want to clean it up
but not in this patch.

> +	fi
> +done
>  
>  ############################################################
>  #  2. object line label check
>  
>  cat >tag.sig <<EOF
> -xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
> +xxxxxx $head
>  type tag
>  tag mytag
>  tagger . <> 0 +0000
> @@ -53,17 +71,18 @@ EOF
>  check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
>  
>  ############################################################
> -#  3. object line SHA1 check
> +#  3. object line SHA check

You say "object" or "object ID" to the tester below; let's use that
consistently instead of SHA.

> +invalid_sha=$(echo $head | tr A-Za-z N-ZA-Mn-za-m)
>  cat >tag.sig <<EOF
> -object zz9e9b33986b1c2670fff52c5067603117b3e895
> +object $invalid_sha
>  type tag
>  tag mytag
>  tagger . <> 0 +0000
>  
>  EOF
>  
> -check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
> +check_verify_failure '"object" line object check' '^error: char7: .*expected object ID, got garbage'
>  
>  ############################################################
>  #  4. type line label check
> @@ -125,7 +144,7 @@ check_verify_failure '"type" line type-name length check' \
>  	'^error: char.*: type too long$'
>  
>  ############################################################
> -#  9. verify object (SHA1/type) check
> +#  9. verify object (SHA/type) check
>  
>  cat >tag.sig <<EOF
>  object $(test_oid deadbeef)
> @@ -135,7 +154,7 @@ tagger . <> 0 +0000
>  
>  EOF
>  
> -check_verify_failure 'verify object (SHA1/type) check' \
> +check_verify_failure 'verify object (SHA/type) check' \
>  	'^error: char7: could not verify object.*$'
>  
>  ############################################################

Ditto.

Thanks.

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

* Re: [PATCH] mktag: don't check SHA-1 object length under SHA-256
  2020-11-23 12:01     ` [PATCH] mktag: don't check SHA-1 object length under SHA-256 Ævar Arnfjörð Bjarmason
  2020-11-23 19:01       ` Junio C Hamano
@ 2020-11-23 21:34       ` Jeff King
  2020-11-24  1:07         ` brian m. carlson
                           ` (13 more replies)
  1 sibling, 14 replies; 229+ messages in thread
From: Jeff King @ 2020-11-23 21:34 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Mon, Nov 23, 2020 at 01:01:11PM +0100, Ævar Arnfjörð Bjarmason wrote:

> @@ -46,9 +48,17 @@ static int verify_tag(char *buffer, unsigned long size)
>  	struct object_id oid;
>  	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
>  	size_t len;
> -
> -	if (size < 84)
> -		return error("wanna fool me ? you obviously got the size wrong !");
> +	int minimum_size =
> +		/* Minimum possible input, see t/t3800-mktag.sh */
> +		strlen("object ") + the_hash_algo->hexsz + strlen("\n") +
> +		strlen("type tag\n") +
> +		strlen("tag x\n") +
> +		strlen("tagger . <> 0 +0000\n") +
> +		strlen("\n");

This is an obvious improvement, but I have to wonder whether this kind
of "minimum size" up-front check is really buying us much. We do a lot
of fixed-size memcmps in the rest of the function.

In the early bits, like:

  if (memcmp(type_line - 1, "\ntype ", 6))
          return error("char%d: could not find \"\\ntype \"", 47);

that is saving us from going off the edge of a too-small input (though
wow, that bare "47" is really horrific).

But later, we'll do this:

  if (memcmp(tagger_line, "tagger ", 7))
           return error("char%"PRIuMAX": could not find \"tagger \"",
                   (uintmax_t) (tagger_line - buffer));

We've already parsed "tag x" at this point, and "x" can be arbitrarily
long. Are we sure we have 7 bytes of the buffer left?

The buffer always has a trailing NUL in it, so it would never match but
memcmp() is allowed to look at the whole thing (e.g., it can start at
the end, or do quadword comparisons). And that usually wouldn't matter,
but may depending on how the strbuf grows, and whether our heap buffer
is near the end of the last allocate page. Try this:

  git init
  git commit --allow-empty -m foo
  {
    echo "object $(git rev-parse HEAD)"
    echo "type commit"
    perl -e 'print "tag "; print "a" x 4026; print "\n"'
  } | git mktag

which ASan will complain about, since the "tagger" memcmp reads past the
end of the buffer (I found 4026 by running that in a loop of 1..4096).

I think this whole thing would be better written to just parse
left-to-right within the buffer, using bits like skip_prefix() that rely
on us having a trailing NUL (which we always will, and there should not
be one inside the header section).

This is how fsck_tag() does it. In fact, it seems like we could just
reuse fsck_tag() here. It wants to pass an oid to report(), but it would
be OK to use null_oid here; ultimately it just ends up back in our
callback error_func().

-Peff

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

* Re: [PATCH] mktag: don't check SHA-1 object length under SHA-256
  2020-11-23 19:01       ` Junio C Hamano
@ 2020-11-23 21:36         ` Jeff King
  2020-11-23 22:17           ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Jeff King @ 2020-11-23 21:36 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Ævar Arnfjörð Bjarmason, git, brian m . carlson,
	Eric Sunshine, Johannes Schindelin

On Mon, Nov 23, 2020 at 11:01:57AM -0800, Junio C Hamano wrote:

> > @@ -58,7 +68,7 @@ static int verify_tag(char *buffer, unsigned long size)
> >  		return error("char%d: does not start with \"object \"", 0);
> >  
> >  	if (parse_oid_hex(object + 7, &oid, &p))
> > -		return error("char%d: could not get SHA1 hash", 7);
> > +		return error("char%d: expected object ID, got garbage", 7);
> 
> Here you say object ID, which is better than <hash> or <sha>.  Let's
> be consistent (I'd say "object name" if I were choosing which to
> use).

It might just be me, but "object name" makes me think we'd take any name
(e.g., a refname that resolves to an object), whereas "object id" would
mean the object's hash specifically. And in this instance we only allow
the latter.

I agree very much with your other comments that if we are changing
these, we should get away from <sha> completely.

-Peff

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

* Re: [PATCH] mktag: don't check SHA-1 object length under SHA-256
  2020-11-23 21:36         ` Jeff King
@ 2020-11-23 22:17           ` Junio C Hamano
  2020-11-24  0:47             ` Jeff King
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2020-11-23 22:17 UTC (permalink / raw)
  To: Jeff King
  Cc: Ævar Arnfjörð Bjarmason, git, brian m . carlson,
	Eric Sunshine, Johannes Schindelin

Jeff King <peff@peff.net> writes:

> It might just be me, but "object name" makes me think we'd take any name
> (e.g., a refname that resolves to an object), whereas "object id" would
> mean the object's hash specifically. And in this instance we only allow
> the latter.

Yeah, but glossary-content is very much explicit about this.  "name"
is the full hexadecimal hash, "identifier" is a synonym for it.  And
"id" does not even appear to be defined.  We used to call "any name
that refers to an object" an "extended SHA-1", but I haven't seen
the phrase used for a long time on the list.

> I agree very much with your other comments that if we are changing
> these, we should get away from <sha> completely.

Yup.

I've always found it cumbersome that, when I want to mean a full hex
representation, I have to say "40-byte object name".  It is not even
technically correct these days with SHA-256.

We'd probably need to update the glossary to make sure we have ways
to refer to "a way, any way, to name an object" and to "the
hexadecimal representation of the full hash value that refers to an
object".  Here is my attempt to redefine "object ID" to be the
narrower one, while losing "usually a 40-character hex" from "object
name".  I am not sure if I like the result as a whole, but it
certainly is nice to have a word or phrase shorter than "full hex
object name" to refer to it.

Thanks.

 Documentation/glossary-content.txt | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git c/Documentation/glossary-content.txt w/Documentation/glossary-content.txt
index 090c888335..e2ab920911 100644
--- c/Documentation/glossary-content.txt
+++ w/Documentation/glossary-content.txt
@@ -262,13 +262,20 @@ This commit is referred to as a "merge commit", or sometimes just a
 	identified by its <<def_object_name,object name>>. The objects usually
 	live in `$GIT_DIR/objects/`.
 
+[[def_object_id]]object ID::
+	Synonym for <<def_object_identifier,object identifier>>.
+
 [[def_object_identifier]]object identifier::
-	Synonym for <<def_object_name,object name>>.
+	An <<def_object_name, object name>> written as an
+	unabbreviated hexadecimal representation of the hash value
+	that uniquely identifies an <<def_object,object>>.
+	Also colloquially called <<def_SHA1,SHA-1>>.
 
 [[def_object_name]]object name::
-	The unique identifier of an <<def_object,object>>.  The
-	object name is usually represented by a 40 character
-	hexadecimal string.  Also colloquially called <<def_SHA1,SHA-1>>.
+	A name that identifies an <<def_object,object>> uniquely,
+	which can be given in various ways, including but not
+	limited to, the object's full <<def_object_identifier,object
+	identifier>>, a <<def_ref,ref>> that refers to the object.
 
 [[def_object_type]]object type::
 	One of the identifiers "<<def_commit_object,commit>>",

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

* Re: [PATCH] mktag: don't check SHA-1 object length under SHA-256
  2020-11-23 22:17           ` Junio C Hamano
@ 2020-11-24  0:47             ` Jeff King
  0 siblings, 0 replies; 229+ messages in thread
From: Jeff King @ 2020-11-24  0:47 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Ævar Arnfjörð Bjarmason, git, brian m . carlson,
	Eric Sunshine, Johannes Schindelin

On Mon, Nov 23, 2020 at 02:17:32PM -0800, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > It might just be me, but "object name" makes me think we'd take any name
> > (e.g., a refname that resolves to an object), whereas "object id" would
> > mean the object's hash specifically. And in this instance we only allow
> > the latter.
> 
> Yeah, but glossary-content is very much explicit about this.  "name"
> is the full hexadecimal hash, "identifier" is a synonym for it.  And
> "id" does not even appear to be defined.  We used to call "any name
> that refers to an object" an "extended SHA-1", but I haven't seen
> the phrase used for a long time on the list.

OK, then my "it might just be me" is clearly just me. :)

I think the distinction I laid out earlier is nicer, but it may not be
worth the trouble of trying to _change_ nomenclature at this point.
Let's see what your glossary changes say...

> I've always found it cumbersome that, when I want to mean a full hex
> representation, I have to say "40-byte object name".  It is not even
> technically correct these days with SHA-256.

Yeah, that is both long and wrong. I'd maybe say "hex object id" in some
cases, which is slightly less cumbersome and extends to sha256. And
distinguishes it from a binary object id (though see below).

>  Documentation/glossary-content.txt | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git c/Documentation/glossary-content.txt w/Documentation/glossary-content.txt
> index 090c888335..e2ab920911 100644
> --- c/Documentation/glossary-content.txt
> +++ w/Documentation/glossary-content.txt
> @@ -262,13 +262,20 @@ This commit is referred to as a "merge commit", or sometimes just a
>  	identified by its <<def_object_name,object name>>. The objects usually
>  	live in `$GIT_DIR/objects/`.
>  
> +[[def_object_id]]object ID::
> +	Synonym for <<def_object_identifier,object identifier>>.
> +
>  [[def_object_identifier]]object identifier::
> -	Synonym for <<def_object_name,object name>>.
> +	An <<def_object_name, object name>> written as an
> +	unabbreviated hexadecimal representation of the hash value
> +	that uniquely identifies an <<def_object,object>>.
> +	Also colloquially called <<def_SHA1,SHA-1>>.

You might want to touch on "binary" here, too, with something like:

  This may also be used to refer to the binary representation of the
  hash value (e.g., as found within Git trees). Unless specified, this
  term typically implies the hexadecimal representation.

But maybe that is overkill. When we are talking about the command line
interface, stdin, etc, I can't think of a place where we'd take the
binary ("hash-object -t tree", but I don't really count that).

>  [[def_object_name]]object name::
> -	The unique identifier of an <<def_object,object>>.  The
> -	object name is usually represented by a 40 character
> -	hexadecimal string.  Also colloquially called <<def_SHA1,SHA-1>>.
> +	A name that identifies an <<def_object,object>> uniquely,
> +	which can be given in various ways, including but not
> +	limited to, the object's full <<def_object_identifier,object
> +	identifier>>, a <<def_ref,ref>> that refers to the object.

This all seems like an improvement to me, though the real question is
how often the term "object name" appears in the _other_ manpages to
refer to the more limited case.

-Peff

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

* Re: [PATCH] mktag: don't check SHA-1 object length under SHA-256
  2020-11-23 21:34       ` Jeff King
@ 2020-11-24  1:07         ` brian m. carlson
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                           ` (12 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: brian m. carlson @ 2020-11-24  1:07 UTC (permalink / raw)
  To: Jeff King
  Cc: Ævar Arnfjörð Bjarmason, git, Junio C Hamano,
	Eric Sunshine, Johannes Schindelin

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

On 2020-11-23 at 21:34:21, Jeff King wrote:
> This is how fsck_tag() does it. In fact, it seems like we could just
> reuse fsck_tag() here. It wants to pass an oid to report(), but it would
> be OK to use null_oid here; ultimately it just ends up back in our
> callback error_func().

I would very much appreciate getting rid of this custom code.  It was a
pain during the SHA-256 transition, and even with significant effort, it
appears I missed a few parts.  Also, while I'm for casual language, its
use here is going to be a little hard to understand for non-native
speakers.

Moreover, when we start mapping objects to write the SHA-1 values into
the loose object index (which is a series I'm slowly working on), most
of this custom code is going to have to disappear or be coalesced
anyway.  If we can use an existing, more robust function now, so much
the better.
-- 
brian m. carlson (he/him or they/them)
Houston, Texas, US

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

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

* [RFC/PATCH 00/12] make "mktag" use fsck_tag()
  2020-11-23 21:34       ` Jeff King
  2020-11-24  1:07         ` brian m. carlson
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                             ` (10 more replies)
  2020-11-26  1:28         ` [RFC/PATCH 01/12] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
                           ` (11 subsequent siblings)
  13 siblings, 11 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

This is a replacement for my earlier one-off SHA-1->SHA-256 cleanup
patch, on the basis of Jeff's comment that we should just be using
fsck_tag().

I was pretty much ready to send this as a non-RFC, but as seen in
12/12 fully duplicating the mktag logic in the context of using
fsck_tag() is a bit tricker than it looks. That breakage was only
revealed by a test I added while writing this.

The result is still nicer than the current code, but even then this
series breaks the tests mid-way through (in "improve verify_object()
test coverage"), but fixes them in 12/12.

I ran out of time to make this more sensible, but wanted to send an
RFC with the current state, and in case anyone else has any better
ideas for how to deal with 12/12. This could be applied as a non-RFC
by squashing 12/12 into the "use fsck instead of custom verify_tag"
change.

Ævar Arnfjörð Bjarmason (12):
  mktag: use default strbuf_read() hint
  mktag: reword write_object_file() error
  mktag: remove redundant braces in one-line body "if"
  mktag tests: don't needlessly use a subshell
  mktag tests: remove needless SHA-1 hardcoding
  mktag tests: improve verify_object() test coverage
  fsck: add new "extra" checks for "mktag"
  mktag: use fsck instead of custom verify_tag()
  mktag: remove now-unused verify_tag() code
  mktag doc: update to explain why to use this
  mktag docs: say <hash> not <sha1>
  mktag: bring back some of the verify_object() logic

 Documentation/git-hash-object.txt |   4 +
 Documentation/git-mktag.txt       |  31 ++++-
 builtin/mktag.c                   | 207 ++++++++++--------------------
 fsck.c                            |  32 ++++-
 fsck.h                            |   2 +
 t/t1006-cat-file.sh               |   2 +-
 t/t3800-mktag.sh                  | 103 ++++++++++-----
 7 files changed, 202 insertions(+), 179 deletions(-)

-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 01/12] mktag: use default strbuf_read() hint
  2020-11-23 21:34       ` Jeff King
  2020-11-24  1:07         ` brian m. carlson
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  1:28         ` [RFC/PATCH 02/12] mktag: reword write_object_file() error Ævar Arnfjörð Bjarmason
                           ` (10 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the hardcoded hint of 2^12 to 0. The default strbuf hint is
perfectly fine here, and the only reason we were hardcoding it is
because it survived migration from a pre-strbuf fixed-sized buffer.

See fd17f5b5f77 (Replace all read_fd use with strbuf_read, and get rid
of it., 2007-09-10) for that migration.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4982d3a93e..ff7ac8e0e5 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,7 +161,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 4096) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0) {
 		die_errno("could not read from stdin");
 	}
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 02/12] mktag: reword write_object_file() error
  2020-11-23 21:34       ` Jeff King
                           ` (2 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 01/12] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  1:28         ` [RFC/PATCH 03/12] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
                           ` (9 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the error message emitted when write_object_file() fails to
make more sense. At this point we're not writing a "tag file" (which
as an aside we never do, we just write to stdout). We are writing an
annotated tag object, let's say that instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index ff7ac8e0e5..603b55aca0 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -171,7 +171,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 		die("invalid tag signature file");
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
-		die("unable to write tag file");
+		die("unable to write annotated tag object");
 
 	strbuf_release(&buf);
 	printf("%s\n", oid_to_hex(&result));
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 03/12] mktag: remove redundant braces in one-line body "if"
  2020-11-23 21:34       ` Jeff King
                           ` (3 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 02/12] mktag: reword write_object_file() error Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  1:28         ` [RFC/PATCH 04/12] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
                           ` (8 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

This minor stylistic churn is usually something we'd avoid, but if we
don't do this then the file after changes in subsequent commits will
only have this minor style inconsistency, so let's change this while
we're at it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 603b55aca0..dc354828f7 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,9 +161,8 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 0) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
-	}
 
 	/* Verify it for some basic sanity: it needs to start with
 	   "object <sha1>\ntype\ntagger " */
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 04/12] mktag tests: don't needlessly use a subshell
  2020-11-23 21:34       ` Jeff King
                           ` (4 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 03/12] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  1:28         ` [RFC/PATCH 05/12] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
                           ` (7 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The use of a subshell dates back to e9b20943b77 (t/t3800: do not use a
temporary file to hold expected result., 2008-01-04). It's not needed
anymore, if it ever was.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index d696aa4e52..0e411e3c45 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -14,7 +14,7 @@ test_description='git mktag: tag object verify test'
 check_verify_failure () {
 	expect="$2"
 	test_expect_success "$1" '
-		( test_must_fail git mktag <tag.sig 2>message ) &&
+		test_must_fail git mktag <tag.sig 2>message &&
 		grep "$expect" message
 	'
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 05/12] mktag tests: remove needless SHA-1 hardcoding
  2020-11-23 21:34       ` Jeff King
                           ` (5 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 04/12] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  7:49           ` Jeff King
  2020-11-26  1:28         ` [RFC/PATCH 06/12] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
                           ` (6 subsequent siblings)
  13 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the tests amended in acb49d1cc8b (t3800: make hash-size
independent, 2019-08-18) even more to make them independent of either
SHA-1 or SHA-256.

Some of these tests were failing for the wrong reasons. The first one
being modified here would fail because the line starts with "xxxxxx"
instead of "object", the rest of the line doesn't matter. Let's just
put a valid hash on the rest of the line anyway to narrow the test
down for just the s/object/xxxxxx/ case.

The second one being modified here would fail under
GIT_TEST_DEFAULT_HASH=sha256 because <some sha-1 length garbage> is an
invalid SHA-256, but we should really be testing <some sha-256 length
garbage> when under SHA-256.

This doesn't really matter since we should be able to trust other
parts of the code to validate things in the 0-9a-f range, but let's do
it for good measure.

There's a later test which tests an invalid SHA which looks like a
valid one, to stress the "We refuse to tag something we can't
verify[...]" logic in mktag.c.

But here we're testing for a SHA-length string which contains
characters outside of the /[0-9a-f]/i set. Let's just do that with a
ROT13 invocation.

We could get really unlucky and switch to a future hash function that
just happens to produce all [0-9] output for this particular input,
but that's very unlikely.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0e411e3c45..b5013af2aa 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -43,7 +43,7 @@ check_verify_failure 'Tag object length check' \
 #  2. object line label check
 
 cat >tag.sig <<EOF
-xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
+xxxxxx $head
 type tag
 tag mytag
 tagger . <> 0 +0000
@@ -53,10 +53,11 @@ EOF
 check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
 
 ############################################################
-#  3. object line SHA1 check
+#  3. object line SHA check
 
+invalid_sha=$(echo $head | tr A-Za-z N-ZA-Mn-za-m)
 cat >tag.sig <<EOF
-object zz9e9b33986b1c2670fff52c5067603117b3e895
+object $invalid_sha
 type tag
 tag mytag
 tagger . <> 0 +0000
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 06/12] mktag tests: improve verify_object() test coverage
  2020-11-23 21:34       ` Jeff King
                           ` (6 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 05/12] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  1:28         ` [RFC/PATCH 07/12] fsck: add new "extra" checks for "mktag" Ævar Arnfjörð Bjarmason
                           ` (5 subsequent siblings)
  13 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The verify_object() function in "mktag.c" is tasked with ensuring that
our tag refers to a valid object. The existing test for this might
fail because it was also testing that "type taggg" didn't refer to a
valid object type (it should be "type tag").

Let's split these tests up, so we're testing all combinations of a
non-existing object and in invalid "type" line.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index b5013af2aa..3801d3a285 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -128,6 +128,28 @@ check_verify_failure '"type" line type-name length check' \
 ############################################################
 #  9. verify object (SHA1/type) check
 
+cat >tag.sig <<EOF
+object $(test_oid deadbeef)
+type tag
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (SHA1/type) check' \
+	'^error: char7: could not verify object.*$'
+
+cat >tag.sig <<EOF
+object $head
+type tagggg
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (SHA1/type) check' \
+	'^fatal: invalid object type'
+
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
 type tagggg
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 07/12] fsck: add new "extra" checks for "mktag"
  2020-11-23 21:34       ` Jeff King
                           ` (7 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 06/12] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  8:02           ` Jeff King
  2020-11-26  1:28         ` [RFC/PATCH 08/12] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
                           ` (4 subsequent siblings)
  13 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Add optional "extra" checks to fsck, these are needed to eventually
replace the custom not-quite-fsck code in mktag.c.

The mktag checks differ from fsck_tag() in several ways, one of those
is that fsck doesn't know how to refuse an object with custom headers,
and isn't strict about header and body newline separation.

Teach it how to optionally report these. I thought the best way to do
that given the current structure of the code was to add a new "extra"
category in addition to error/warn/info. Under --strict the "info"
becomes a "warn" and "warn" becomes "error". Existing users of
fsck's (and others, e.g. index-pack) --strict option rely on this.

By adding an "extra" category and only reporting it based on a flag in
fsck_options callers can opt-in to these "extra" messages, which
they'll then need to deal with in their own "error_func".

No tests are being added for this new functionality, they're added in
a subsequent commit where we teach "mktag" to use this new validation
mode.

I'm not changing fsck_commit() to validate commit objects like this
either, we could do that, but unlike in the tag case that code
wouldn't be used anywhere. If someone wants to write a "mkcommit" they
which behaves like "mktag" they can borrow or refactor this logic for
use in fsck_commit().

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 fsck.c | 32 +++++++++++++++++++++++++++++++-
 fsck.h |  2 ++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/fsck.c b/fsck.c
index f82e2fe9e3..3c25df2244 100644
--- a/fsck.c
+++ b/fsck.c
@@ -80,7 +80,10 @@ static struct oidset gitmodules_done = OIDSET_INIT;
 	/* infos (reported as warnings, but ignored by default) */ \
 	FUNC(GITMODULES_PARSE, INFO) \
 	FUNC(BAD_TAG_NAME, INFO) \
-	FUNC(MISSING_TAGGER_ENTRY, INFO)
+	FUNC(MISSING_TAGGER_ENTRY, INFO) \
+	/* extra (only reported when requested) */ \
+	FUNC(EXTRA_HEADER_ENTRY, EXTRA) \
+	FUNC(EXTRA_HEADER_BODY_NEWLINE, EXTRA)
 
 #define MSG_ID(id, msg_type) FSCK_MSG_##id,
 enum fsck_msg_id {
@@ -975,6 +978,33 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 	else
 		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
 
+	if (options->extra && *buffer) {
+		if (!starts_with(buffer, "\n")) {
+			/*
+			 * The verify_headers() check will allow
+			 * e.g. "[...]tagger <tagger>\nsome
+			 * garbage\n\nmessage" to pass, thinking "some
+			 * garbage" could be a custom
+			 * header. E.g. "mktag" doesn't want any
+			 * unknown headers.
+			 */
+			ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
+			if (ret)
+				goto done;
+		}
+		if (starts_with(buffer, "\n\n")) {
+			/*
+			 * Some callers such as "mktag" want to
+			 * disallow "[...]tagger
+			 * <tagger>\n\n\nmessage", only allowing a
+			 * single newline for separation.
+			 */
+			ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_BODY_NEWLINE, "invalid format - headers separated body by more than one newline");
+			if (ret)
+				goto done;
+		}
+	}
+
 done:
 	strbuf_release(&sb);
 	return ret;
diff --git a/fsck.h b/fsck.h
index 69cf715e79..110efc65fd 100644
--- a/fsck.h
+++ b/fsck.h
@@ -6,6 +6,7 @@
 #define FSCK_ERROR 1
 #define FSCK_WARN 2
 #define FSCK_IGNORE 3
+#define FSCK_EXTRA 4
 
 struct fsck_options;
 struct object;
@@ -40,6 +41,7 @@ struct fsck_options {
 	unsigned strict:1;
 	int *msg_type;
 	struct oidset skiplist;
+	unsigned extra:1;
 	kh_oid_map_t *object_names;
 };
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 08/12] mktag: use fsck instead of custom verify_tag()
  2020-11-23 21:34       ` Jeff King
                           ` (8 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 07/12] fsck: add new "extra" checks for "mktag" Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  8:17           ` Jeff King
  2020-11-26  1:28         ` [RFC/PATCH 09/12] mktag: remove now-unused verify_tag() code Ævar Arnfjörð Bjarmason
                           ` (3 subsequent siblings)
  13 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

TODO: This subtly breaks one check, see the last patch in this series.

Change the validation logic in "mktag" to use fsck's fsck_tag()
instead of its own custom parser. Curiously the logic for both dates
back to the same commit[1]. Let's unify them so we're not maintaining
two sets functions to verify that a tag is OK.

Moving to fsck_tag() required teaching it to optionally use some
validations that only the old mktag code could perform. That was done
in an earlier commit, the "extraHeaderEntry" and
"extraHeaderBodyNewline" tests being added here make use of that
logic.

There was other "mktag" validation logic that I think makes sense to
just remove. Namely:

 A. fsck only cares that the timezone matches [-+][0-9]{4}. The mktag
    code disallowed values larger than 1400.

    Yes there's currently no timezone with a greater offset[2], but
    since we allow any number of non-offical timezones (e.g. +1234)
    passing this through seems fine. Git also won't break in the
    future if e.g. French Polynesia decides it needs to outdo the Line
    Islands when it comes to timezone extravagance.

 B. fsck allows missing author names such as "tagger <email>", mktag
    wouldn't, but would allow e.g. "tagger <email>" (but not "tagger
    <email>"). Now we allow all of these.

 C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
    allows it.

We didn't only lose obscure validation logic, we also gained some:

 D. fsck disallows zero-padded dates, but mktag didn't care. So
    e.g. the timestamp "0000000000 +0000" produces an error now. A
    test in "t1006-cat-file.sh" relied on this, it's been changed to
    use "hash-object" (without fsck) instead.

1. ec4465adb38 (Add "tag" objects that can be used to sign other
   objects., 2005-04-25)

2. https://en.wikipedia.org/wiki/List_of_UTC_time_offsets

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c     | 45 +++++++++++++++++++++++++---
 t/t1006-cat-file.sh |  2 +-
 t/t3800-mktag.sh    | 72 +++++++++++++++++++++++++++------------------
 3 files changed, 86 insertions(+), 33 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index dc354828f7..a1ae80702d 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -2,6 +2,7 @@
 #include "tag.h"
 #include "replace-object.h"
 #include "object-store.h"
+#include "fsck.h"
 
 /*
  * A signature file has a very simple fixed format: four lines
@@ -47,6 +48,9 @@ static int verify_tag(char *buffer, unsigned long size)
 	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
 	size_t len;
 
+	/* verify_tag() will be removed in the next commit */
+	return 0;
+
 	if (size < 84)
 		return error("wanna fool me ? you obviously got the size wrong !");
 
@@ -153,10 +157,34 @@ static int verify_tag(char *buffer, unsigned long size)
 	return 0;
 }
 
+static int mktag_fsck_error_func(struct fsck_options *o,
+				 const struct object_id *oid,
+				 enum object_type object_type,
+				 int msg_type, const char *message)
+{
+	switch (msg_type) {
+	case FSCK_WARN:
+	case FSCK_ERROR:
+	case FSCK_EXTRA:
+		/*
+		 * We treat both warnings and errors as errors, things
+		 * like missing "tagger" lines are "only" warnings
+		 * under fsck, we've always considered them an error.
+		 */
+		fprintf_ln(stderr, "error: %s", message);
+		return 1;
+	default:
+		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
+		    msg_type);
+	}
+}
+
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
+	struct object obj;
 	struct strbuf buf = STRBUF_INIT;
 	struct object_id result;
+	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 
 	if (argc != 1)
 		usage("git mktag");
@@ -164,10 +192,19 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
 
-	/* Verify it for some basic sanity: it needs to start with
-	   "object <sha1>\ntype\ntagger " */
-	if (verify_tag(buf.buf, buf.len) < 0)
-		die("invalid tag signature file");
+	/* verify_tag() will be removed in the next commit */
+	verify_tag("", 0);
+
+	/*
+	 * Fake up an object for fsck_object()
+	 */
+	obj.parsed = 1;
+	obj.type = OBJ_TAG;
+
+	fsck_options.extra = 1;
+	fsck_options.error_func = mktag_fsck_error_func;
+	if (fsck_object(&obj, buf.buf, buf.len, &fsck_options))
+		die("tag on stdin did not pass our strict fsck check");
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
 		die("unable to write annotated tag object");
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 2f501d2dc9..5d2dc99b74 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -166,7 +166,7 @@ tag_content="$tag_header_without_timestamp 0000000000 +0000
 
 $tag_description"
 
-tag_sha1=$(echo_without_newline "$tag_content" | git mktag)
+tag_sha1=$(echo_without_newline "$tag_content" | git hash-object -t tag --stdin -w)
 tag_size=$(strlen "$tag_content")
 
 run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" 1
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 3801d3a285..bc57ee85c9 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -37,7 +37,7 @@ too short for a tag
 EOF
 
 check_verify_failure 'Tag object length check' \
-	'^error: .*size wrong.*$'
+	'^error: missingObject:'
 
 ############################################################
 #  2. object line label check
@@ -50,7 +50,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
+check_verify_failure '"object" line label check' '^error: missingObject:'
 
 ############################################################
 #  3. object line SHA check
@@ -64,7 +64,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
+check_verify_failure '"object" line check' '^error: badObjectSha1:'
 
 ############################################################
 #  4. type line label check
@@ -77,7 +77,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error: missingTypeEntry:'
 
 ############################################################
 #  5. type line eol check
@@ -85,7 +85,7 @@ check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
 echo "object $head" >tag.sig
 printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
 
-check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error: unterminatedHeader:'
 
 ############################################################
 #  6. tag line label check #1
@@ -99,7 +99,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure '"tag" line label check #1' \
-	'^error: char.*: no "tag " found$'
+	'^error: missingTagEntry:'
 
 ############################################################
 #  7. tag line label check #2
@@ -111,7 +111,7 @@ tag
 EOF
 
 check_verify_failure '"tag" line label check #2' \
-	'^error: char.*: no "tag " found$'
+	'^error: badType:'
 
 ############################################################
 #  8. type line type-name length check
@@ -123,7 +123,7 @@ tag mytag
 EOF
 
 check_verify_failure '"type" line type-name length check' \
-	'^error: char.*: type too long$'
+	'^error: badType:'
 
 ############################################################
 #  9. verify object (SHA1/type) check
@@ -159,7 +159,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (SHA1/type) check' \
-	'^error: char7: could not verify object.*$'
+	'^error: badType:'
 
 ############################################################
 # 10. verify tag-name check
@@ -173,7 +173,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error: char.*: could not verify tag name$'
+	'^error: badTagName:'
 
 ############################################################
 # 11. tagger line label check #1
@@ -187,7 +187,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error: char.*: could not find "tagger "$'
+	'^error: missingTaggerEntry:'
 
 ############################################################
 # 12. tagger line label check #2
@@ -202,10 +202,10 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error: char.*: could not find "tagger "$'
+	'^error: missingTaggerEntry:'
 
 ############################################################
-# 13. disallow missing tag author name
+# 13. allow missing tag author name like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -216,8 +216,9 @@ tagger  <> 0 +0000
 This is filler
 EOF
 
-check_verify_failure 'disallow missing tag author name' \
-	'^error: char.*: missing tagger name$'
+test_expect_success 'allow missing tag author name' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 14. disallow missing tag author name
@@ -232,7 +233,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error: char.*: malformed tagger field$'
+	'^error: badEmail:'
 
 ############################################################
 # 15. allow empty tag email
@@ -250,7 +251,7 @@ test_expect_success \
     'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
 
 ############################################################
-# 16. disallow spaces in tag email
+# 16. allow spaces in tag email like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -260,8 +261,9 @@ tagger T A Gger <tag ger@example.com> 0 +0000
 
 EOF
 
-check_verify_failure 'disallow spaces in tag email' \
-	'^error: char.*: malformed tagger field$'
+test_expect_success 'allow spaces in tag email like fsck' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 17. disallow missing tag timestamp
@@ -275,7 +277,7 @@ tagger T A Gger <tagger@example.com>__
 EOF
 
 check_verify_failure 'disallow missing tag timestamp' \
-	'^error: char.*: missing tag timestamp$'
+	'^error: badDate:'
 
 ############################################################
 # 18. detect invalid tag timestamp1
@@ -289,7 +291,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
 EOF
 
 check_verify_failure 'detect invalid tag timestamp1' \
-	'^error: char.*: missing tag timestamp$'
+	'^error: badDate:'
 
 ############################################################
 # 19. detect invalid tag timestamp2
@@ -303,7 +305,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
 EOF
 
 check_verify_failure 'detect invalid tag timestamp2' \
-	'^error: char.*: malformed tag timestamp$'
+	'^error: badDate:'
 
 ############################################################
 # 20. detect invalid tag timezone1
@@ -317,7 +319,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
 EOF
 
 check_verify_failure 'detect invalid tag timezone1' \
-	'^error: char.*: malformed tag timezone$'
+	'^error: badTimezone:'
 
 ############################################################
 # 21. detect invalid tag timezone2
@@ -331,10 +333,10 @@ tagger T A Gger <tagger@example.com> 1206478233 +  30
 EOF
 
 check_verify_failure 'detect invalid tag timezone2' \
-	'^error: char.*: malformed tag timezone$'
+	'^error: badTimezone:'
 
 ############################################################
-# 22. detect invalid tag timezone3
+# 22. allow invalid tag timezone3 (the maximum is -1200/+1400)
 
 cat >tag.sig <<EOF
 object $head
@@ -344,8 +346,9 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
 
 EOF
 
-check_verify_failure 'detect invalid tag timezone3' \
-	'^error: char.*: malformed tag timezone$'
+test_expect_success 'allow invalid tag timezone' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 23. detect invalid header entry
@@ -360,7 +363,20 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error: char.*: trailing garbage in tag header$'
+	'^error: extraHeaderEntry:'
+
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+
+
+this line should be one line up
+EOF
+
+check_verify_failure 'detect invalid header entry' \
+	'^error: extraHeaderBodyNewline:'
 
 ############################################################
 # 24. create valid tag
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 09/12] mktag: remove now-unused verify_tag() code
  2020-11-23 21:34       ` Jeff King
                           ` (9 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 08/12] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  8:20           ` Jeff King
  2020-11-26  1:28         ` [RFC/PATCH 10/12] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
                           ` (2 subsequent siblings)
  13 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The preceding commit removed the use of the verify_tag() function, but
didn't remove this code to keep the diff smaller. Let's remove this
unused code now.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 157 ------------------------------------------------
 1 file changed, 157 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index a1ae80702d..e9a0954dcb 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -1,162 +1,8 @@
 #include "builtin.h"
 #include "tag.h"
-#include "replace-object.h"
 #include "object-store.h"
 #include "fsck.h"
 
-/*
- * A signature file has a very simple fixed format: four lines
- * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
- * "tagger <committer>", followed by a blank line, a free-form tag
- * message and a signature block that git itself doesn't care about,
- * but that can be verified with gpg or similar.
- *
- * The first four lines are guaranteed to be at least 83 bytes:
- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
- * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
- * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
- * the shortest possible tagger-line.
- */
-
-/*
- * We refuse to tag something we can't verify. Just because.
- */
-static int verify_object(const struct object_id *oid, const char *expected_type)
-{
-	int ret = -1;
-	enum object_type type;
-	unsigned long size;
-	void *buffer = read_object_file(oid, &type, &size);
-	const struct object_id *repl = lookup_replace_object(the_repository, oid);
-
-	if (buffer) {
-		if (type == type_from_string(expected_type)) {
-			ret = check_object_signature(the_repository, repl,
-						     buffer, size,
-						     expected_type);
-		}
-		free(buffer);
-	}
-	return ret;
-}
-
-static int verify_tag(char *buffer, unsigned long size)
-{
-	int typelen;
-	char type[20];
-	struct object_id oid;
-	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
-	size_t len;
-
-	/* verify_tag() will be removed in the next commit */
-	return 0;
-
-	if (size < 84)
-		return error("wanna fool me ? you obviously got the size wrong !");
-
-	buffer[size] = 0;
-
-	/* Verify object line */
-	object = buffer;
-	if (memcmp(object, "object ", 7))
-		return error("char%d: does not start with \"object \"", 0);
-
-	if (parse_oid_hex(object + 7, &oid, &p))
-		return error("char%d: could not get SHA1 hash", 7);
-
-	/* Verify type line */
-	type_line = p + 1;
-	if (memcmp(type_line - 1, "\ntype ", 6))
-		return error("char%d: could not find \"\\ntype \"", 47);
-
-	/* Verify tag-line */
-	tag_line = strchr(type_line, '\n');
-	if (!tag_line)
-		return error("char%"PRIuMAX": could not find next \"\\n\"",
-				(uintmax_t) (type_line - buffer));
-	tag_line++;
-	if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
-		return error("char%"PRIuMAX": no \"tag \" found",
-				(uintmax_t) (tag_line - buffer));
-
-	/* Get the actual type */
-	typelen = tag_line - type_line - strlen("type \n");
-	if (typelen >= sizeof(type))
-		return error("char%"PRIuMAX": type too long",
-				(uintmax_t) (type_line+5 - buffer));
-
-	memcpy(type, type_line+5, typelen);
-	type[typelen] = 0;
-
-	/* Verify that the object matches */
-	if (verify_object(&oid, type))
-		return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));
-
-	/* Verify the tag-name: we don't allow control characters or spaces in it */
-	tag_line += 4;
-	for (;;) {
-		unsigned char c = *tag_line++;
-		if (c == '\n')
-			break;
-		if (c > ' ')
-			continue;
-		return error("char%"PRIuMAX": could not verify tag name",
-				(uintmax_t) (tag_line - buffer));
-	}
-
-	/* Verify the tagger line */
-	tagger_line = tag_line;
-
-	if (memcmp(tagger_line, "tagger ", 7))
-		return error("char%"PRIuMAX": could not find \"tagger \"",
-			(uintmax_t) (tagger_line - buffer));
-
-	/*
-	 * Check for correct form for name and email
-	 * i.e. " <" followed by "> " on _this_ line
-	 * No angle brackets within the name or email address fields.
-	 * No spaces within the email address field.
-	 */
-	tagger_line += 7;
-	if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
-		strpbrk(tagger_line, "<>\n") != lb+1 ||
-		strpbrk(lb+2, "><\n ") != rb)
-		return error("char%"PRIuMAX": malformed tagger field",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* Check for author name, at least one character, space is acceptable */
-	if (lb == tagger_line)
-		return error("char%"PRIuMAX": missing tagger name",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* timestamp, 1 or more digits followed by space */
-	tagger_line = rb + 2;
-	if (!(len = strspn(tagger_line, "0123456789")))
-		return error("char%"PRIuMAX": missing tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += len;
-	if (*tagger_line != ' ')
-		return error("char%"PRIuMAX": malformed tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line++;
-
-	/* timezone, 5 digits [+-]hhmm, max. 1400 */
-	if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
-	      strspn(tagger_line+1, "0123456789") == 4 &&
-	      tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
-		return error("char%"PRIuMAX": malformed tag timezone",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += 6;
-
-	/* Verify the blank line separating the header from the body */
-	if (*tagger_line != '\n')
-		return error("char%"PRIuMAX": trailing garbage in tag header",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* The actual stuff afterwards we don't care about.. */
-	return 0;
-}
-
 static int mktag_fsck_error_func(struct fsck_options *o,
 				 const struct object_id *oid,
 				 enum object_type object_type,
@@ -192,9 +38,6 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
 
-	/* verify_tag() will be removed in the next commit */
-	verify_tag("", 0);
-
 	/*
 	 * Fake up an object for fsck_object()
 	 */
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 10/12] mktag doc: update to explain why to use this
  2020-11-23 21:34       ` Jeff King
                           ` (10 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 09/12] mktag: remove now-unused verify_tag() code Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  1:28         ` [RFC/PATCH 11/12] mktag docs: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
  2020-11-26  1:28         ` [RFC/PATCH 12/12] mktag: bring back some of the verify_object() logic Ævar Arnfjörð Bjarmason
  13 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the mktag documentation to compare itself to the similar
"hash-object -t tag" command. Before this someone reading the
documentation wouldn't have much of an idea what the difference
was.

Let's make it clear that it's to do with slightly different fsck
validation logic, and cross-link the "mktag" and "hash-object"
documentation to aid discover-ability.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-hash-object.txt |  4 ++++
 Documentation/git-mktag.txt       | 29 +++++++++++++++++++++++++----
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index df9e2c58bd..c535661ced 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -58,6 +58,10 @@ OPTIONS
 	stress-testing Git itself or reproducing characteristics of corrupt or
 	bogus objects encountered in the wild.
 
+SEE ALSO
+--------
+linkgit:git-mktag[1]
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index fa6a756123..11ce8e4bb4 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -3,7 +3,7 @@ git-mktag(1)
 
 NAME
 ----
-git-mktag - Creates a tag object
+git-mktag - Creates a tag object with extra validation
 
 
 SYNOPSIS
@@ -13,10 +13,20 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Reads a tag contents on standard input and creates a tag object
-that can also be used to sign other objects.
 
-The output is the new tag's <object> identifier.
+Reads a tag contents on standard input and creates a tag object. The
+output is the new tag's <object> identifier.
+
+This command accepts a subset of what linkgit:git-hash-object[1] would
+accept with `-t tag --stdin`. I.e. both of these work:
+
+    git mktag <my-tag
+    git hash-object -t tag --stdin <my-tag
+
+The difference between the two is that mktag does the equivalent of a
+linkgit:git-fsck(1) check on its input, and furthermore disallows some
+thing linkgit:git-hash-object[1] would pass, e.g. extra headers in the
+object before the message.
 
 Tag Format
 ----------
@@ -34,6 +44,17 @@ exists, is separated by a blank line from the header.  The
 message part may contain a signature that Git itself doesn't
 care about, but that can be verified with gpg.
 
+HISTORY
+-------
+
+In versions of Git before v2.30.0 the "mktag" command's validation
+logic was subtly different than that of linkgit:git-fsck[1]. It is now
+a strict superset of linkgit:git-fsck[1]'s validation logic.
+
+SEE ALSO
+--------
+linkgit:git-hash-object[1],
+
 GIT
 ---
 Part of the linkgit:git[1] suite
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 11/12] mktag docs: say <hash> not <sha1>
  2020-11-23 21:34       ` Jeff King
                           ` (11 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 10/12] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  1:28         ` [RFC/PATCH 12/12] mktag: bring back some of the verify_object() logic Ævar Arnfjörð Bjarmason
  13 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the "mktag" documentation to refer to the input hash as just
"hash", not "sha1". This command has supported SHA-256 for a while
now.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 11ce8e4bb4..3ba15072df 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -33,7 +33,7 @@ Tag Format
 A tag signature file, to be fed to this command's standard input,
 has a very simple fixed format: four lines of
 
-  object <sha1>
+  object <hash>
   type <typename>
   tag <tagname>
   tagger <tagger>
-- 
2.29.2.222.g5d2a92d10f8


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

* [RFC/PATCH 12/12] mktag: bring back some of the verify_object() logic
  2020-11-23 21:34       ` Jeff King
                           ` (12 preceding siblings ...)
  2020-11-26  1:28         ` [RFC/PATCH 11/12] mktag docs: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
@ 2020-11-26  1:28         ` Ævar Arnfjörð Bjarmason
  2020-11-26  8:32           ` Jeff King
  13 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26  1:28 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

When working on this series I saw too late that I'd removed the mktag
check for validating the object the tag points to. The fsck_tag() code
doesn't do this because it's meant for the context of fsck, where
we're validating reachability anyway.

We'd need to either refactor fsck_tag() so that it can pass us back
its "tagged_oid" and the "type_from_string_gently()" value it throws
away to get rid of the re-parsing of stdin here, or just duplicate the
logic as I'm doing here.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c  | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 t/t3800-mktag.sh |  4 ++--
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index e9a0954dcb..f1f1cf04ff 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "tag.h"
+#include "replace-object.h"
 #include "object-store.h"
 #include "fsck.h"
 
@@ -25,6 +26,50 @@ static int mktag_fsck_error_func(struct fsck_options *o,
 	}
 }
 
+static int verify_object_in_tag(const char *stdin)
+{
+	struct object_id oid;
+	char *eol;
+	const char *p;
+	int expected_type_id;
+	const char *expected_type;
+	int ret = -1;
+	enum object_type type;
+	unsigned long size;
+	void *buffer;
+	const struct object_id *repl;
+
+	if (!skip_prefix(stdin, "object ", &stdin))
+		goto bug;
+	if (parse_oid_hex(stdin, &oid, &p) || *p != '\n')
+		goto bug;
+	stdin = p + 1;
+	if (!skip_prefix(stdin, "type ", &stdin))
+		goto bug;
+	eol = strchr(stdin, '\n');
+	expected_type_id = type_from_string_gently(stdin, eol - stdin, 1);
+	if (expected_type_id < 0)
+		goto bug;
+	expected_type = type_name(expected_type_id);
+
+	buffer = read_object_file(&oid, &type, &size);
+	repl = lookup_replace_object(the_repository, &oid);
+
+	if (buffer) {
+		if (type == type_from_string(expected_type)) {
+			ret = check_object_signature(the_repository, repl,
+						     buffer, size,
+						     expected_type);
+		}
+		free(buffer);
+	}
+	goto ok;
+bug:
+	BUG("fsck_object() should have ensured a sane tag format already!");
+ok:
+	return ret;
+}
+
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	struct object obj;
@@ -49,6 +94,9 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (fsck_object(&obj, buf.buf, buf.len, &fsck_options))
 		die("tag on stdin did not pass our strict fsck check");
 
+	if (verify_object_in_tag(buf.buf))
+		die("tag on stdin did not refer to a valid object");
+
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
 		die("unable to write annotated tag object");
 
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index bc57ee85c9..74cd2eb141 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -137,7 +137,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (SHA1/type) check' \
-	'^error: char7: could not verify object.*$'
+	'^fatal: tag on stdin did not refer to a valid object'
 
 cat >tag.sig <<EOF
 object $head
@@ -148,7 +148,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (SHA1/type) check' \
-	'^fatal: invalid object type'
+	'^error: badType:'
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: [RFC/PATCH 05/12] mktag tests: remove needless SHA-1 hardcoding
  2020-11-26  1:28         ` [RFC/PATCH 05/12] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
@ 2020-11-26  7:49           ` Jeff King
  0 siblings, 0 replies; 229+ messages in thread
From: Jeff King @ 2020-11-26  7:49 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Thu, Nov 26, 2020 at 02:28:47AM +0100, Ævar Arnfjörð Bjarmason wrote:

> But here we're testing for a SHA-length string which contains
> characters outside of the /[0-9a-f]/i set. Let's just do that with a
> ROT13 invocation.
> 
> We could get really unlucky and switch to a future hash function that
> just happens to produce all [0-9] output for this particular input,
> but that's very unlikely.

Maybe s/[0-9a-f]/z/ would be both simpler and more robust?

-Peff

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

* Re: [RFC/PATCH 07/12] fsck: add new "extra" checks for "mktag"
  2020-11-26  1:28         ` [RFC/PATCH 07/12] fsck: add new "extra" checks for "mktag" Ævar Arnfjörð Bjarmason
@ 2020-11-26  8:02           ` Jeff King
  2020-11-26 12:43             ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Jeff King @ 2020-11-26  8:02 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Thu, Nov 26, 2020 at 02:28:49AM +0100, Ævar Arnfjörð Bjarmason wrote:

> Add optional "extra" checks to fsck, these are needed to eventually
> replace the custom not-quite-fsck code in mktag.c.
> 
> The mktag checks differ from fsck_tag() in several ways, one of those
> is that fsck doesn't know how to refuse an object with custom headers,
> and isn't strict about header and body newline separation.
> 
> Teach it how to optionally report these. I thought the best way to do
> that given the current structure of the code was to add a new "extra"
> category in addition to error/warn/info.

Hmm, this new severity (and the extra options bit) feels a bit
backwards. We are already passing the information on what we find to the
report() callback. It seems like that is the place that should be
deciding what is important and what is not.

Unfortunately the defaults are somewhat backwards here. We'd have to
teach the fsck callbacks to ignore these harmless entries, rather than
teaching the mktag caller that they need to be respected.

So probably the extra bit in options to say "do these extra tag checks"
is the least-bad thing. But then why do we need to put them in their own
EXTRA section? The only caller that wants them would treat them as
errors.

I'm slightly on the fence on whether mktag really needs to enforce the
"unknown header" thing at all. Sure, we don't encourage them, but it's a
plumbing tool one could use to experiment with new headers. I guess the
downside is that a typo'd header would not be caught.

> Under --strict the "info"
> becomes a "warn" and "warn" becomes "error". Existing users of
> fsck's (and others, e.g. index-pack) --strict option rely on this.

Yeah, this is a weirdness I think we should eventually fix (along with
re-prioritizing some of the existing checks). I'm wary of doing anything
that further cements that somewhat broken world-view (keep in mind that
"index-pack --strict" is not "do fsck more strictly" but "do fsck at
all").

> I'm not changing fsck_commit() to validate commit objects like this
> either, we could do that, but unlike in the tag case that code
> wouldn't be used anywhere. If someone wants to write a "mkcommit" they
> which behaves like "mktag" they can borrow or refactor this logic for
> use in fsck_commit().

Seems reasonable.

-Peff

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

* Re: [RFC/PATCH 08/12] mktag: use fsck instead of custom verify_tag()
  2020-11-26  1:28         ` [RFC/PATCH 08/12] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
@ 2020-11-26  8:17           ` Jeff King
  2020-11-26 12:46             ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Jeff King @ 2020-11-26  8:17 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Thu, Nov 26, 2020 at 02:28:50AM +0100, Ævar Arnfjörð Bjarmason wrote:

> There was other "mktag" validation logic that I think makes sense to
> just remove. Namely:
> 
>  A. fsck only cares that the timezone matches [-+][0-9]{4}. The mktag
>     code disallowed values larger than 1400.
> 
>     Yes there's currently no timezone with a greater offset[2], but
>     since we allow any number of non-offical timezones (e.g. +1234)
>     passing this through seems fine. Git also won't break in the
>     future if e.g. French Polynesia decides it needs to outdo the Line
>     Islands when it comes to timezone extravagance.

Yeah, I think this is a good choice to loosen.

>  B. fsck allows missing author names such as "tagger <email>", mktag
>     wouldn't, but would allow e.g. "tagger <email>" (but not "tagger
>     <email>"). Now we allow all of these.

Likewise, though I am confused. Should the second "tagger <email>" in
that paragraph have something else in it?

>  C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
>     allows it.

Possibly something we'd want to tighten in fsck, but I think keeping
them in alignment is a good idea for now.

> We didn't only lose obscure validation logic, we also gained some:
> 
>  D. fsck disallows zero-padded dates, but mktag didn't care. So
>     e.g. the timestamp "0000000000 +0000" produces an error now. A
>     test in "t1006-cat-file.sh" relied on this, it's been changed to
>     use "hash-object" (without fsck) instead.

Seems reasonable.

> +	/* verify_tag() will be removed in the next commit */
> +	verify_tag("", 0);
> +
> +	/*
> +	 * Fake up an object for fsck_object()
> +	 */
> +	obj.parsed = 1;
> +	obj.type = OBJ_TAG;

I don't love this "fake object struct on the stack" thing. I can't think
of anything that would break outright, but it may be the only place
where that struct isn't coming from the usual pool, and representing the
common part of a larger object. Two definite gotchas, though:

  - if the type is OBJ_TAG, then it may get cast to a "struct tag" by
    other code, which could look past the end of the struct. I think
    that fsck_object() doesn't do this, but it could (and it definitely
    used to)

  - you don't initialize the other fields. We'll definitely pass
    &obj->oid in the fsck code, and even back to our report() callback,
    even though it's full of garbage. In practice this is OK because our
    custom report() won't look at them, but it seems awfully fragile.

I recently genericized the type-specific fsck_* functions so that they
just need an oid, and not an object struct. I think I didn't do
fsck_object() just because it didn't have any callers where it mattered.
So I think it would make sense here to either:

  - make fsck_tag() specifically available outside of fsck.c, so could
    call it directly

  - convert fsck_object() to take an oid rather than an object struct.
    It only uses the object itself to check for NULL-ness. Looking at
    the callers, they all have non-NULL objects already. So I think that
    check can't be triggered.

>  check_verify_failure 'Tag object length check' \
> -	'^error: .*size wrong.*$'
> +	'^error: missingObject:'

We may want to enhance the "error:" here to make it clear we're talking
about a format error in the tag input. Maybe:

  error: tag input does not pass fsck: missingObject: ...

or something.

-Peff

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

* Re: [RFC/PATCH 09/12] mktag: remove now-unused verify_tag() code
  2020-11-26  1:28         ` [RFC/PATCH 09/12] mktag: remove now-unused verify_tag() code Ævar Arnfjörð Bjarmason
@ 2020-11-26  8:20           ` Jeff King
  0 siblings, 0 replies; 229+ messages in thread
From: Jeff King @ 2020-11-26  8:20 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Thu, Nov 26, 2020 at 02:28:51AM +0100, Ævar Arnfjörð Bjarmason wrote:

> The preceding commit removed the use of the verify_tag() function, but
> didn't remove this code to keep the diff smaller. Let's remove this
> unused code now.

I do appreciate keeping diffs readable, but IMHO this is making things
more confusing, because you had to add a new dummy call to verify_tag()
in the previous commit in order to keep the compiler from complaining
about the unused static function (I'm actually surprised that it doesn't
complain about the immediate "return 0" in that function, which makes
the rest of the function unambiguously unreachable).

-Peff

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

* Re: [RFC/PATCH 12/12] mktag: bring back some of the verify_object() logic
  2020-11-26  1:28         ` [RFC/PATCH 12/12] mktag: bring back some of the verify_object() logic Ævar Arnfjörð Bjarmason
@ 2020-11-26  8:32           ` Jeff King
  0 siblings, 0 replies; 229+ messages in thread
From: Jeff King @ 2020-11-26  8:32 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Thu, Nov 26, 2020 at 02:28:54AM +0100, Ævar Arnfjörð Bjarmason wrote:

> When working on this series I saw too late that I'd removed the mktag
> check for validating the object the tag points to. The fsck_tag() code
> doesn't do this because it's meant for the context of fsck, where
> we're validating reachability anyway.
> 
> We'd need to either refactor fsck_tag() so that it can pass us back
> its "tagged_oid" and the "type_from_string_gently()" value it throws
> away to get rid of the re-parsing of stdin here, or just duplicate the
> logic as I'm doing here.

We have yet another tag parser (because of course there's more): the one
in parse_tag_buffer() that we use for reading tags. I think your new
function here could just be:

  enum object_type real_type;
  struct tag t; /* yuck! another fake object */

  memset(&t, 0, sizeof(t));
  if (parse_tag_buffer(r, &t, buf, len) < 0)
	die("unable to parse");

  real_type = oid_object_info(r, &t->tagged->oid, NULL);
  if (real_type < 0)
	die("tagged object does not exist");
  if (real_type != t->tagged->type)
	die("tagged object's type does not match tag type field");

I almost wonder if we could simply rely on parse_tag_buffer() instead of
fsck_tag(), but it is not nearly as picky about finding potential
problems (its goal is the opposite: to return something usable if it's
at all possible to do so).

The "yuck" above isn't great. We could use pretend_object_file() for
that, though it's a bit heavy-weight (it computes the actual oid!). And
also it's a weird one-off that we've talked about getting rid of.

-Peff

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

* Re: [RFC/PATCH 07/12] fsck: add new "extra" checks for "mktag"
  2020-11-26  8:02           ` Jeff King
@ 2020-11-26 12:43             ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 12:43 UTC (permalink / raw)
  To: Jeff King
  Cc: git, Junio C Hamano, brian m . carlson, Eric Sunshine,
	Johannes Schindelin


On Thu, Nov 26 2020, Jeff King wrote:

> On Thu, Nov 26, 2020 at 02:28:49AM +0100, Ævar Arnfjörð Bjarmason wrote:
>
>> Add optional "extra" checks to fsck, these are needed to eventually
>> replace the custom not-quite-fsck code in mktag.c.
>> 
>> The mktag checks differ from fsck_tag() in several ways, one of those
>> is that fsck doesn't know how to refuse an object with custom headers,
>> and isn't strict about header and body newline separation.
>> 
>> Teach it how to optionally report these. I thought the best way to do
>> that given the current structure of the code was to add a new "extra"
>> category in addition to error/warn/info.
>
> Hmm, this new severity (and the extra options bit) feels a bit
> backwards. We are already passing the information on what we find to the
> report() callback. It seems like that is the place that should be
> deciding what is important and what is not.
>
> Unfortunately the defaults are somewhat backwards here. We'd have to
> teach the fsck callbacks to ignore these harmless entries, rather than
> teaching the mktag caller that they need to be respected.
>
> So probably the extra bit in options to say "do these extra tag checks"
> is the least-bad thing. But then why do we need to put them in their own
> EXTRA section? The only caller that wants them would treat them as
> errors.

Right, it'll be hidden behind options->extra, so I could just make them
ERROR. I guess I was thinking it would be confusing to stick stuff in
the middle of ERROR that wasn't on by default, e.g. I've sometimes
skimmed that macro definition and saw "ah, bad parent sha1 is an error",
as in transfer.fsckObjects would reject it.

So I'm slightly on the fence about keeping it as it is, what do you
think?

> I'm slightly on the fence on whether mktag really needs to enforce the
> "unknown header" thing at all. Sure, we don't encourage them, but it's a
> plumbing tool one could use to experiment with new headers. I guess the
> downside is that a typo'd header would not be caught.

The problem is that since verify_headers() in fsck.c wants to allow it,
there's no way for it to distinguish a fat-fingerd "didn't separate the
body from the headers" v.s. actually wanting a custom header in some
cases.

>> Under --strict the "info"
>> becomes a "warn" and "warn" becomes "error". Existing users of
>> fsck's (and others, e.g. index-pack) --strict option rely on this.
>
> Yeah, this is a weirdness I think we should eventually fix (along with
> re-prioritizing some of the existing checks). I'm wary of doing anything
> that further cements that somewhat broken world-view (keep in mind that
> "index-pack --strict" is not "do fsck more strictly" but "do fsck at
> all").

*nod*, will note that.

>> I'm not changing fsck_commit() to validate commit objects like this
>> either, we could do that, but unlike in the tag case that code
>> wouldn't be used anywhere. If someone wants to write a "mkcommit" they
>> which behaves like "mktag" they can borrow or refactor this logic for
>> use in fsck_commit().
>
> Seems reasonable.
>
> -Peff


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

* Re: [RFC/PATCH 08/12] mktag: use fsck instead of custom verify_tag()
  2020-11-26  8:17           ` Jeff King
@ 2020-11-26 12:46             ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 12:46 UTC (permalink / raw)
  To: Jeff King
  Cc: git, Junio C Hamano, brian m . carlson, Eric Sunshine,
	Johannes Schindelin


On Thu, Nov 26 2020, Jeff King wrote:

> On Thu, Nov 26, 2020 at 02:28:50AM +0100, Ævar Arnfjörð Bjarmason wrote:
>
>> There was other "mktag" validation logic that I think makes sense to
>> just remove. Namely:
>> 
>>  A. fsck only cares that the timezone matches [-+][0-9]{4}. The mktag
>>     code disallowed values larger than 1400.
>> 
>>     Yes there's currently no timezone with a greater offset[2], but
>>     since we allow any number of non-offical timezones (e.g. +1234)
>>     passing this through seems fine. Git also won't break in the
>>     future if e.g. French Polynesia decides it needs to outdo the Line
>>     Islands when it comes to timezone extravagance.
>
> Yeah, I think this is a good choice to loosen.
>
>>  B. fsck allows missing author names such as "tagger <email>", mktag
>>     wouldn't, but would allow e.g. "tagger <email>" (but not "tagger
>>     <email>"). Now we allow all of these.
>
> Likewise, though I am confused. Should the second "tagger <email>" in
> that paragraph have something else in it?

There should be 1-2 and 3 spaces there, don't know why that didn't make
it. Will fix.

>>  C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
>>     allows it.
>
> Possibly something we'd want to tighten in fsck, but I think keeping
> them in alignment is a good idea for now.
>
>> We didn't only lose obscure validation logic, we also gained some:
>> 
>>  D. fsck disallows zero-padded dates, but mktag didn't care. So
>>     e.g. the timestamp "0000000000 +0000" produces an error now. A
>>     test in "t1006-cat-file.sh" relied on this, it's been changed to
>>     use "hash-object" (without fsck) instead.
>
> Seems reasonable.
>
>> +	/* verify_tag() will be removed in the next commit */
>> +	verify_tag("", 0);
>> +
>> +	/*
>> +	 * Fake up an object for fsck_object()
>> +	 */
>> +	obj.parsed = 1;
>> +	obj.type = OBJ_TAG;
>
> I don't love this "fake object struct on the stack" thing. I can't think
> of anything that would break outright, but it may be the only place
> where that struct isn't coming from the usual pool, and representing the
> common part of a larger object. Two definite gotchas, though:
>
>   - if the type is OBJ_TAG, then it may get cast to a "struct tag" by
>     other code, which could look past the end of the struct. I think
>     that fsck_object() doesn't do this, but it could (and it definitely
>     used to)
>
>   - you don't initialize the other fields. We'll definitely pass
>     &obj->oid in the fsck code, and even back to our report() callback,
>     even though it's full of garbage. In practice this is OK because our
>     custom report() won't look at them, but it seems awfully fragile.
>
> I recently genericized the type-specific fsck_* functions so that they
> just need an oid, and not an object struct. I think I didn't do
> fsck_object() just because it didn't have any callers where it mattered.
> So I think it would make sense here to either:
>
>   - make fsck_tag() specifically available outside of fsck.c, so could
>     call it directly
>
>   - convert fsck_object() to take an oid rather than an object struct.
>     It only uses the object itself to check for NULL-ness. Looking at
>     the callers, they all have non-NULL objects already. So I think that
>     check can't be triggered.
>
>>  check_verify_failure 'Tag object length check' \
>> -	'^error: .*size wrong.*$'
>> +	'^error: missingObject:'

When I started out hacking on this I just made fsck_tag() a non-static
function. The faking up obj only got added because I needed to call
fsck_object().

Between this and your comment to 12/12 I wonder if the least bad thing
isn't just to split up fsck_tag() into fsck_tag() and
fsck_tag_standalone(), so I can call the latter with a "populate the
object and type" argument, and fsck.c will just NULL those two
parameters since it doesn't care.

Gets rid of the obj faking, and gets rid of the custom parser in
mktag.c. It'll only need to do the object lookup at that point, and even
then since I've added everything else to fsck.c I might as well make
that another custom ERROR/EXTRA, i.e. have it learn to do the lookup
itself.

> We may want to enhance the "error:" here to make it clear we're talking
> about a format error in the tag input. Maybe:
>
>   error: tag input does not pass fsck: missingObject: ...
>
> or something.

*nod*

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

* [PATCH v2 00/10] make "mktag" use fsck_tag()
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-12-01 10:08             ` Ævar Arnfjörð Bjarmason
                               ` (11 more replies)
  2020-11-26 22:22           ` [PATCH v2 01/10] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
                             ` (9 subsequent siblings)
  10 siblings, 12 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Now a non-RFC. I went for the approach I suggested in
<87r1ognv4b.fsf@evledraar.gmail.com> of just having fsck_tag() able to
optionally tell us about its parsed tag/type, thus avoiding any need
for a custom parser in mktag.c. Hopefully I've addressed the rest of
the feedback, range-diff below.

Ævar Arnfjörð Bjarmason (10):
  mktag doc: say <hash> not <sha1>
  mktag: use default strbuf_read() hint
  mktag: reword write_object_file() error
  mktag: remove redundant braces in one-line body "if"
  mktag tests: don't needlessly use a subshell
  mktag tests: remove needless SHA-1 hardcoding
  mktag tests: improve verify_object() test coverage
  fsck: add new "extra" checks for "mktag"
  mktag: use fsck instead of custom verify_tag()
  mktag doc: update to explain why to use this

 Documentation/git-hash-object.txt |   4 +
 Documentation/git-mktag.txt       |  31 ++++-
 builtin/mktag.c                   | 202 ++++++++----------------------
 fsck.c                            |  47 ++++++-
 fsck.h                            |  11 ++
 t/t1006-cat-file.sh               |   2 +-
 t/t3800-mktag.sh                  | 117 ++++++++++++-----
 7 files changed, 222 insertions(+), 192 deletions(-)

Range-diff:
11:  a7a6524b2a !  1:  f46abb37df mktag docs: say <hash> not <sha1>
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    mktag docs: say <hash> not <sha1>
    +    mktag doc: say <hash> not <sha1>
     
         Change the "mktag" documentation to refer to the input hash as just
         "hash", not "sha1". This command has supported SHA-256 for a while
 1:  f6d9482c5b =  2:  1b4d9a5330 mktag: use default strbuf_read() hint
 2:  49be8dbdd3 =  3:  83f4af6013 mktag: reword write_object_file() error
 3:  868d424e65 =  4:  bca1484ed9 mktag: remove redundant braces in one-line body "if"
 4:  e57969ce5d =  5:  ac7c4097c9 mktag tests: don't needlessly use a subshell
 5:  8cf5d95b1e !  6:  5e076659e4 mktag tests: remove needless SHA-1 hardcoding
    @@ Commit message
     
         Some of these tests were failing for the wrong reasons. The first one
         being modified here would fail because the line starts with "xxxxxx"
    -    instead of "object", the rest of the line doesn't matter. Let's just
    -    put a valid hash on the rest of the line anyway to narrow the test
    -    down for just the s/object/xxxxxx/ case.
    +    instead of "object", the rest of the line doesn't matter.
    +
    +    Let's just put a valid hash on the rest of the line anyway to narrow
    +    the test down for just the s/object/xxxxxx/ case.
     
         The second one being modified here would fail under
         GIT_TEST_DEFAULT_HASH=sha256 because <some sha-1 length garbage> is an
    @@ Commit message
         garbage> when under SHA-256.
     
         This doesn't really matter since we should be able to trust other
    -    parts of the code to validate things in the 0-9a-f range, but let's do
    -    it for good measure.
    +    parts of the code to validate things in the 0-9a-f range, but let's
    +    keep it for good measure.
     
         There's a later test which tests an invalid SHA which looks like a
         valid one, to stress the "We refuse to tag something we can't
         verify[...]" logic in mktag.c.
     
         But here we're testing for a SHA-length string which contains
    -    characters outside of the /[0-9a-f]/i set. Let's just do that with a
    -    ROT13 invocation.
    -
    -    We could get really unlucky and switch to a future hash function that
    -    just happens to produce all [0-9] output for this particular input,
    -    but that's very unlikely.
    +    characters outside of the /[0-9a-f]/i set.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ t/t3800-mktag.sh: EOF
     -#  3. object line SHA1 check
     +#  3. object line SHA check
      
    -+invalid_sha=$(echo $head | tr A-Za-z N-ZA-Mn-za-m)
      cat >tag.sig <<EOF
     -object zz9e9b33986b1c2670fff52c5067603117b3e895
    -+object $invalid_sha
    ++object $(echo $head | tr 0-9a-f z)
      type tag
      tag mytag
      tagger . <> 0 +0000
 6:  2899f9cda5 <  -:  ---------- mktag tests: improve verify_object() test coverage
 -:  ---------- >  7:  a048c3e640 mktag tests: improve verify_object() test coverage
 7:  70d1d877aa =  8:  dab44d3235 fsck: add new "extra" checks for "mktag"
 8:  d37d684135 !  9:  8ff853caee mktag: use fsck instead of custom verify_tag()
    @@ Metadata
      ## Commit message ##
         mktag: use fsck instead of custom verify_tag()
     
    -    TODO: This subtly breaks one check, see the last patch in this series.
    -
         Change the validation logic in "mktag" to use fsck's fsck_tag()
         instead of its own custom parser. Curiously the logic for both dates
         back to the same commit[1]. Let's unify them so we're not maintaining
    @@ Commit message
             Islands when it comes to timezone extravagance.
     
          B. fsck allows missing author names such as "tagger <email>", mktag
    -        wouldn't, but would allow e.g. "tagger <email>" (but not "tagger
    -        <email>"). Now we allow all of these.
    +        wouldn't, but would allow e.g. "tagger [2 spaces] <email>" (but
    +        not "tagger [1 space] <email>"). Now we allow all of these.
     
          C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
             allows it.
    @@ builtin/mktag.c
      #include "object-store.h"
     +#include "fsck.h"
      
    - /*
    -  * A signature file has a very simple fixed format: four lines
    -@@ builtin/mktag.c: static int verify_tag(char *buffer, unsigned long size)
    - 	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
    - 	size_t len;
    - 
    -+	/* verify_tag() will be removed in the next commit */
    -+	return 0;
    -+
    - 	if (size < 84)
    - 		return error("wanna fool me ? you obviously got the size wrong !");
    - 
    -@@ builtin/mktag.c: static int verify_tag(char *buffer, unsigned long size)
    - 	return 0;
    - }
    - 
    +-/*
    +- * A signature file has a very simple fixed format: four lines
    +- * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
    +- * "tagger <committer>", followed by a blank line, a free-form tag
    +- * message and a signature block that git itself doesn't care about,
    +- * but that can be verified with gpg or similar.
    +- *
    +- * The first four lines are guaranteed to be at least 83 bytes:
    +- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
    +- * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
    +- * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
    +- * the shortest possible tagger-line.
    +- */
    +-
    +-/*
    +- * We refuse to tag something we can't verify. Just because.
    +- */
    +-static int verify_object(const struct object_id *oid, const char *expected_type)
     +static int mktag_fsck_error_func(struct fsck_options *o,
     +				 const struct object_id *oid,
     +				 enum object_type object_type,
     +				 int msg_type, const char *message)
    -+{
    + {
    +-	int ret = -1;
    +-	enum object_type type;
    +-	unsigned long size;
    +-	void *buffer = read_object_file(oid, &type, &size);
    +-	const struct object_id *repl = lookup_replace_object(the_repository, oid);
    +-
    +-	if (buffer) {
    +-		if (type == type_from_string(expected_type)) {
    +-			ret = check_object_signature(the_repository, repl,
    +-						     buffer, size,
    +-						     expected_type);
    +-		}
    +-		free(buffer);
     +	switch (msg_type) {
     +	case FSCK_WARN:
     +	case FSCK_ERROR:
    @@ builtin/mktag.c: static int verify_tag(char *buffer, unsigned long size)
     +		 * like missing "tagger" lines are "only" warnings
     +		 * under fsck, we've always considered them an error.
     +		 */
    -+		fprintf_ln(stderr, "error: %s", message);
    ++		fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message);
     +		return 1;
     +	default:
     +		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
     +		    msg_type);
    -+	}
    -+}
    + 	}
    +-	return ret;
    + }
    + 
    +-static int verify_tag(char *buffer, unsigned long size)
    ++static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
    + {
    +-	int typelen;
    +-	char type[20];
    +-	struct object_id oid;
    +-	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
    +-	size_t len;
    +-
    +-	if (size < 84)
    +-		return error("wanna fool me ? you obviously got the size wrong !");
    +-
    +-	buffer[size] = 0;
    +-
    +-	/* Verify object line */
    +-	object = buffer;
    +-	if (memcmp(object, "object ", 7))
    +-		return error("char%d: does not start with \"object \"", 0);
    +-
    +-	if (parse_oid_hex(object + 7, &oid, &p))
    +-		return error("char%d: could not get SHA1 hash", 7);
    +-
    +-	/* Verify type line */
    +-	type_line = p + 1;
    +-	if (memcmp(type_line - 1, "\ntype ", 6))
    +-		return error("char%d: could not find \"\\ntype \"", 47);
    +-
    +-	/* Verify tag-line */
    +-	tag_line = strchr(type_line, '\n');
    +-	if (!tag_line)
    +-		return error("char%"PRIuMAX": could not find next \"\\n\"",
    +-				(uintmax_t) (type_line - buffer));
    +-	tag_line++;
    +-	if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
    +-		return error("char%"PRIuMAX": no \"tag \" found",
    +-				(uintmax_t) (tag_line - buffer));
    +-
    +-	/* Get the actual type */
    +-	typelen = tag_line - type_line - strlen("type \n");
    +-	if (typelen >= sizeof(type))
    +-		return error("char%"PRIuMAX": type too long",
    +-				(uintmax_t) (type_line+5 - buffer));
    +-
    +-	memcpy(type, type_line+5, typelen);
    +-	type[typelen] = 0;
    +-
    +-	/* Verify that the object matches */
    +-	if (verify_object(&oid, type))
    +-		return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));
    +-
    +-	/* Verify the tag-name: we don't allow control characters or spaces in it */
    +-	tag_line += 4;
    +-	for (;;) {
    +-		unsigned char c = *tag_line++;
    +-		if (c == '\n')
    +-			break;
    +-		if (c > ' ')
    +-			continue;
    +-		return error("char%"PRIuMAX": could not verify tag name",
    +-				(uintmax_t) (tag_line - buffer));
    +-	}
    +-
    +-	/* Verify the tagger line */
    +-	tagger_line = tag_line;
    +-
    +-	if (memcmp(tagger_line, "tagger ", 7))
    +-		return error("char%"PRIuMAX": could not find \"tagger \"",
    +-			(uintmax_t) (tagger_line - buffer));
    +-
    +-	/*
    +-	 * Check for correct form for name and email
    +-	 * i.e. " <" followed by "> " on _this_ line
    +-	 * No angle brackets within the name or email address fields.
    +-	 * No spaces within the email address field.
    +-	 */
    +-	tagger_line += 7;
    +-	if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
    +-		strpbrk(tagger_line, "<>\n") != lb+1 ||
    +-		strpbrk(lb+2, "><\n ") != rb)
    +-		return error("char%"PRIuMAX": malformed tagger field",
    +-			(uintmax_t) (tagger_line - buffer));
    +-
    +-	/* Check for author name, at least one character, space is acceptable */
    +-	if (lb == tagger_line)
    +-		return error("char%"PRIuMAX": missing tagger name",
    +-			(uintmax_t) (tagger_line - buffer));
    +-
    +-	/* timestamp, 1 or more digits followed by space */
    +-	tagger_line = rb + 2;
    +-	if (!(len = strspn(tagger_line, "0123456789")))
    +-		return error("char%"PRIuMAX": missing tag timestamp",
    +-			(uintmax_t) (tagger_line - buffer));
    +-	tagger_line += len;
    +-	if (*tagger_line != ' ')
    +-		return error("char%"PRIuMAX": malformed tag timestamp",
    +-			(uintmax_t) (tagger_line - buffer));
    +-	tagger_line++;
    +-
    +-	/* timezone, 5 digits [+-]hhmm, max. 1400 */
    +-	if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
    +-	      strspn(tagger_line+1, "0123456789") == 4 &&
    +-	      tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
    +-		return error("char%"PRIuMAX": malformed tag timezone",
    +-			(uintmax_t) (tagger_line - buffer));
    +-	tagger_line += 6;
    +-
    +-	/* Verify the blank line separating the header from the body */
    +-	if (*tagger_line != '\n')
    +-		return error("char%"PRIuMAX": trailing garbage in tag header",
    +-			(uintmax_t) (tagger_line - buffer));
    ++	int ret;
    ++	enum object_type type;
    ++	unsigned long size;
    ++	void *buffer;
    ++	const struct object_id *repl;
    ++
    ++	buffer = read_object_file(tagged_oid, &type, &size);
    ++	if (!buffer)
    ++		die("could not read tagged object '%s'\n",
    ++		    oid_to_hex(tagged_oid));
    ++	if (type != *tagged_type)
    ++		die("object '%s' tagged as '%s', but is a '%s' type\n",
    ++		    oid_to_hex(tagged_oid),
    ++		    type_name(*tagged_type), type_name(type));
     +
    ++	repl = lookup_replace_object(the_repository, tagged_oid);
    ++	ret = check_object_signature(the_repository, repl,
    ++				     buffer, size, type_name(*tagged_type));
    ++	free(buffer);
    + 
    +-	/* The actual stuff afterwards we don't care about.. */
    +-	return 0;
    ++	return ret;
    + }
    + 
      int cmd_mktag(int argc, const char **argv, const char *prefix)
      {
    -+	struct object obj;
      	struct strbuf buf = STRBUF_INIT;
    - 	struct object_id result;
     +	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
    ++	struct object_id tagged_oid;
    ++	int tagged_type;
    + 	struct object_id result;
      
      	if (argc != 1)
    - 		usage("git mktag");
     @@ builtin/mktag.c: int cmd_mktag(int argc, const char **argv, const char *prefix)
      	if (strbuf_read(&buf, 0, 0) < 0)
      		die_errno("could not read from stdin");
    @@ builtin/mktag.c: int cmd_mktag(int argc, const char **argv, const char *prefix)
     -	   "object <sha1>\ntype\ntagger " */
     -	if (verify_tag(buf.buf, buf.len) < 0)
     -		die("invalid tag signature file");
    -+	/* verify_tag() will be removed in the next commit */
    -+	verify_tag("", 0);
    -+
    -+	/*
    -+	 * Fake up an object for fsck_object()
    -+	 */
    -+	obj.parsed = 1;
    -+	obj.type = OBJ_TAG;
    -+
     +	fsck_options.extra = 1;
     +	fsck_options.error_func = mktag_fsck_error_func;
    -+	if (fsck_object(&obj, buf.buf, buf.len, &fsck_options))
    ++	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
    ++				&tagged_oid, &tagged_type))
     +		die("tag on stdin did not pass our strict fsck check");
    ++
    ++	if (verify_object_in_tag(&tagged_oid, &tagged_type))
    ++		die("tag on stdin did not refer to a valid object");
      
      	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
      		die("unable to write annotated tag object");
     
    + ## fsck.c ##
    +@@ fsck.c: static int fsck_tag(const struct object_id *oid, const char *buffer,
    + 		    unsigned long size, struct fsck_options *options)
    + {
    + 	struct object_id tagged_oid;
    ++	int tagged_type;
    ++	return fsck_tag_standalone(oid, buffer, size, options, &tagged_oid,
    ++				   &tagged_type);
    ++}
    ++
    ++int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
    ++			unsigned long size, struct fsck_options *options,
    ++			struct object_id *tagged_oid,
    ++			int *tagged_type)
    ++{
    + 	int ret = 0;
    + 	char *eol;
    + 	struct strbuf sb = STRBUF_INIT;
    +@@ fsck.c: static int fsck_tag(const struct object_id *oid, const char *buffer,
    + 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
    + 		goto done;
    + 	}
    +-	if (parse_oid_hex(buffer, &tagged_oid, &p) || *p != '\n') {
    ++	if (parse_oid_hex(buffer, tagged_oid, &p) || *p != '\n') {
    + 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
    + 		if (ret)
    + 			goto done;
    +@@ fsck.c: static int fsck_tag(const struct object_id *oid, const char *buffer,
    + 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
    + 		goto done;
    + 	}
    +-	if (type_from_string_gently(buffer, eol - buffer, 1) < 0)
    ++	*tagged_type = type_from_string_gently(buffer, eol - buffer, 1);
    ++	if (*tagged_type < 0)
    + 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
    + 	if (ret)
    + 		goto done;
    +
    + ## fsck.h ##
    +@@ fsck.h: int fsck_walk(struct object *obj, void *data, struct fsck_options *options);
    + int fsck_object(struct object *obj, void *data, unsigned long size,
    + 	struct fsck_options *options);
    + 
    ++/*
    ++ * fsck a tag, and pass info about it back to the caller. This is
    ++ * exposed fsck_object() internals for git-mktag(1).
    ++ */
    ++int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
    ++			unsigned long size, struct fsck_options *options,
    ++			struct object_id *tagged_oid,
    ++			int *tag_type);
    ++
    + /*
    +  * Some fsck checks are context-dependent, and may end up queued; run this
    +  * after completing all fsck_object() calls in order to resolve any remaining
    +
      ## t/t1006-cat-file.sh ##
     @@ t/t1006-cat-file.sh: tag_content="$tag_header_without_timestamp 0000000000 +0000
      
    @@ t/t3800-mktag.sh: too short for a tag
      
      check_verify_failure 'Tag object length check' \
     -	'^error: .*size wrong.*$'
    -+	'^error: missingObject:'
    ++	'^error:.* missingObject:'
      
      ############################################################
      #  2. object line label check
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
     -check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
    -+check_verify_failure '"object" line label check' '^error: missingObject:'
    ++check_verify_failure '"object" line label check' '^error:.* missingObject:'
      
      ############################################################
      #  3. object line SHA check
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
     -check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
    -+check_verify_failure '"object" line check' '^error: badObjectSha1:'
    ++check_verify_failure '"object" line check' '^error:.* badObjectSha1:'
      
      ############################################################
      #  4. type line label check
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
     -check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
    -+check_verify_failure '"type" line label check' '^error: missingTypeEntry:'
    ++check_verify_failure '"type" line label check' '^error:.* missingTypeEntry:'
      
      ############################################################
      #  5. type line eol check
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line label check' '^error: char.*
      printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
      
     -check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
    -+check_verify_failure '"type" line eol check' '^error: unterminatedHeader:'
    ++check_verify_failure '"type" line eol check' '^error:.* unterminatedHeader:'
      
      ############################################################
      #  6. tag line label check #1
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      
      check_verify_failure '"tag" line label check #1' \
     -	'^error: char.*: no "tag " found$'
    -+	'^error: missingTagEntry:'
    ++	'^error:.* missingTagEntry:'
      
      ############################################################
      #  7. tag line label check #2
    @@ t/t3800-mktag.sh: tag
      
      check_verify_failure '"tag" line label check #2' \
     -	'^error: char.*: no "tag " found$'
    -+	'^error: badType:'
    ++	'^error:.* badType:'
      
      ############################################################
      #  8. type line type-name length check
    @@ t/t3800-mktag.sh: tag mytag
      
      check_verify_failure '"type" line type-name length check' \
     -	'^error: char.*: type too long$'
    -+	'^error: badType:'
    ++	'^error:.* badType:'
      
      ############################################################
    - #  9. verify object (SHA1/type) check
    + #  9. verify object (SHA/type) check
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
    - check_verify_failure 'verify object (SHA1/type) check' \
    + check_verify_failure 'verify object (SHA/type) check -- correct type, nonexisting object' \
     -	'^error: char7: could not verify object.*$'
    -+	'^error: badType:'
    ++	'^fatal: could not read tagged object'
    + 
    + cat >tag.sig <<EOF
    + object $head
    +@@ t/t3800-mktag.sh: tagger . <> 0 +0000
    + EOF
    + 
    + check_verify_failure 'verify object (SHA/type) check -- made-up type, nonexisting object' \
    +-	'^fatal: invalid object type'
    ++	'^error:.* badType:'
    + 
    + cat >tag.sig <<EOF
    + object $(test_oid deadbeef)
    +@@ t/t3800-mktag.sh: tagger . <> 0 +0000
    + EOF
    + 
    + check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
    +-	'^error: char7: could not verify object.*$'
    ++	'^error:.* badType:'
    + 
    + cat >tag.sig <<EOF
    + object $head
    +@@ t/t3800-mktag.sh: tagger . <> 0 +0000
    + EOF
    + 
    + check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
    +-	'^error: char7: could not verify object'
    ++	'^fatal: object.*tagged as.*tree.*but is.*commit'
      
      ############################################################
      # 10. verify tag-name check
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      
      check_verify_failure 'verify tag-name check' \
     -	'^error: char.*: could not verify tag name$'
    -+	'^error: badTagName:'
    ++	'^error:.* badTagName:'
      
      ############################################################
      # 11. tagger line label check #1
    @@ t/t3800-mktag.sh: This is filler
      
      check_verify_failure '"tagger" line label check #1' \
     -	'^error: char.*: could not find "tagger "$'
    -+	'^error: missingTaggerEntry:'
    ++	'^error:.* missingTaggerEntry:'
      
      ############################################################
      # 12. tagger line label check #2
    @@ t/t3800-mktag.sh: This is filler
      
      check_verify_failure '"tagger" line label check #2' \
     -	'^error: char.*: could not find "tagger "$'
    -+	'^error: missingTaggerEntry:'
    ++	'^error:.* missingTaggerEntry:'
      
      ############################################################
     -# 13. disallow missing tag author name
    @@ t/t3800-mktag.sh: tagger T A Gger <
      
      check_verify_failure 'disallow malformed tagger' \
     -	'^error: char.*: malformed tagger field$'
    -+	'^error: badEmail:'
    ++	'^error:.* badEmail:'
      
      ############################################################
      # 15. allow empty tag email
    @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com>__
      
      check_verify_failure 'disallow missing tag timestamp' \
     -	'^error: char.*: missing tag timestamp$'
    -+	'^error: badDate:'
    ++	'^error:.* badDate:'
      
      ############################################################
      # 18. detect invalid tag timestamp1
    @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
      
      check_verify_failure 'detect invalid tag timestamp1' \
     -	'^error: char.*: missing tag timestamp$'
    -+	'^error: badDate:'
    ++	'^error:.* badDate:'
      
      ############################################################
      # 19. detect invalid tag timestamp2
    @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
      
      check_verify_failure 'detect invalid tag timestamp2' \
     -	'^error: char.*: malformed tag timestamp$'
    -+	'^error: badDate:'
    ++	'^error:.* badDate:'
      
      ############################################################
      # 20. detect invalid tag timezone1
    @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 GMT
      
      check_verify_failure 'detect invalid tag timezone1' \
     -	'^error: char.*: malformed tag timezone$'
    -+	'^error: badTimezone:'
    ++	'^error:.* badTimezone:'
      
      ############################################################
      # 21. detect invalid tag timezone2
    @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 +  30
      
      check_verify_failure 'detect invalid tag timezone2' \
     -	'^error: char.*: malformed tag timezone$'
    -+	'^error: badTimezone:'
    ++	'^error:.* badTimezone:'
      
      ############################################################
     -# 22. detect invalid tag timezone3
    @@ t/t3800-mktag.sh: this line should not be here
      
      check_verify_failure 'detect invalid header entry' \
     -	'^error: char.*: trailing garbage in tag header$'
    -+	'^error: extraHeaderEntry:'
    ++	'^error:.* extraHeaderEntry:'
     +
     +cat >tag.sig <<EOF
     +object $head
    @@ t/t3800-mktag.sh: this line should not be here
     +EOF
     +
     +check_verify_failure 'detect invalid header entry' \
    -+	'^error: extraHeaderBodyNewline:'
    ++	'^error:.* extraHeaderBodyNewline:'
      
      ############################################################
      # 24. create valid tag
 9:  403820698b <  -:  ---------- mktag: remove now-unused verify_tag() code
10:  78a4877450 = 10:  e38feefd3f mktag doc: update to explain why to use this
12:  0e840246a8 <  -:  ---------- mktag: bring back some of the verify_object() logic
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 01/10] mktag doc: say <hash> not <sha1>
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-12-01 20:17             ` Junio C Hamano
  2020-11-26 22:22           ` [PATCH v2 02/10] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
                             ` (8 subsequent siblings)
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the "mktag" documentation to refer to the input hash as just
"hash", not "sha1". This command has supported SHA-256 for a while
now.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index fa6a756123..a158428eb9 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -23,7 +23,7 @@ Tag Format
 A tag signature file, to be fed to this command's standard input,
 has a very simple fixed format: four lines of
 
-  object <sha1>
+  object <hash>
   type <typename>
   tag <tagname>
   tagger <tagger>
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 02/10] mktag: use default strbuf_read() hint
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
  2020-11-26 22:22           ` [PATCH v2 01/10] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-12-01 20:19             ` Junio C Hamano
  2020-11-26 22:22           ` [PATCH v2 03/10] mktag: reword write_object_file() error Ævar Arnfjörð Bjarmason
                             ` (7 subsequent siblings)
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the hardcoded hint of 2^12 to 0. The default strbuf hint is
perfectly fine here, and the only reason we were hardcoding it is
because it survived migration from a pre-strbuf fixed-sized buffer.

See fd17f5b5f77 (Replace all read_fd use with strbuf_read, and get rid
of it., 2007-09-10) for that migration.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4982d3a93e..ff7ac8e0e5 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,7 +161,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 4096) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0) {
 		die_errno("could not read from stdin");
 	}
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 03/10] mktag: reword write_object_file() error
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                             ` (2 preceding siblings ...)
  2020-11-26 22:22           ` [PATCH v2 02/10] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-12-01 20:20             ` Junio C Hamano
  2020-11-26 22:22           ` [PATCH v2 04/10] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
                             ` (6 subsequent siblings)
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the error message emitted when write_object_file() fails to
make more sense. At this point we're not writing a "tag file" (which
as an aside we never do, we just write to stdout). We are writing an
annotated tag object, let's say that instead.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index ff7ac8e0e5..603b55aca0 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -171,7 +171,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 		die("invalid tag signature file");
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
-		die("unable to write tag file");
+		die("unable to write annotated tag object");
 
 	strbuf_release(&buf);
 	printf("%s\n", oid_to_hex(&result));
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 04/10] mktag: remove redundant braces in one-line body "if"
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                             ` (3 preceding siblings ...)
  2020-11-26 22:22           ` [PATCH v2 03/10] mktag: reword write_object_file() error Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-11-26 22:22           ` [PATCH v2 05/10] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
                             ` (5 subsequent siblings)
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

This minor stylistic churn is usually something we'd avoid, but if we
don't do this then the file after changes in subsequent commits will
only have this minor style inconsistency, so let's change this while
we're at it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 603b55aca0..dc354828f7 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,9 +161,8 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 0) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
-	}
 
 	/* Verify it for some basic sanity: it needs to start with
 	   "object <sha1>\ntype\ntagger " */
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 05/10] mktag tests: don't needlessly use a subshell
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                             ` (4 preceding siblings ...)
  2020-11-26 22:22           ` [PATCH v2 04/10] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-11-26 22:22           ` [PATCH v2 06/10] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
                             ` (4 subsequent siblings)
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The use of a subshell dates back to e9b20943b77 (t/t3800: do not use a
temporary file to hold expected result., 2008-01-04). It's not needed
anymore, if it ever was.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index d696aa4e52..0e411e3c45 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -14,7 +14,7 @@ test_description='git mktag: tag object verify test'
 check_verify_failure () {
 	expect="$2"
 	test_expect_success "$1" '
-		( test_must_fail git mktag <tag.sig 2>message ) &&
+		test_must_fail git mktag <tag.sig 2>message &&
 		grep "$expect" message
 	'
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 06/10] mktag tests: remove needless SHA-1 hardcoding
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                             ` (5 preceding siblings ...)
  2020-11-26 22:22           ` [PATCH v2 05/10] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-12-01 20:24             ` Junio C Hamano
  2020-11-26 22:22           ` [PATCH v2 07/10] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
                             ` (3 subsequent siblings)
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the tests amended in acb49d1cc8b (t3800: make hash-size
independent, 2019-08-18) even more to make them independent of either
SHA-1 or SHA-256.

Some of these tests were failing for the wrong reasons. The first one
being modified here would fail because the line starts with "xxxxxx"
instead of "object", the rest of the line doesn't matter.

Let's just put a valid hash on the rest of the line anyway to narrow
the test down for just the s/object/xxxxxx/ case.

The second one being modified here would fail under
GIT_TEST_DEFAULT_HASH=sha256 because <some sha-1 length garbage> is an
invalid SHA-256, but we should really be testing <some sha-256 length
garbage> when under SHA-256.

This doesn't really matter since we should be able to trust other
parts of the code to validate things in the 0-9a-f range, but let's
keep it for good measure.

There's a later test which tests an invalid SHA which looks like a
valid one, to stress the "We refuse to tag something we can't
verify[...]" logic in mktag.c.

But here we're testing for a SHA-length string which contains
characters outside of the /[0-9a-f]/i set.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0e411e3c45..e9d7799537 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -43,7 +43,7 @@ check_verify_failure 'Tag object length check' \
 #  2. object line label check
 
 cat >tag.sig <<EOF
-xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
+xxxxxx $head
 type tag
 tag mytag
 tagger . <> 0 +0000
@@ -53,10 +53,10 @@ EOF
 check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
 
 ############################################################
-#  3. object line SHA1 check
+#  3. object line SHA check
 
 cat >tag.sig <<EOF
-object zz9e9b33986b1c2670fff52c5067603117b3e895
+object $(echo $head | tr 0-9a-f z)
 type tag
 tag mytag
 tagger . <> 0 +0000
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 07/10] mktag tests: improve verify_object() test coverage
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                             ` (6 preceding siblings ...)
  2020-11-26 22:22           ` [PATCH v2 06/10] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-11-26 22:22           ` [PATCH v2 08/10] fsck: add new "extra" checks for "mktag" Ævar Arnfjörð Bjarmason
                             ` (2 subsequent siblings)
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The verify_object() function in "mktag.c" is tasked with ensuring that
our tag refers to a valid object.

The existing test for this might fail because it was also testing that
"type taggg" didn't refer to a valid object type (it should be "type
tag"), or because we referred to a valid object but got the type
wrong.

Let's split these tests up, so we're testing all combinations of a
non-existing object and in invalid/wrong "type" lines.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index e9d7799537..a6a67b6f27 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -125,19 +125,52 @@ check_verify_failure '"type" line type-name length check' \
 	'^error: char.*: type too long$'
 
 ############################################################
-#  9. verify object (SHA1/type) check
+#  9. verify object (SHA/type) check
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
+type tag
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (SHA/type) check -- correct type, nonexisting object' \
+	'^error: char7: could not verify object.*$'
+
+cat >tag.sig <<EOF
+object $head
 type tagggg
 tag mytag
 tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure 'verify object (SHA1/type) check' \
+check_verify_failure 'verify object (SHA/type) check -- made-up type, nonexisting object' \
+	'^fatal: invalid object type'
+
+cat >tag.sig <<EOF
+object $(test_oid deadbeef)
+type tagggg
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
 	'^error: char7: could not verify object.*$'
 
+cat >tag.sig <<EOF
+object $head
+type tree
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
+	'^error: char7: could not verify object'
+
 ############################################################
 # 10. verify tag-name check
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 08/10] fsck: add new "extra" checks for "mktag"
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                             ` (7 preceding siblings ...)
  2020-11-26 22:22           ` [PATCH v2 07/10] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-12-01 20:33             ` Junio C Hamano
  2020-11-26 22:22           ` [PATCH v2 09/10] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
  2020-11-26 22:22           ` [PATCH v2 10/10] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Add optional "extra" checks to fsck, these are needed to eventually
replace the custom not-quite-fsck code in mktag.c.

The mktag checks differ from fsck_tag() in several ways, one of those
is that fsck doesn't know how to refuse an object with custom headers,
and isn't strict about header and body newline separation.

Teach it how to optionally report these. I thought the best way to do
that given the current structure of the code was to add a new "extra"
category in addition to error/warn/info. Under --strict the "info"
becomes a "warn" and "warn" becomes "error". Existing users of
fsck's (and others, e.g. index-pack) --strict option rely on this.

By adding an "extra" category and only reporting it based on a flag in
fsck_options callers can opt-in to these "extra" messages, which
they'll then need to deal with in their own "error_func".

No tests are being added for this new functionality, they're added in
a subsequent commit where we teach "mktag" to use this new validation
mode.

I'm not changing fsck_commit() to validate commit objects like this
either, we could do that, but unlike in the tag case that code
wouldn't be used anywhere. If someone wants to write a "mkcommit" they
which behaves like "mktag" they can borrow or refactor this logic for
use in fsck_commit().

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 fsck.c | 32 +++++++++++++++++++++++++++++++-
 fsck.h |  2 ++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/fsck.c b/fsck.c
index f82e2fe9e3..3c25df2244 100644
--- a/fsck.c
+++ b/fsck.c
@@ -80,7 +80,10 @@ static struct oidset gitmodules_done = OIDSET_INIT;
 	/* infos (reported as warnings, but ignored by default) */ \
 	FUNC(GITMODULES_PARSE, INFO) \
 	FUNC(BAD_TAG_NAME, INFO) \
-	FUNC(MISSING_TAGGER_ENTRY, INFO)
+	FUNC(MISSING_TAGGER_ENTRY, INFO) \
+	/* extra (only reported when requested) */ \
+	FUNC(EXTRA_HEADER_ENTRY, EXTRA) \
+	FUNC(EXTRA_HEADER_BODY_NEWLINE, EXTRA)
 
 #define MSG_ID(id, msg_type) FSCK_MSG_##id,
 enum fsck_msg_id {
@@ -975,6 +978,33 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 	else
 		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
 
+	if (options->extra && *buffer) {
+		if (!starts_with(buffer, "\n")) {
+			/*
+			 * The verify_headers() check will allow
+			 * e.g. "[...]tagger <tagger>\nsome
+			 * garbage\n\nmessage" to pass, thinking "some
+			 * garbage" could be a custom
+			 * header. E.g. "mktag" doesn't want any
+			 * unknown headers.
+			 */
+			ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
+			if (ret)
+				goto done;
+		}
+		if (starts_with(buffer, "\n\n")) {
+			/*
+			 * Some callers such as "mktag" want to
+			 * disallow "[...]tagger
+			 * <tagger>\n\n\nmessage", only allowing a
+			 * single newline for separation.
+			 */
+			ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_BODY_NEWLINE, "invalid format - headers separated body by more than one newline");
+			if (ret)
+				goto done;
+		}
+	}
+
 done:
 	strbuf_release(&sb);
 	return ret;
diff --git a/fsck.h b/fsck.h
index 69cf715e79..110efc65fd 100644
--- a/fsck.h
+++ b/fsck.h
@@ -6,6 +6,7 @@
 #define FSCK_ERROR 1
 #define FSCK_WARN 2
 #define FSCK_IGNORE 3
+#define FSCK_EXTRA 4
 
 struct fsck_options;
 struct object;
@@ -40,6 +41,7 @@ struct fsck_options {
 	unsigned strict:1;
 	int *msg_type;
 	struct oidset skiplist;
+	unsigned extra:1;
 	kh_oid_map_t *object_names;
 };
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 09/10] mktag: use fsck instead of custom verify_tag()
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                             ` (8 preceding siblings ...)
  2020-11-26 22:22           ` [PATCH v2 08/10] fsck: add new "extra" checks for "mktag" Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-12-01 20:47             ` Junio C Hamano
  2020-11-26 22:22           ` [PATCH v2 10/10] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the validation logic in "mktag" to use fsck's fsck_tag()
instead of its own custom parser. Curiously the logic for both dates
back to the same commit[1]. Let's unify them so we're not maintaining
two sets functions to verify that a tag is OK.

Moving to fsck_tag() required teaching it to optionally use some
validations that only the old mktag code could perform. That was done
in an earlier commit, the "extraHeaderEntry" and
"extraHeaderBodyNewline" tests being added here make use of that
logic.

There was other "mktag" validation logic that I think makes sense to
just remove. Namely:

 A. fsck only cares that the timezone matches [-+][0-9]{4}. The mktag
    code disallowed values larger than 1400.

    Yes there's currently no timezone with a greater offset[2], but
    since we allow any number of non-offical timezones (e.g. +1234)
    passing this through seems fine. Git also won't break in the
    future if e.g. French Polynesia decides it needs to outdo the Line
    Islands when it comes to timezone extravagance.

 B. fsck allows missing author names such as "tagger <email>", mktag
    wouldn't, but would allow e.g. "tagger [2 spaces] <email>" (but
    not "tagger [1 space] <email>"). Now we allow all of these.

 C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
    allows it.

We didn't only lose obscure validation logic, we also gained some:

 D. fsck disallows zero-padded dates, but mktag didn't care. So
    e.g. the timestamp "0000000000 +0000" produces an error now. A
    test in "t1006-cat-file.sh" relied on this, it's been changed to
    use "hash-object" (without fsck) instead.

1. ec4465adb38 (Add "tag" objects that can be used to sign other
   objects., 2005-04-25)

2. https://en.wikipedia.org/wiki/List_of_UTC_time_offsets

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c     | 197 ++++++++++++--------------------------------
 fsck.c              |  15 +++-
 fsck.h              |   9 ++
 t/t1006-cat-file.sh |   2 +-
 t/t3800-mktag.sh    |  78 +++++++++++-------
 5 files changed, 121 insertions(+), 180 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index dc354828f7..54b0d75ff7 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -2,160 +2,61 @@
 #include "tag.h"
 #include "replace-object.h"
 #include "object-store.h"
+#include "fsck.h"
 
-/*
- * A signature file has a very simple fixed format: four lines
- * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
- * "tagger <committer>", followed by a blank line, a free-form tag
- * message and a signature block that git itself doesn't care about,
- * but that can be verified with gpg or similar.
- *
- * The first four lines are guaranteed to be at least 83 bytes:
- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
- * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
- * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
- * the shortest possible tagger-line.
- */
-
-/*
- * We refuse to tag something we can't verify. Just because.
- */
-static int verify_object(const struct object_id *oid, const char *expected_type)
+static int mktag_fsck_error_func(struct fsck_options *o,
+				 const struct object_id *oid,
+				 enum object_type object_type,
+				 int msg_type, const char *message)
 {
-	int ret = -1;
-	enum object_type type;
-	unsigned long size;
-	void *buffer = read_object_file(oid, &type, &size);
-	const struct object_id *repl = lookup_replace_object(the_repository, oid);
-
-	if (buffer) {
-		if (type == type_from_string(expected_type)) {
-			ret = check_object_signature(the_repository, repl,
-						     buffer, size,
-						     expected_type);
-		}
-		free(buffer);
+	switch (msg_type) {
+	case FSCK_WARN:
+	case FSCK_ERROR:
+	case FSCK_EXTRA:
+		/*
+		 * We treat both warnings and errors as errors, things
+		 * like missing "tagger" lines are "only" warnings
+		 * under fsck, we've always considered them an error.
+		 */
+		fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message);
+		return 1;
+	default:
+		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
+		    msg_type);
 	}
-	return ret;
 }
 
-static int verify_tag(char *buffer, unsigned long size)
+static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 {
-	int typelen;
-	char type[20];
-	struct object_id oid;
-	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
-	size_t len;
-
-	if (size < 84)
-		return error("wanna fool me ? you obviously got the size wrong !");
-
-	buffer[size] = 0;
-
-	/* Verify object line */
-	object = buffer;
-	if (memcmp(object, "object ", 7))
-		return error("char%d: does not start with \"object \"", 0);
-
-	if (parse_oid_hex(object + 7, &oid, &p))
-		return error("char%d: could not get SHA1 hash", 7);
-
-	/* Verify type line */
-	type_line = p + 1;
-	if (memcmp(type_line - 1, "\ntype ", 6))
-		return error("char%d: could not find \"\\ntype \"", 47);
-
-	/* Verify tag-line */
-	tag_line = strchr(type_line, '\n');
-	if (!tag_line)
-		return error("char%"PRIuMAX": could not find next \"\\n\"",
-				(uintmax_t) (type_line - buffer));
-	tag_line++;
-	if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
-		return error("char%"PRIuMAX": no \"tag \" found",
-				(uintmax_t) (tag_line - buffer));
-
-	/* Get the actual type */
-	typelen = tag_line - type_line - strlen("type \n");
-	if (typelen >= sizeof(type))
-		return error("char%"PRIuMAX": type too long",
-				(uintmax_t) (type_line+5 - buffer));
-
-	memcpy(type, type_line+5, typelen);
-	type[typelen] = 0;
-
-	/* Verify that the object matches */
-	if (verify_object(&oid, type))
-		return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));
-
-	/* Verify the tag-name: we don't allow control characters or spaces in it */
-	tag_line += 4;
-	for (;;) {
-		unsigned char c = *tag_line++;
-		if (c == '\n')
-			break;
-		if (c > ' ')
-			continue;
-		return error("char%"PRIuMAX": could not verify tag name",
-				(uintmax_t) (tag_line - buffer));
-	}
-
-	/* Verify the tagger line */
-	tagger_line = tag_line;
-
-	if (memcmp(tagger_line, "tagger ", 7))
-		return error("char%"PRIuMAX": could not find \"tagger \"",
-			(uintmax_t) (tagger_line - buffer));
-
-	/*
-	 * Check for correct form for name and email
-	 * i.e. " <" followed by "> " on _this_ line
-	 * No angle brackets within the name or email address fields.
-	 * No spaces within the email address field.
-	 */
-	tagger_line += 7;
-	if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
-		strpbrk(tagger_line, "<>\n") != lb+1 ||
-		strpbrk(lb+2, "><\n ") != rb)
-		return error("char%"PRIuMAX": malformed tagger field",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* Check for author name, at least one character, space is acceptable */
-	if (lb == tagger_line)
-		return error("char%"PRIuMAX": missing tagger name",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* timestamp, 1 or more digits followed by space */
-	tagger_line = rb + 2;
-	if (!(len = strspn(tagger_line, "0123456789")))
-		return error("char%"PRIuMAX": missing tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += len;
-	if (*tagger_line != ' ')
-		return error("char%"PRIuMAX": malformed tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line++;
-
-	/* timezone, 5 digits [+-]hhmm, max. 1400 */
-	if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
-	      strspn(tagger_line+1, "0123456789") == 4 &&
-	      tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
-		return error("char%"PRIuMAX": malformed tag timezone",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += 6;
-
-	/* Verify the blank line separating the header from the body */
-	if (*tagger_line != '\n')
-		return error("char%"PRIuMAX": trailing garbage in tag header",
-			(uintmax_t) (tagger_line - buffer));
+	int ret;
+	enum object_type type;
+	unsigned long size;
+	void *buffer;
+	const struct object_id *repl;
+
+	buffer = read_object_file(tagged_oid, &type, &size);
+	if (!buffer)
+		die("could not read tagged object '%s'\n",
+		    oid_to_hex(tagged_oid));
+	if (type != *tagged_type)
+		die("object '%s' tagged as '%s', but is a '%s' type\n",
+		    oid_to_hex(tagged_oid),
+		    type_name(*tagged_type), type_name(type));
+
+	repl = lookup_replace_object(the_repository, tagged_oid);
+	ret = check_object_signature(the_repository, repl,
+				     buffer, size, type_name(*tagged_type));
+	free(buffer);
 
-	/* The actual stuff afterwards we don't care about.. */
-	return 0;
+	return ret;
 }
 
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	struct strbuf buf = STRBUF_INIT;
+	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
+	struct object_id tagged_oid;
+	int tagged_type;
 	struct object_id result;
 
 	if (argc != 1)
@@ -164,10 +65,14 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
 
-	/* Verify it for some basic sanity: it needs to start with
-	   "object <sha1>\ntype\ntagger " */
-	if (verify_tag(buf.buf, buf.len) < 0)
-		die("invalid tag signature file");
+	fsck_options.extra = 1;
+	fsck_options.error_func = mktag_fsck_error_func;
+	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
+				&tagged_oid, &tagged_type))
+		die("tag on stdin did not pass our strict fsck check");
+
+	if (verify_object_in_tag(&tagged_oid, &tagged_type))
+		die("tag on stdin did not refer to a valid object");
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
 		die("unable to write annotated tag object");
diff --git a/fsck.c b/fsck.c
index 3c25df2244..97da3a13c6 100644
--- a/fsck.c
+++ b/fsck.c
@@ -914,6 +914,16 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		    unsigned long size, struct fsck_options *options)
 {
 	struct object_id tagged_oid;
+	int tagged_type;
+	return fsck_tag_standalone(oid, buffer, size, options, &tagged_oid,
+				   &tagged_type);
+}
+
+int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+			unsigned long size, struct fsck_options *options,
+			struct object_id *tagged_oid,
+			int *tagged_type)
+{
 	int ret = 0;
 	char *eol;
 	struct strbuf sb = STRBUF_INIT;
@@ -927,7 +937,7 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
 		goto done;
 	}
-	if (parse_oid_hex(buffer, &tagged_oid, &p) || *p != '\n') {
+	if (parse_oid_hex(buffer, tagged_oid, &p) || *p != '\n') {
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
 		if (ret)
 			goto done;
@@ -943,7 +953,8 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
 		goto done;
 	}
-	if (type_from_string_gently(buffer, eol - buffer, 1) < 0)
+	*tagged_type = type_from_string_gently(buffer, eol - buffer, 1);
+	if (*tagged_type < 0)
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
 	if (ret)
 		goto done;
diff --git a/fsck.h b/fsck.h
index 110efc65fd..cf43046146 100644
--- a/fsck.h
+++ b/fsck.h
@@ -64,6 +64,15 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options);
 int fsck_object(struct object *obj, void *data, unsigned long size,
 	struct fsck_options *options);
 
+/*
+ * fsck a tag, and pass info about it back to the caller. This is
+ * exposed fsck_object() internals for git-mktag(1).
+ */
+int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+			unsigned long size, struct fsck_options *options,
+			struct object_id *tagged_oid,
+			int *tag_type);
+
 /*
  * Some fsck checks are context-dependent, and may end up queued; run this
  * after completing all fsck_object() calls in order to resolve any remaining
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 2f501d2dc9..5d2dc99b74 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -166,7 +166,7 @@ tag_content="$tag_header_without_timestamp 0000000000 +0000
 
 $tag_description"
 
-tag_sha1=$(echo_without_newline "$tag_content" | git mktag)
+tag_sha1=$(echo_without_newline "$tag_content" | git hash-object -t tag --stdin -w)
 tag_size=$(strlen "$tag_content")
 
 run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" 1
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index a6a67b6f27..352235353f 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -37,7 +37,7 @@ too short for a tag
 EOF
 
 check_verify_failure 'Tag object length check' \
-	'^error: .*size wrong.*$'
+	'^error:.* missingObject:'
 
 ############################################################
 #  2. object line label check
@@ -50,7 +50,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
+check_verify_failure '"object" line label check' '^error:.* missingObject:'
 
 ############################################################
 #  3. object line SHA check
@@ -63,7 +63,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
+check_verify_failure '"object" line check' '^error:.* badObjectSha1:'
 
 ############################################################
 #  4. type line label check
@@ -76,7 +76,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error:.* missingTypeEntry:'
 
 ############################################################
 #  5. type line eol check
@@ -84,7 +84,7 @@ check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
 echo "object $head" >tag.sig
 printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
 
-check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error:.* unterminatedHeader:'
 
 ############################################################
 #  6. tag line label check #1
@@ -98,7 +98,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure '"tag" line label check #1' \
-	'^error: char.*: no "tag " found$'
+	'^error:.* missingTagEntry:'
 
 ############################################################
 #  7. tag line label check #2
@@ -110,7 +110,7 @@ tag
 EOF
 
 check_verify_failure '"tag" line label check #2' \
-	'^error: char.*: no "tag " found$'
+	'^error:.* badType:'
 
 ############################################################
 #  8. type line type-name length check
@@ -122,7 +122,7 @@ tag mytag
 EOF
 
 check_verify_failure '"type" line type-name length check' \
-	'^error: char.*: type too long$'
+	'^error:.* badType:'
 
 ############################################################
 #  9. verify object (SHA/type) check
@@ -136,7 +136,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (SHA/type) check -- correct type, nonexisting object' \
-	'^error: char7: could not verify object.*$'
+	'^fatal: could not read tagged object'
 
 cat >tag.sig <<EOF
 object $head
@@ -147,7 +147,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (SHA/type) check -- made-up type, nonexisting object' \
-	'^fatal: invalid object type'
+	'^error:.* badType:'
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
@@ -158,7 +158,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
-	'^error: char7: could not verify object.*$'
+	'^error:.* badType:'
 
 cat >tag.sig <<EOF
 object $head
@@ -169,7 +169,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
-	'^error: char7: could not verify object'
+	'^fatal: object.*tagged as.*tree.*but is.*commit'
 
 ############################################################
 # 10. verify tag-name check
@@ -183,7 +183,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error: char.*: could not verify tag name$'
+	'^error:.* badTagName:'
 
 ############################################################
 # 11. tagger line label check #1
@@ -197,7 +197,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error: char.*: could not find "tagger "$'
+	'^error:.* missingTaggerEntry:'
 
 ############################################################
 # 12. tagger line label check #2
@@ -212,10 +212,10 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error: char.*: could not find "tagger "$'
+	'^error:.* missingTaggerEntry:'
 
 ############################################################
-# 13. disallow missing tag author name
+# 13. allow missing tag author name like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -226,8 +226,9 @@ tagger  <> 0 +0000
 This is filler
 EOF
 
-check_verify_failure 'disallow missing tag author name' \
-	'^error: char.*: missing tagger name$'
+test_expect_success 'allow missing tag author name' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 14. disallow missing tag author name
@@ -242,7 +243,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error: char.*: malformed tagger field$'
+	'^error:.* badEmail:'
 
 ############################################################
 # 15. allow empty tag email
@@ -260,7 +261,7 @@ test_expect_success \
     'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
 
 ############################################################
-# 16. disallow spaces in tag email
+# 16. allow spaces in tag email like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -270,8 +271,9 @@ tagger T A Gger <tag ger@example.com> 0 +0000
 
 EOF
 
-check_verify_failure 'disallow spaces in tag email' \
-	'^error: char.*: malformed tagger field$'
+test_expect_success 'allow spaces in tag email like fsck' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 17. disallow missing tag timestamp
@@ -285,7 +287,7 @@ tagger T A Gger <tagger@example.com>__
 EOF
 
 check_verify_failure 'disallow missing tag timestamp' \
-	'^error: char.*: missing tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 18. detect invalid tag timestamp1
@@ -299,7 +301,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
 EOF
 
 check_verify_failure 'detect invalid tag timestamp1' \
-	'^error: char.*: missing tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 19. detect invalid tag timestamp2
@@ -313,7 +315,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
 EOF
 
 check_verify_failure 'detect invalid tag timestamp2' \
-	'^error: char.*: malformed tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 20. detect invalid tag timezone1
@@ -327,7 +329,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
 EOF
 
 check_verify_failure 'detect invalid tag timezone1' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 ############################################################
 # 21. detect invalid tag timezone2
@@ -341,10 +343,10 @@ tagger T A Gger <tagger@example.com> 1206478233 +  30
 EOF
 
 check_verify_failure 'detect invalid tag timezone2' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 ############################################################
-# 22. detect invalid tag timezone3
+# 22. allow invalid tag timezone3 (the maximum is -1200/+1400)
 
 cat >tag.sig <<EOF
 object $head
@@ -354,8 +356,9 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
 
 EOF
 
-check_verify_failure 'detect invalid tag timezone3' \
-	'^error: char.*: malformed tag timezone$'
+test_expect_success 'allow invalid tag timezone' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 23. detect invalid header entry
@@ -370,7 +373,20 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error: char.*: trailing garbage in tag header$'
+	'^error:.* extraHeaderEntry:'
+
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+
+
+this line should be one line up
+EOF
+
+check_verify_failure 'detect invalid header entry' \
+	'^error:.* extraHeaderBodyNewline:'
 
 ############################################################
 # 24. create valid tag
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 10/10] mktag doc: update to explain why to use this
  2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
                             ` (9 preceding siblings ...)
  2020-11-26 22:22           ` [PATCH v2 09/10] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
@ 2020-11-26 22:22           ` Ævar Arnfjörð Bjarmason
  2020-12-01 20:59             ` Junio C Hamano
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-11-26 22:22 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the mktag documentation to compare itself to the similar
"hash-object -t tag" command. Before this someone reading the
documentation wouldn't have much of an idea what the difference
was.

Let's make it clear that it's to do with slightly different fsck
validation logic, and cross-link the "mktag" and "hash-object"
documentation to aid discover-ability.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-hash-object.txt |  4 ++++
 Documentation/git-mktag.txt       | 29 +++++++++++++++++++++++++----
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index df9e2c58bd..c535661ced 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -58,6 +58,10 @@ OPTIONS
 	stress-testing Git itself or reproducing characteristics of corrupt or
 	bogus objects encountered in the wild.
 
+SEE ALSO
+--------
+linkgit:git-mktag[1]
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index a158428eb9..3ba15072df 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -3,7 +3,7 @@ git-mktag(1)
 
 NAME
 ----
-git-mktag - Creates a tag object
+git-mktag - Creates a tag object with extra validation
 
 
 SYNOPSIS
@@ -13,10 +13,20 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Reads a tag contents on standard input and creates a tag object
-that can also be used to sign other objects.
 
-The output is the new tag's <object> identifier.
+Reads a tag contents on standard input and creates a tag object. The
+output is the new tag's <object> identifier.
+
+This command accepts a subset of what linkgit:git-hash-object[1] would
+accept with `-t tag --stdin`. I.e. both of these work:
+
+    git mktag <my-tag
+    git hash-object -t tag --stdin <my-tag
+
+The difference between the two is that mktag does the equivalent of a
+linkgit:git-fsck(1) check on its input, and furthermore disallows some
+thing linkgit:git-hash-object[1] would pass, e.g. extra headers in the
+object before the message.
 
 Tag Format
 ----------
@@ -34,6 +44,17 @@ exists, is separated by a blank line from the header.  The
 message part may contain a signature that Git itself doesn't
 care about, but that can be verified with gpg.
 
+HISTORY
+-------
+
+In versions of Git before v2.30.0 the "mktag" command's validation
+logic was subtly different than that of linkgit:git-fsck[1]. It is now
+a strict superset of linkgit:git-fsck[1]'s validation logic.
+
+SEE ALSO
+--------
+linkgit:git-hash-object[1],
+
 GIT
 ---
 Part of the linkgit:git[1] suite
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: [PATCH v2 00/10] make "mktag" use fsck_tag()
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
@ 2020-12-01 10:08             ` Ævar Arnfjörð Bjarmason
  2020-12-01 20:01               ` Junio C Hamano
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                               ` (10 subsequent siblings)
  11 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-01 10:08 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason


On Thu, Nov 26 2020, Ævar Arnfjörð Bjarmason wrote:

> Now a non-RFC. I went for the approach I suggested in
> <87r1ognv4b.fsf@evledraar.gmail.com> of just having fsck_tag() able to
> optionally tell us about its parsed tag/type, thus avoiding any need
> for a custom parser in mktag.c. Hopefully I've addressed the rest of
> the feedback, range-diff below.

Ping @ Jeff & brian: you said you wanted this in one shape or another,
so mind seeing if the v2 looks good to you?:)

Junio didn't pick it up for the "What's Cooking" sent out recently,
hopefully some reviewer ACK/NACK will help move it forward. Thanks!

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

* Re: [PATCH v2 00/10] make "mktag" use fsck_tag()
  2020-12-01 10:08             ` Ævar Arnfjörð Bjarmason
@ 2020-12-01 20:01               ` Junio C Hamano
  2020-12-02 22:20                 ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:01 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> On Thu, Nov 26 2020, Ævar Arnfjörð Bjarmason wrote:
>
>> Now a non-RFC. I went for the approach I suggested in
>> <87r1ognv4b.fsf@evledraar.gmail.com> of just having fsck_tag() able to
>> optionally tell us about its parsed tag/type, thus avoiding any need
>> for a custom parser in mktag.c. Hopefully I've addressed the rest of
>> the feedback, range-diff below.
>
> Ping @ Jeff & brian: you said you wanted this in one shape or another,
> so mind seeing if the v2 looks good to you?:)
>
> Junio didn't pick it up for the "What's Cooking" sent out recently,
> hopefully some reviewer ACK/NACK will help move it forward. Thanks!

True.  I don't want to queue too many topics on 'seen', only to end
up with a pile of patches that haven't been reviewed adequately and
cannot move forward.

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

* Re: [PATCH v2 01/10] mktag doc: say <hash> not <sha1>
  2020-11-26 22:22           ` [PATCH v2 01/10] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
@ 2020-12-01 20:17             ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:17 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the "mktag" documentation to refer to the input hash as just
> "hash", not "sha1". This command has supported SHA-256 for a while
> now.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---

I think saying <hash> instead of <sha> is a very good idea---it won't
tie us to the SHA family of hashes, including SHA-256, forever.

>  Documentation/git-mktag.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
> index fa6a756123..a158428eb9 100644
> --- a/Documentation/git-mktag.txt
> +++ b/Documentation/git-mktag.txt
> @@ -23,7 +23,7 @@ Tag Format
>  A tag signature file, to be fed to this command's standard input,
>  has a very simple fixed format: four lines of
>  
> -  object <sha1>
> +  object <hash>
>    type <typename>
>    tag <tagname>
>    tagger <tagger>

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

* Re: [PATCH v2 02/10] mktag: use default strbuf_read() hint
  2020-11-26 22:22           ` [PATCH v2 02/10] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
@ 2020-12-01 20:19             ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:19 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the hardcoded hint of 2^12 to 0. The default strbuf hint is
> perfectly fine here, and the only reason we were hardcoding it is
> because it survived migration from a pre-strbuf fixed-sized buffer.
>
> See fd17f5b5f77 (Replace all read_fd use with strbuf_read, and get rid
> of it., 2007-09-10) for that migration.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  builtin/mktag.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/builtin/mktag.c b/builtin/mktag.c
> index 4982d3a93e..ff7ac8e0e5 100644
> --- a/builtin/mktag.c
> +++ b/builtin/mktag.c
> @@ -161,7 +161,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)

In the lines beyond the pre-context there is a comment that mentions
<sha1>, but I think it is sensible not to clean it up with this
patch, as it will go away with the main "use fsck machinery" step.

>  	if (argc != 1)
>  		usage("git mktag");
>  
> -	if (strbuf_read(&buf, 0, 4096) < 0) {
> +	if (strbuf_read(&buf, 0, 0) < 0) {
>  		die_errno("could not read from stdin");
>  	}

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

* Re: [PATCH v2 03/10] mktag: reword write_object_file() error
  2020-11-26 22:22           ` [PATCH v2 03/10] mktag: reword write_object_file() error Ævar Arnfjörð Bjarmason
@ 2020-12-01 20:20             ` Junio C Hamano
  2020-12-01 20:49               ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:20 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the error message emitted when write_object_file() fails to
> make more sense. At this point we're not writing a "tag file" (which
> as an aside we never do, we just write to stdout). We are writing an
> annotated tag object, let's say that instead.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  builtin/mktag.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/builtin/mktag.c b/builtin/mktag.c
> index ff7ac8e0e5..603b55aca0 100644
> --- a/builtin/mktag.c
> +++ b/builtin/mktag.c
> @@ -171,7 +171,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
>  		die("invalid tag signature file");
>  
>  	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
> -		die("unable to write tag file");
> +		die("unable to write annotated tag object");

"write an annotated tag object"?

It is not just this call to die(), but we'd eventually want to _(l10n/i18n)
these messages.  Perhaps in a separate step but on all messages fed
to die/error/warn in this file.

>  
>  	strbuf_release(&buf);
>  	printf("%s\n", oid_to_hex(&result));

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

* Re: [PATCH v2 06/10] mktag tests: remove needless SHA-1 hardcoding
  2020-11-26 22:22           ` [PATCH v2 06/10] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
@ 2020-12-01 20:24             ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:24 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the tests amended in acb49d1cc8b (t3800: make hash-size
> independent, 2019-08-18) even more to make them independent of either
> SHA-1 or SHA-256.
>
> Some of these tests were failing for the wrong reasons. The first one
> being modified here would fail because the line starts with "xxxxxx"
> instead of "object", the rest of the line doesn't matter.
>
> Let's just put a valid hash on the rest of the line anyway to narrow
> the test down for just the s/object/xxxxxx/ case.
>
> The second one being modified here would fail under
> GIT_TEST_DEFAULT_HASH=sha256 because <some sha-1 length garbage> is an
> invalid SHA-256, but we should really be testing <some sha-256 length
> garbage> when under SHA-256.
>
> This doesn't really matter since we should be able to trust other
> parts of the code to validate things in the 0-9a-f range, but let's
> keep it for good measure.
>
> There's a later test which tests an invalid SHA which looks like a
> valid one, to stress the "We refuse to tag something we can't
> verify[...]" logic in mktag.c.
>
> But here we're testing for a SHA-length string which contains
> characters outside of the /[0-9a-f]/i set.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t3800-mktag.sh | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index 0e411e3c45..e9d7799537 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -43,7 +43,7 @@ check_verify_failure 'Tag object length check' \
>  #  2. object line label check
>  
>  cat >tag.sig <<EOF
> -xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
> +xxxxxx $head
>  type tag
>  tag mytag
>  tagger . <> 0 +0000

These steps to prepare the input and the expected output outside the
test_expect_* block look too old-fashioned but they are consistently
so, so let's let them pass, at least inside this series.

> @@ -53,10 +53,10 @@ EOF
>  check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
>  
>  ############################################################
> -#  3. object line SHA1 check
> +#  3. object line SHA check

Shouldn't we say hash instead of SHA for consistency?

>  
>  cat >tag.sig <<EOF
> -object zz9e9b33986b1c2670fff52c5067603117b3e895
> +object $(echo $head | tr 0-9a-f z)
>  type tag
>  tag mytag
>  tagger . <> 0 +0000

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

* Re: [PATCH v2 08/10] fsck: add new "extra" checks for "mktag"
  2020-11-26 22:22           ` [PATCH v2 08/10] fsck: add new "extra" checks for "mktag" Ævar Arnfjörð Bjarmason
@ 2020-12-01 20:33             ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:33 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Add optional "extra" checks to fsck, these are needed to eventually
> replace the custom not-quite-fsck code in mktag.c.
>
> The mktag checks differ from fsck_tag() in several ways, one of those
> is that fsck doesn't know how to refuse an object with custom headers,
> and isn't strict about header and body newline separation.

You say "there must be only one blank line between the header and
the body", but viewing from the way we parse header and body, I
think that such a rule actually forbids a leading blank line in the
body and steps into checking whitespace errors---makes readers
wonder if we should be also detecting trailing whitespaces on lines,
etc.

Is there actually such a check enforced in the original?  Or is this
a new rule that appeared out of thin air?  We'd have to inspect the
lines deleted from builtin/mktag.c in the next step, I gues.

> By adding an "extra" category and only reporting it based on a flag in
> fsck_options callers can opt-in to these "extra" messages, which
> they'll then need to deal with in their own "error_func".

Makes sense.


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

* Re: [PATCH v2 09/10] mktag: use fsck instead of custom verify_tag()
  2020-11-26 22:22           ` [PATCH v2 09/10] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
@ 2020-12-01 20:47             ` Junio C Hamano
  2020-12-01 22:28               ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:47 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the validation logic in "mktag" to use fsck's fsck_tag()
> instead of its own custom parser. Curiously the logic for both dates
> back to the same commit[1]. Let's unify them so we're not maintaining
> two sets functions to verify that a tag is OK.
>
> Moving to fsck_tag() required teaching it to optionally use some
> validations that only the old mktag code could perform. That was done
> in an earlier commit, the "extraHeaderEntry" and
> "extraHeaderBodyNewline" tests being added here make use of that
> logic.
>
> There was other "mktag" validation logic that I think makes sense to
> just remove. Namely:

I may not agree with the specifics in this list, but I agree that
the validation should be consistent between mktag and fsck.

> +	switch (msg_type) {
> +	case FSCK_WARN:
> +	case FSCK_ERROR:
> +	case FSCK_EXTRA:
> +		/*
> +		 * We treat both warnings and errors as errors, things
> +		 * like missing "tagger" lines are "only" warnings
> +		 * under fsck, we've always considered them an error.
> +		 */

This is a good comment and design decision.  

As far as I am concerned, the only reason we warn on a missing
tagger line without erroring out is because very early versions of
Git did allow creating such tag objects, and there are annotated
tags in the wild that lack the tagger line.

> +		fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message);
> +		return 1;
> +	default:
> +		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
> +		    msg_type);
>  	}
> -	return ret;
>  }
>  
> -static int verify_tag(char *buffer, unsigned long size)
> ...
> -	/* timezone, 5 digits [+-]hhmm, max. 1400 */
> -	if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
> -	      strspn(tagger_line+1, "0123456789") == 4 &&
> -	      tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
> -		return error("char%"PRIuMAX": malformed tag timezone",
> -			(uintmax_t) (tagger_line - buffer));
> -	tagger_line += 6;
> -
> -	/* Verify the blank line separating the header from the body */
> -	if (*tagger_line != '\n')
> -		return error("char%"PRIuMAX": trailing garbage in tag header",
> -			(uintmax_t) (tagger_line - buffer));
>  
> -	/* The actual stuff afterwards we don't care about.. */
> -	return 0;

I do not see the "we do not want more than one blank line after the
header" in the original, which was one thing I was looking for after
seeing what 08/10 did.

> +	fsck_options.extra = 1;
> +	fsck_options.error_func = mktag_fsck_error_func;

I wonder if we really need the new .extra bit member in the
fsck_options.  Wouldn't it be sufficient to instead teach
fsck_error_func() that the extra level is a non-event?


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

* Re: [PATCH v2 03/10] mktag: reword write_object_file() error
  2020-12-01 20:20             ` Junio C Hamano
@ 2020-12-01 20:49               ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:49 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

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

> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
>
>> Change the error message emitted when write_object_file() fails to
>> make more sense. At this point we're not writing a "tag file" (which
>> as an aside we never do, we just write to stdout). We are writing an
>> annotated tag object, let's say that instead.
>>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>>  builtin/mktag.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/builtin/mktag.c b/builtin/mktag.c
>> index ff7ac8e0e5..603b55aca0 100644
>> --- a/builtin/mktag.c
>> +++ b/builtin/mktag.c
>> @@ -171,7 +171,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
>>  		die("invalid tag signature file");
>>  
>>  	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
>> -		die("unable to write tag file");
>> +		die("unable to write annotated tag object");
>
> "write an annotated tag object"?

Actually, there is no such thing as an "unannotated tag object".
Perhaps _("unable to create a tag object")?

>
> It is not just this call to die(), but we'd eventually want to _(l10n/i18n)
> these messages.  Perhaps in a separate step but on all messages fed
> to die/error/warn in this file.
>
>>  
>>  	strbuf_release(&buf);
>>  	printf("%s\n", oid_to_hex(&result));

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

* Re: [PATCH v2 10/10] mktag doc: update to explain why to use this
  2020-11-26 22:22           ` [PATCH v2 10/10] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
@ 2020-12-01 20:59             ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 20:59 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> +Reads a tag contents on standard input and creates a tag object. The
> +output is the new tag's <object> identifier.
> +
> +This command accepts a subset of what linkgit:git-hash-object[1] would
> +accept with `-t tag --stdin`. I.e. both of these work:
> +
> +    git mktag <my-tag
> +    git hash-object -t tag --stdin <my-tag

It's misleading to say "both of these work", I am afraid.  If the
former works, the latter would.  That is what "accepts a subset"
means, no?

> +The difference between the two is that mktag does the equivalent of a
> +linkgit:git-fsck(1) check on its input, and furthermore disallows some
> +thing linkgit:git-hash-object[1] would pass, e.g. extra headers in the
> +object before the message.

Good description.

> @@ -34,6 +44,17 @@ exists, is separated by a blank line from the header.  The
>  message part may contain a signature that Git itself doesn't
>  care about, but that can be verified with gpg.
>  
> +HISTORY
> +-------
> +
> +In versions of Git before v2.30.0 the "mktag" command's validation

Hardcoding v2.30.0 here feels problematic.  If the series cooks in
'next' while 2.30 gets released, it has to be kicked out of 'next'
to update this line before it gets allowed in 'next'.

> +logic was subtly different than that of linkgit:git-fsck[1]. It is now
> +a strict superset of linkgit:git-fsck[1]'s validation logic.

It may be a better direction to go to drop this section.

Also, I somehow have a feeling that we'd rather want to loosen the
"no other headers allowed" in the longer run to be consistent with
what "fsck" does.

I also wonder if we want to teach "commit-tree" to also run fsck
check like this new version of mktag does.  It is outside the scope
of this "mktag" series, of course.

Thanks.

> +SEE ALSO
> +--------
> +linkgit:git-hash-object[1],
> +
>  GIT
>  ---
>  Part of the linkgit:git[1] suite

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

* Re: [PATCH v2 09/10] mktag: use fsck instead of custom verify_tag()
  2020-12-01 20:47             ` Junio C Hamano
@ 2020-12-01 22:28               ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-01 22:28 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

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

> I do not see the "we do not want more than one blank line after the
> header" in the original, which was one thing I was looking for after
> seeing what 08/10 did.
>
>> +	fsck_options.extra = 1;
>> +	fsck_options.error_func = mktag_fsck_error_func;

Hmph, recent "released" versions of Git seems to be fine when

--- >8 ------ >8 ------ >8 ------ >8 ------ >8 ---
object 72ffeb997eaf999f6938b2a7e0d9a75dcceaa311
type commit
tag tester
tagger Junio C Hamano <gitster@pobox.com> 1606860947 -0800


a message after a blank
--- 8< ------ 8< ------ 8< ------ 8< ------ 8< ---

is fed to their "git mktag".  If I am not mistaken, we definitely
want to drop the EXTRA_HEADER_BODY_NEWLINE check from 08/10, even
though EXTRA_HEADER_ENTRY may be something we want to retain at
least for some releases for backward compatibility.




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

* Re: [PATCH v2 00/10] make "mktag" use fsck_tag()
  2020-12-01 20:01               ` Junio C Hamano
@ 2020-12-02 22:20                 ` Junio C Hamano
  2020-12-03 16:38                   ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2020-12-02 22:20 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

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

> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> On Thu, Nov 26 2020, Ævar Arnfjörð Bjarmason wrote:
>>
>>> Now a non-RFC. I went for the approach I suggested in
>>> <87r1ognv4b.fsf@evledraar.gmail.com> of just having fsck_tag() able to
>>> optionally tell us about its parsed tag/type, thus avoiding any need
>>> for a custom parser in mktag.c. Hopefully I've addressed the rest of
>>> the feedback, range-diff below.
>>
>> Ping @ Jeff & brian: you said you wanted this in one shape or another,
>> so mind seeing if the v2 looks good to you?:)
>>
>> Junio didn't pick it up for the "What's Cooking" sent out recently,
>> hopefully some reviewer ACK/NACK will help move it forward. Thanks!
>
> True.  I don't want to queue too many topics on 'seen', only to end
> up with a pile of patches that haven't been reviewed adequately and
> cannot move forward.

So, now I've seen all of them.

There were some minor things in the earlier part I commented on, and
if I am not mistaken, a new check, "body must not begin with a blank
line", should not be added at all, which would affect 08/10.

I am not sure how much longer we want to retain the .extra level of
checks that are more strict than those of fsck.  If we decide that
it is not worth it to forbid new object headers, we may be able to
lose 08/10 altogether.

Other than the above, the series mostly looked well done.

Thanks.

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

* Re: [PATCH v2 00/10] make "mktag" use fsck_tag()
  2020-12-02 22:20                 ` Junio C Hamano
@ 2020-12-03 16:38                   ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-03 16:38 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin


On Wed, Dec 02 2020, Junio C Hamano wrote:

> Junio C Hamano <gitster@pobox.com> writes:
>
>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>>
>>> On Thu, Nov 26 2020, Ævar Arnfjörð Bjarmason wrote:
>>>
>>>> Now a non-RFC. I went for the approach I suggested in
>>>> <87r1ognv4b.fsf@evledraar.gmail.com> of just having fsck_tag() able to
>>>> optionally tell us about its parsed tag/type, thus avoiding any need
>>>> for a custom parser in mktag.c. Hopefully I've addressed the rest of
>>>> the feedback, range-diff below.
>>>
>>> Ping @ Jeff & brian: you said you wanted this in one shape or another,
>>> so mind seeing if the v2 looks good to you?:)
>>>
>>> Junio didn't pick it up for the "What's Cooking" sent out recently,
>>> hopefully some reviewer ACK/NACK will help move it forward. Thanks!
>>
>> True.  I don't want to queue too many topics on 'seen', only to end
>> up with a pile of patches that haven't been reviewed adequately and
>> cannot move forward.
>
> So, now I've seen all of them.
>
> There were some minor things in the earlier part I commented on, and
> if I am not mistaken, a new check, "body must not begin with a blank
> line", should not be added at all, which would affect 08/10.
>
> I am not sure how much longer we want to retain the .extra level of
> checks that are more strict than those of fsck.  If we decide that
> it is not worth it to forbid new object headers, we may be able to
> lose 08/10 altogether.
>
> Other than the above, the series mostly looked well done.

Hi. Just a quick note to say thanks for all the feedback, and that I
don't have a v3 ready now, but will submit one soon-ish.

FWIW the header-body newline thing wasn't something I was trying to
sneak in, I went wrong in my testing somewhere and thought it was a bug
under mktag. Will test for that, remove that check or whatever as
appropriate. Thanks for the review.

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

* [PATCH v3 00/10] make "mktag" use fsck_tag()
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
  2020-12-01 10:08             ` Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 22:30               ` Junio C Hamano
                                 ` (21 more replies)
  2020-12-09 20:01             ` [PATCH v3 01/10] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
                               ` (9 subsequent siblings)
  11 siblings, 22 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

This version should address all the comments Junio made on v2. Changes:

 * The whole "extra" fsck option is gone, I just didn't realize I
   could set the new check to "ignore", and then manually promote it.

 * Ejected "mktag: reword write_object_file() error". It was the same
   phrasing as "git tag" uses, let's just keep it.

 * Clarifications in docs/commit messages

 * There's 2 extra patches at the end now which take the first steps
   into making "git mktag" more of a normal builtin. It reads fsck.*
   config variables, so you can turn off that "no extra headers" check
   through the normal fsck.<msg-id>=ignore config.

   It should also be moved to getopts, and we could make it support
   --no-strict to have the same idea of error/warning as fsck itself,
   but that's #leftoverbits, along with moving it to i18n.

   It would be nice to have patches 1-8 merged down if they're deemed
   ready, and if 9-10 aren't deemed wanted just discard them. I think
   it makes sense though...

Ævar Arnfjörð Bjarmason (10):
  mktag doc: say <hash> not <sha1>
  mktag: use default strbuf_read() hint
  mktag: remove redundant braces in one-line body "if"
  mktag tests: don't needlessly use a subshell
  mktag tests: remove needless SHA-1 hardcoding
  mktag tests: improve verify_object() test coverage
  mktag: use fsck instead of custom verify_tag()
  mktag doc: update to explain why to use this
  fsck: make fsck_config() re-usable
  mktag: allow turning off fsck.extraHeaderEntry

 Documentation/git-hash-object.txt |   4 +
 Documentation/git-mktag.txt       |  34 ++++-
 builtin/fsck.c                    |  20 +--
 builtin/mktag.c                   | 204 +++++++++---------------------
 fsck.c                            |  57 ++++++++-
 fsck.h                            |  16 +++
 t/t1006-cat-file.sh               |   2 +-
 t/t3800-mktag.sh                  | 132 ++++++++++++++-----
 8 files changed, 261 insertions(+), 208 deletions(-)

Range-diff:
 1:  f46abb37df9 =  1:  aee3f52a478 mktag doc: say <hash> not <sha1>
 2:  1b4d9a53302 =  2:  6e98557709a mktag: use default strbuf_read() hint
 3:  83f4af6013e <  -:  ----------- mktag: reword write_object_file() error
 4:  bca1484ed96 =  3:  8e5fe08f155 mktag: remove redundant braces in one-line body "if"
 5:  ac7c4097c90 =  4:  1f06b9c0cf9 mktag tests: don't needlessly use a subshell
 6:  5e076659e45 !  5:  5d1cb73ca35 mktag tests: remove needless SHA-1 hardcoding
    @@ t/t3800-mktag.sh: EOF
      
      ############################################################
     -#  3. object line SHA1 check
    -+#  3. object line SHA check
    ++#  3. object line hash check
      
      cat >tag.sig <<EOF
     -object zz9e9b33986b1c2670fff52c5067603117b3e895
 7:  a048c3e6401 !  6:  cf86f4ca37d mktag tests: improve verify_object() test coverage
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
      
      ############################################################
     -#  9. verify object (SHA1/type) check
    -+#  9. verify object (SHA/type) check
    ++#  9. verify object (hash/type) check
      
      cat >tag.sig <<EOF
      object $(test_oid deadbeef)
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
     +
     +EOF
     +
    -+check_verify_failure 'verify object (SHA/type) check -- correct type, nonexisting object' \
    ++check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
     +	'^error: char7: could not verify object.*$'
     +
     +cat >tag.sig <<EOF
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
      EOF
      
     -check_verify_failure 'verify object (SHA1/type) check' \
    -+check_verify_failure 'verify object (SHA/type) check -- made-up type, nonexisting object' \
    ++check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
     +	'^fatal: invalid object type'
     +
     +cat >tag.sig <<EOF
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
     +
     +EOF
     +
    -+check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
    ++check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
      	'^error: char7: could not verify object.*$'
      
     +cat >tag.sig <<EOF
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
     +
     +EOF
     +
    -+check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
    ++check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
     +	'^error: char7: could not verify object'
     +
      ############################################################
 8:  dab44d32359 <  -:  ----------- fsck: add new "extra" checks for "mktag"
 9:  8ff853caeea !  7:  5812ee53c97 mktag: use fsck instead of custom verify_tag()
    @@ Commit message
         back to the same commit[1]. Let's unify them so we're not maintaining
         two sets functions to verify that a tag is OK.
     
    -    Moving to fsck_tag() required teaching it to optionally use some
    -    validations that only the old mktag code could perform. That was done
    -    in an earlier commit, the "extraHeaderEntry" and
    -    "extraHeaderBodyNewline" tests being added here make use of that
    -    logic.
    +    The behavior of fsck_tag() and the old "mktag" code being removed here
    +    is different in few aspects.
     
    -    There was other "mktag" validation logic that I think makes sense to
    -    just remove. Namely:
    +    I think it makes sense to remove some of those checks, namely:
     
          A. fsck only cares that the timezone matches [-+][0-9]{4}. The mktag
             code disallowed values larger than 1400.
    @@ Commit message
          C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
             allows it.
     
    -    We didn't only lose obscure validation logic, we also gained some:
    +    In some ways fsck_tag() is stricter than "mktag" was, namely:
     
          D. fsck disallows zero-padded dates, but mktag didn't care. So
             e.g. the timestamp "0000000000 +0000" produces an error now. A
             test in "t1006-cat-file.sh" relied on this, it's been changed to
             use "hash-object" (without fsck) instead.
     
    +    There was one check I deemed worth keeping by porting it over to
    +    fsck_tag():
    +
    +     E. "mktag" did not allow any custom headers, and by extension (as an
    +        empty commit is allowed) also forbade an extra stray trailing
    +        newline after the headers it knew about.
    +
    +        Add a new check in the "ignore" category to fsck and use it. This
    +        somewhat abuses the facility added in efaba7cc77f (fsck:
    +        optionally ignore specific fsck issues completely, 2015-06-22).
    +
    +        This is somewhat of hack, but probably the least invasive change
    +        we can make here. The fsck command will shuffle these categories
    +        around, e.g. under --strict the "info" becomes a "warn" and "warn"
    +        becomes "error". Existing users of fsck's (and others,
    +        e.g. index-pack) --strict option rely on this.
    +
    +        So we need to put something into a category that'll be ignored by
    +        all existing users of the API. Pretending that
    +        fsck.extraHeaderEntry=error ("ignore" by default) was set serves
    +        to do this for us.
    +
         1. ec4465adb38 (Add "tag" objects that can be used to sign other
            objects., 2005-04-25)
     
    @@ builtin/mktag.c
     +	switch (msg_type) {
     +	case FSCK_WARN:
     +	case FSCK_ERROR:
    -+	case FSCK_EXTRA:
     +		/*
     +		 * We treat both warnings and errors as errors, things
     +		 * like missing "tagger" lines are "only" warnings
    @@ builtin/mktag.c: int cmd_mktag(int argc, const char **argv, const char *prefix)
     -	   "object <sha1>\ntype\ntagger " */
     -	if (verify_tag(buf.buf, buf.len) < 0)
     -		die("invalid tag signature file");
    -+	fsck_options.extra = 1;
     +	fsck_options.error_func = mktag_fsck_error_func;
    ++	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
     +	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
     +				&tagged_oid, &tagged_type))
     +		die("tag on stdin did not pass our strict fsck check");
    @@ builtin/mktag.c: int cmd_mktag(int argc, const char **argv, const char *prefix)
     +		die("tag on stdin did not refer to a valid object");
      
      	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
    - 		die("unable to write annotated tag object");
    + 		die("unable to write tag file");
     
      ## fsck.c ##
    +@@ fsck.c: static struct oidset gitmodules_done = OIDSET_INIT;
    + 	/* infos (reported as warnings, but ignored by default) */ \
    + 	FUNC(GITMODULES_PARSE, INFO) \
    + 	FUNC(BAD_TAG_NAME, INFO) \
    +-	FUNC(MISSING_TAGGER_ENTRY, INFO)
    ++	FUNC(MISSING_TAGGER_ENTRY, INFO) \
    ++	/* ignored (elevated when requested) */ \
    ++	FUNC(EXTRA_HEADER_ENTRY, IGNORE)
    + 
    + #define MSG_ID(id, msg_type) FSCK_MSG_##id,
    + enum fsck_msg_id {
     @@ fsck.c: static int fsck_tag(const struct object_id *oid, const char *buffer,
      		    unsigned long size, struct fsck_options *options)
      {
    @@ fsck.c: static int fsck_tag(const struct object_id *oid, const char *buffer,
      		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
      	if (ret)
      		goto done;
    +@@ fsck.c: static int fsck_tag(const struct object_id *oid, const char *buffer,
    + 	else
    + 		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
    + 
    ++	if (!starts_with(buffer, "\n")) {
    ++		/*
    ++		 * The verify_headers() check will allow
    ++		 * e.g. "[...]tagger <tagger>\nsome
    ++		 * garbage\n\nmessage" to pass, thinking "some
    ++		 * garbage" could be a custom header. E.g. "mktag"
    ++		 * doesn't want any unknown headers.
    ++		 */
    ++		ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
    ++		if (ret)
    ++			goto done;
    ++	}
    ++
    + done:
    + 	strbuf_release(&sb);
    + 	return ret;
     
      ## fsck.h ##
     @@ fsck.h: int fsck_walk(struct object *obj, void *data, struct fsck_options *options);
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
     +check_verify_failure '"object" line label check' '^error:.* missingObject:'
      
      ############################################################
    - #  3. object line SHA check
    + #  3. object line hash check
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      
      EOF
    @@ t/t3800-mktag.sh: tag mytag
     +	'^error:.* badType:'
      
      ############################################################
    - #  9. verify object (SHA/type) check
    + #  9. verify object (hash/type) check
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
    - check_verify_failure 'verify object (SHA/type) check -- correct type, nonexisting object' \
    + check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
     -	'^error: char7: could not verify object.*$'
     +	'^fatal: could not read tagged object'
      
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
    - check_verify_failure 'verify object (SHA/type) check -- made-up type, nonexisting object' \
    + check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
     -	'^fatal: invalid object type'
     +	'^error:.* badType:'
      
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
    - check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
    + check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
     -	'^error: char7: could not verify object.*$'
     +	'^error:.* badType:'
      
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
    - check_verify_failure 'verify object (SHA/type) check -- incorrect type, valid object' \
    + check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
     -	'^error: char7: could not verify object'
     +	'^fatal: object.*tagged as.*tree.*but is.*commit'
      
    @@ t/t3800-mktag.sh: this line should not be here
     +tagger T A Gger <tagger@example.com> 1206478233 -0500
     +
     +
    -+this line should be one line up
    ++this line comes after an extra newline
     +EOF
     +
    -+check_verify_failure 'detect invalid header entry' \
    -+	'^error:.* extraHeaderBodyNewline:'
    ++test_expect_success \
    ++    'allow extra newlines at start of body' \
    ++    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
      
      ############################################################
      # 24. create valid tag
10:  e38feefd3f8 !  8:  fa04664f7f1 mktag doc: update to explain why to use this
    @@ Documentation/git-mktag.txt: SYNOPSIS
     +Reads a tag contents on standard input and creates a tag object. The
     +output is the new tag's <object> identifier.
     +
    -+This command accepts a subset of what linkgit:git-hash-object[1] would
    -+accept with `-t tag --stdin`. I.e. both of these work:
    ++This command is mostly equivalent to linkgit:git-hash-object[1]
    ++invoked with `-t tag -w --stdin`. I.e. both of these will create and
    ++write a tag found in `my-tag`:
     +
     +    git mktag <my-tag
    -+    git hash-object -t tag --stdin <my-tag
    ++    git hash-object -t tag -w --stdin <my-tag
     +
    -+The difference between the two is that mktag does the equivalent of a
    -+linkgit:git-fsck(1) check on its input, and furthermore disallows some
    -+thing linkgit:git-hash-object[1] would pass, e.g. extra headers in the
    -+object before the message.
    ++The difference is that mktag will die before writing the tag if the
    ++tag doesn't pass a linkgit:git-fsck[1] check.
    ++
    ++The "fsck" check done mktag is is stricter than what
    ++linkgit:git-fsck[1] would run by default in that all `fsck.<msg-id>`
    ++messages are promoted from warnings to errors (so e.g. a missing
    ++"tagger" line is an error). Extra headers in the object are also an
    ++error under mktag, but ignored by linkgit:git-fsck[1].
      
      Tag Format
      ----------
    @@ Documentation/git-mktag.txt: exists, is separated by a blank line from the heade
      message part may contain a signature that Git itself doesn't
      care about, but that can be verified with gpg.
      
    -+HISTORY
    -+-------
    -+
    -+In versions of Git before v2.30.0 the "mktag" command's validation
    -+logic was subtly different than that of linkgit:git-fsck[1]. It is now
    -+a strict superset of linkgit:git-fsck[1]'s validation logic.
    -+
     +SEE ALSO
     +--------
     +linkgit:git-hash-object[1],
 -:  ----------- >  9:  30eff9170fb fsck: make fsck_config() re-usable
 -:  ----------- > 10:  11139ec2b8d mktag: allow turning off fsck.extraHeaderEntry
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 01/10] mktag doc: say <hash> not <sha1>
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
  2020-12-01 10:08             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 02/10] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
                               ` (8 subsequent siblings)
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the "mktag" documentation to refer to the input hash as just
"hash", not "sha1". This command has supported SHA-256 for a while
now.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index fa6a7561236..a158428eb9f 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -23,7 +23,7 @@ Tag Format
 A tag signature file, to be fed to this command's standard input,
 has a very simple fixed format: four lines of
 
-  object <sha1>
+  object <hash>
   type <typename>
   tag <tagname>
   tagger <tagger>
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 02/10] mktag: use default strbuf_read() hint
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (2 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 01/10] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 03/10] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
                               ` (7 subsequent siblings)
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the hardcoded hint of 2^12 to 0. The default strbuf hint is
perfectly fine here, and the only reason we were hardcoding it is
because it survived migration from a pre-strbuf fixed-sized buffer.

See fd17f5b5f77 (Replace all read_fd use with strbuf_read, and get rid
of it., 2007-09-10) for that migration.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4982d3a93ef..ff7ac8e0e5d 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,7 +161,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 4096) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0) {
 		die_errno("could not read from stdin");
 	}
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 03/10] mktag: remove redundant braces in one-line body "if"
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (3 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 02/10] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 04/10] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
                               ` (6 subsequent siblings)
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

This minor stylistic churn is usually something we'd avoid, but if we
don't do this then the file after changes in subsequent commits will
only have this minor style inconsistency, so let's change this while
we're at it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index ff7ac8e0e5d..97ca5f28b1b 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,9 +161,8 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 0) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
-	}
 
 	/* Verify it for some basic sanity: it needs to start with
 	   "object <sha1>\ntype\ntagger " */
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 04/10] mktag tests: don't needlessly use a subshell
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (4 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 03/10] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 05/10] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
                               ` (5 subsequent siblings)
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The use of a subshell dates back to e9b20943b77 (t/t3800: do not use a
temporary file to hold expected result., 2008-01-04). It's not needed
anymore, if it ever was.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index d696aa4e52e..0e411e3c45f 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -14,7 +14,7 @@ test_description='git mktag: tag object verify test'
 check_verify_failure () {
 	expect="$2"
 	test_expect_success "$1" '
-		( test_must_fail git mktag <tag.sig 2>message ) &&
+		test_must_fail git mktag <tag.sig 2>message &&
 		grep "$expect" message
 	'
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 05/10] mktag tests: remove needless SHA-1 hardcoding
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (5 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 04/10] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 06/10] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
                               ` (4 subsequent siblings)
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the tests amended in acb49d1cc8b (t3800: make hash-size
independent, 2019-08-18) even more to make them independent of either
SHA-1 or SHA-256.

Some of these tests were failing for the wrong reasons. The first one
being modified here would fail because the line starts with "xxxxxx"
instead of "object", the rest of the line doesn't matter.

Let's just put a valid hash on the rest of the line anyway to narrow
the test down for just the s/object/xxxxxx/ case.

The second one being modified here would fail under
GIT_TEST_DEFAULT_HASH=sha256 because <some sha-1 length garbage> is an
invalid SHA-256, but we should really be testing <some sha-256 length
garbage> when under SHA-256.

This doesn't really matter since we should be able to trust other
parts of the code to validate things in the 0-9a-f range, but let's
keep it for good measure.

There's a later test which tests an invalid SHA which looks like a
valid one, to stress the "We refuse to tag something we can't
verify[...]" logic in mktag.c.

But here we're testing for a SHA-length string which contains
characters outside of the /[0-9a-f]/i set.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0e411e3c45f..a22a0954d5e 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -43,7 +43,7 @@ check_verify_failure 'Tag object length check' \
 #  2. object line label check
 
 cat >tag.sig <<EOF
-xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
+xxxxxx $head
 type tag
 tag mytag
 tagger . <> 0 +0000
@@ -53,10 +53,10 @@ EOF
 check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
 
 ############################################################
-#  3. object line SHA1 check
+#  3. object line hash check
 
 cat >tag.sig <<EOF
-object zz9e9b33986b1c2670fff52c5067603117b3e895
+object $(echo $head | tr 0-9a-f z)
 type tag
 tag mytag
 tagger . <> 0 +0000
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 06/10] mktag tests: improve verify_object() test coverage
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (6 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 05/10] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 07/10] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
                               ` (3 subsequent siblings)
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The verify_object() function in "mktag.c" is tasked with ensuring that
our tag refers to a valid object.

The existing test for this might fail because it was also testing that
"type taggg" didn't refer to a valid object type (it should be "type
tag"), or because we referred to a valid object but got the type
wrong.

Let's split these tests up, so we're testing all combinations of a
non-existing object and in invalid/wrong "type" lines.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index a22a0954d5e..9ae1b0bb0af 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -125,19 +125,52 @@ check_verify_failure '"type" line type-name length check' \
 	'^error: char.*: type too long$'
 
 ############################################################
-#  9. verify object (SHA1/type) check
+#  9. verify object (hash/type) check
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
+type tag
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
+	'^error: char7: could not verify object.*$'
+
+cat >tag.sig <<EOF
+object $head
 type tagggg
 tag mytag
 tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure 'verify object (SHA1/type) check' \
+check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
+	'^fatal: invalid object type'
+
+cat >tag.sig <<EOF
+object $(test_oid deadbeef)
+type tagggg
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
 	'^error: char7: could not verify object.*$'
 
+cat >tag.sig <<EOF
+object $head
+type tree
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
+	'^error: char7: could not verify object'
+
 ############################################################
 # 10. verify tag-name check
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 07/10] mktag: use fsck instead of custom verify_tag()
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (7 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 06/10] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 08/10] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
                               ` (2 subsequent siblings)
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the validation logic in "mktag" to use fsck's fsck_tag()
instead of its own custom parser. Curiously the logic for both dates
back to the same commit[1]. Let's unify them so we're not maintaining
two sets functions to verify that a tag is OK.

The behavior of fsck_tag() and the old "mktag" code being removed here
is different in few aspects.

I think it makes sense to remove some of those checks, namely:

 A. fsck only cares that the timezone matches [-+][0-9]{4}. The mktag
    code disallowed values larger than 1400.

    Yes there's currently no timezone with a greater offset[2], but
    since we allow any number of non-offical timezones (e.g. +1234)
    passing this through seems fine. Git also won't break in the
    future if e.g. French Polynesia decides it needs to outdo the Line
    Islands when it comes to timezone extravagance.

 B. fsck allows missing author names such as "tagger <email>", mktag
    wouldn't, but would allow e.g. "tagger [2 spaces] <email>" (but
    not "tagger [1 space] <email>"). Now we allow all of these.

 C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
    allows it.

In some ways fsck_tag() is stricter than "mktag" was, namely:

 D. fsck disallows zero-padded dates, but mktag didn't care. So
    e.g. the timestamp "0000000000 +0000" produces an error now. A
    test in "t1006-cat-file.sh" relied on this, it's been changed to
    use "hash-object" (without fsck) instead.

There was one check I deemed worth keeping by porting it over to
fsck_tag():

 E. "mktag" did not allow any custom headers, and by extension (as an
    empty commit is allowed) also forbade an extra stray trailing
    newline after the headers it knew about.

    Add a new check in the "ignore" category to fsck and use it. This
    somewhat abuses the facility added in efaba7cc77f (fsck:
    optionally ignore specific fsck issues completely, 2015-06-22).

    This is somewhat of hack, but probably the least invasive change
    we can make here. The fsck command will shuffle these categories
    around, e.g. under --strict the "info" becomes a "warn" and "warn"
    becomes "error". Existing users of fsck's (and others,
    e.g. index-pack) --strict option rely on this.

    So we need to put something into a category that'll be ignored by
    all existing users of the API. Pretending that
    fsck.extraHeaderEntry=error ("ignore" by default) was set serves
    to do this for us.

1. ec4465adb38 (Add "tag" objects that can be used to sign other
   objects., 2005-04-25)

2. https://en.wikipedia.org/wiki/List_of_UTC_time_offsets

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c     | 196 +++++++++++---------------------------------
 fsck.c              |  32 +++++++-
 fsck.h              |   9 ++
 t/t1006-cat-file.sh |   2 +-
 t/t3800-mktag.sh    |  79 +++++++++++-------
 5 files changed, 137 insertions(+), 181 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 97ca5f28b1b..5765cde0032 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -2,160 +2,60 @@
 #include "tag.h"
 #include "replace-object.h"
 #include "object-store.h"
+#include "fsck.h"
 
-/*
- * A signature file has a very simple fixed format: four lines
- * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
- * "tagger <committer>", followed by a blank line, a free-form tag
- * message and a signature block that git itself doesn't care about,
- * but that can be verified with gpg or similar.
- *
- * The first four lines are guaranteed to be at least 83 bytes:
- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
- * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
- * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
- * the shortest possible tagger-line.
- */
-
-/*
- * We refuse to tag something we can't verify. Just because.
- */
-static int verify_object(const struct object_id *oid, const char *expected_type)
+static int mktag_fsck_error_func(struct fsck_options *o,
+				 const struct object_id *oid,
+				 enum object_type object_type,
+				 int msg_type, const char *message)
 {
-	int ret = -1;
-	enum object_type type;
-	unsigned long size;
-	void *buffer = read_object_file(oid, &type, &size);
-	const struct object_id *repl = lookup_replace_object(the_repository, oid);
-
-	if (buffer) {
-		if (type == type_from_string(expected_type)) {
-			ret = check_object_signature(the_repository, repl,
-						     buffer, size,
-						     expected_type);
-		}
-		free(buffer);
+	switch (msg_type) {
+	case FSCK_WARN:
+	case FSCK_ERROR:
+		/*
+		 * We treat both warnings and errors as errors, things
+		 * like missing "tagger" lines are "only" warnings
+		 * under fsck, we've always considered them an error.
+		 */
+		fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message);
+		return 1;
+	default:
+		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
+		    msg_type);
 	}
-	return ret;
 }
 
-static int verify_tag(char *buffer, unsigned long size)
+static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 {
-	int typelen;
-	char type[20];
-	struct object_id oid;
-	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
-	size_t len;
-
-	if (size < 84)
-		return error("wanna fool me ? you obviously got the size wrong !");
-
-	buffer[size] = 0;
-
-	/* Verify object line */
-	object = buffer;
-	if (memcmp(object, "object ", 7))
-		return error("char%d: does not start with \"object \"", 0);
-
-	if (parse_oid_hex(object + 7, &oid, &p))
-		return error("char%d: could not get SHA1 hash", 7);
-
-	/* Verify type line */
-	type_line = p + 1;
-	if (memcmp(type_line - 1, "\ntype ", 6))
-		return error("char%d: could not find \"\\ntype \"", 47);
-
-	/* Verify tag-line */
-	tag_line = strchr(type_line, '\n');
-	if (!tag_line)
-		return error("char%"PRIuMAX": could not find next \"\\n\"",
-				(uintmax_t) (type_line - buffer));
-	tag_line++;
-	if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
-		return error("char%"PRIuMAX": no \"tag \" found",
-				(uintmax_t) (tag_line - buffer));
-
-	/* Get the actual type */
-	typelen = tag_line - type_line - strlen("type \n");
-	if (typelen >= sizeof(type))
-		return error("char%"PRIuMAX": type too long",
-				(uintmax_t) (type_line+5 - buffer));
-
-	memcpy(type, type_line+5, typelen);
-	type[typelen] = 0;
-
-	/* Verify that the object matches */
-	if (verify_object(&oid, type))
-		return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));
-
-	/* Verify the tag-name: we don't allow control characters or spaces in it */
-	tag_line += 4;
-	for (;;) {
-		unsigned char c = *tag_line++;
-		if (c == '\n')
-			break;
-		if (c > ' ')
-			continue;
-		return error("char%"PRIuMAX": could not verify tag name",
-				(uintmax_t) (tag_line - buffer));
-	}
-
-	/* Verify the tagger line */
-	tagger_line = tag_line;
-
-	if (memcmp(tagger_line, "tagger ", 7))
-		return error("char%"PRIuMAX": could not find \"tagger \"",
-			(uintmax_t) (tagger_line - buffer));
-
-	/*
-	 * Check for correct form for name and email
-	 * i.e. " <" followed by "> " on _this_ line
-	 * No angle brackets within the name or email address fields.
-	 * No spaces within the email address field.
-	 */
-	tagger_line += 7;
-	if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
-		strpbrk(tagger_line, "<>\n") != lb+1 ||
-		strpbrk(lb+2, "><\n ") != rb)
-		return error("char%"PRIuMAX": malformed tagger field",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* Check for author name, at least one character, space is acceptable */
-	if (lb == tagger_line)
-		return error("char%"PRIuMAX": missing tagger name",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* timestamp, 1 or more digits followed by space */
-	tagger_line = rb + 2;
-	if (!(len = strspn(tagger_line, "0123456789")))
-		return error("char%"PRIuMAX": missing tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += len;
-	if (*tagger_line != ' ')
-		return error("char%"PRIuMAX": malformed tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line++;
-
-	/* timezone, 5 digits [+-]hhmm, max. 1400 */
-	if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
-	      strspn(tagger_line+1, "0123456789") == 4 &&
-	      tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
-		return error("char%"PRIuMAX": malformed tag timezone",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += 6;
-
-	/* Verify the blank line separating the header from the body */
-	if (*tagger_line != '\n')
-		return error("char%"PRIuMAX": trailing garbage in tag header",
-			(uintmax_t) (tagger_line - buffer));
+	int ret;
+	enum object_type type;
+	unsigned long size;
+	void *buffer;
+	const struct object_id *repl;
+
+	buffer = read_object_file(tagged_oid, &type, &size);
+	if (!buffer)
+		die("could not read tagged object '%s'\n",
+		    oid_to_hex(tagged_oid));
+	if (type != *tagged_type)
+		die("object '%s' tagged as '%s', but is a '%s' type\n",
+		    oid_to_hex(tagged_oid),
+		    type_name(*tagged_type), type_name(type));
+
+	repl = lookup_replace_object(the_repository, tagged_oid);
+	ret = check_object_signature(the_repository, repl,
+				     buffer, size, type_name(*tagged_type));
+	free(buffer);
 
-	/* The actual stuff afterwards we don't care about.. */
-	return 0;
+	return ret;
 }
 
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	struct strbuf buf = STRBUF_INIT;
+	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
+	struct object_id tagged_oid;
+	int tagged_type;
 	struct object_id result;
 
 	if (argc != 1)
@@ -164,10 +64,14 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
 
-	/* Verify it for some basic sanity: it needs to start with
-	   "object <sha1>\ntype\ntagger " */
-	if (verify_tag(buf.buf, buf.len) < 0)
-		die("invalid tag signature file");
+	fsck_options.error_func = mktag_fsck_error_func;
+	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
+	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
+				&tagged_oid, &tagged_type))
+		die("tag on stdin did not pass our strict fsck check");
+
+	if (verify_object_in_tag(&tagged_oid, &tagged_type))
+		die("tag on stdin did not refer to a valid object");
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
 		die("unable to write tag file");
diff --git a/fsck.c b/fsck.c
index f82e2fe9e30..bed5e20e03b 100644
--- a/fsck.c
+++ b/fsck.c
@@ -80,7 +80,9 @@ static struct oidset gitmodules_done = OIDSET_INIT;
 	/* infos (reported as warnings, but ignored by default) */ \
 	FUNC(GITMODULES_PARSE, INFO) \
 	FUNC(BAD_TAG_NAME, INFO) \
-	FUNC(MISSING_TAGGER_ENTRY, INFO)
+	FUNC(MISSING_TAGGER_ENTRY, INFO) \
+	/* ignored (elevated when requested) */ \
+	FUNC(EXTRA_HEADER_ENTRY, IGNORE)
 
 #define MSG_ID(id, msg_type) FSCK_MSG_##id,
 enum fsck_msg_id {
@@ -911,6 +913,16 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		    unsigned long size, struct fsck_options *options)
 {
 	struct object_id tagged_oid;
+	int tagged_type;
+	return fsck_tag_standalone(oid, buffer, size, options, &tagged_oid,
+				   &tagged_type);
+}
+
+int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+			unsigned long size, struct fsck_options *options,
+			struct object_id *tagged_oid,
+			int *tagged_type)
+{
 	int ret = 0;
 	char *eol;
 	struct strbuf sb = STRBUF_INIT;
@@ -924,7 +936,7 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
 		goto done;
 	}
-	if (parse_oid_hex(buffer, &tagged_oid, &p) || *p != '\n') {
+	if (parse_oid_hex(buffer, tagged_oid, &p) || *p != '\n') {
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
 		if (ret)
 			goto done;
@@ -940,7 +952,8 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
 		goto done;
 	}
-	if (type_from_string_gently(buffer, eol - buffer, 1) < 0)
+	*tagged_type = type_from_string_gently(buffer, eol - buffer, 1);
+	if (*tagged_type < 0)
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
 	if (ret)
 		goto done;
@@ -975,6 +988,19 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 	else
 		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
 
+	if (!starts_with(buffer, "\n")) {
+		/*
+		 * The verify_headers() check will allow
+		 * e.g. "[...]tagger <tagger>\nsome
+		 * garbage\n\nmessage" to pass, thinking "some
+		 * garbage" could be a custom header. E.g. "mktag"
+		 * doesn't want any unknown headers.
+		 */
+		ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
+		if (ret)
+			goto done;
+	}
+
 done:
 	strbuf_release(&sb);
 	return ret;
diff --git a/fsck.h b/fsck.h
index 69cf715e798..29ee4c45e87 100644
--- a/fsck.h
+++ b/fsck.h
@@ -62,6 +62,15 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options);
 int fsck_object(struct object *obj, void *data, unsigned long size,
 	struct fsck_options *options);
 
+/*
+ * fsck a tag, and pass info about it back to the caller. This is
+ * exposed fsck_object() internals for git-mktag(1).
+ */
+int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+			unsigned long size, struct fsck_options *options,
+			struct object_id *tagged_oid,
+			int *tag_type);
+
 /*
  * Some fsck checks are context-dependent, and may end up queued; run this
  * after completing all fsck_object() calls in order to resolve any remaining
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 2f501d2dc94..5d2dc99b74a 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -166,7 +166,7 @@ tag_content="$tag_header_without_timestamp 0000000000 +0000
 
 $tag_description"
 
-tag_sha1=$(echo_without_newline "$tag_content" | git mktag)
+tag_sha1=$(echo_without_newline "$tag_content" | git hash-object -t tag --stdin -w)
 tag_size=$(strlen "$tag_content")
 
 run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" 1
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 9ae1b0bb0af..19b3c1bca9c 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -37,7 +37,7 @@ too short for a tag
 EOF
 
 check_verify_failure 'Tag object length check' \
-	'^error: .*size wrong.*$'
+	'^error:.* missingObject:'
 
 ############################################################
 #  2. object line label check
@@ -50,7 +50,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
+check_verify_failure '"object" line label check' '^error:.* missingObject:'
 
 ############################################################
 #  3. object line hash check
@@ -63,7 +63,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
+check_verify_failure '"object" line check' '^error:.* badObjectSha1:'
 
 ############################################################
 #  4. type line label check
@@ -76,7 +76,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error:.* missingTypeEntry:'
 
 ############################################################
 #  5. type line eol check
@@ -84,7 +84,7 @@ check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
 echo "object $head" >tag.sig
 printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
 
-check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error:.* unterminatedHeader:'
 
 ############################################################
 #  6. tag line label check #1
@@ -98,7 +98,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure '"tag" line label check #1' \
-	'^error: char.*: no "tag " found$'
+	'^error:.* missingTagEntry:'
 
 ############################################################
 #  7. tag line label check #2
@@ -110,7 +110,7 @@ tag
 EOF
 
 check_verify_failure '"tag" line label check #2' \
-	'^error: char.*: no "tag " found$'
+	'^error:.* badType:'
 
 ############################################################
 #  8. type line type-name length check
@@ -122,7 +122,7 @@ tag mytag
 EOF
 
 check_verify_failure '"type" line type-name length check' \
-	'^error: char.*: type too long$'
+	'^error:.* badType:'
 
 ############################################################
 #  9. verify object (hash/type) check
@@ -136,7 +136,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
-	'^error: char7: could not verify object.*$'
+	'^fatal: could not read tagged object'
 
 cat >tag.sig <<EOF
 object $head
@@ -147,7 +147,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
-	'^fatal: invalid object type'
+	'^error:.* badType:'
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
@@ -158,7 +158,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
-	'^error: char7: could not verify object.*$'
+	'^error:.* badType:'
 
 cat >tag.sig <<EOF
 object $head
@@ -169,7 +169,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
-	'^error: char7: could not verify object'
+	'^fatal: object.*tagged as.*tree.*but is.*commit'
 
 ############################################################
 # 10. verify tag-name check
@@ -183,7 +183,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error: char.*: could not verify tag name$'
+	'^error:.* badTagName:'
 
 ############################################################
 # 11. tagger line label check #1
@@ -197,7 +197,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error: char.*: could not find "tagger "$'
+	'^error:.* missingTaggerEntry:'
 
 ############################################################
 # 12. tagger line label check #2
@@ -212,10 +212,10 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error: char.*: could not find "tagger "$'
+	'^error:.* missingTaggerEntry:'
 
 ############################################################
-# 13. disallow missing tag author name
+# 13. allow missing tag author name like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -226,8 +226,9 @@ tagger  <> 0 +0000
 This is filler
 EOF
 
-check_verify_failure 'disallow missing tag author name' \
-	'^error: char.*: missing tagger name$'
+test_expect_success 'allow missing tag author name' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 14. disallow missing tag author name
@@ -242,7 +243,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error: char.*: malformed tagger field$'
+	'^error:.* badEmail:'
 
 ############################################################
 # 15. allow empty tag email
@@ -260,7 +261,7 @@ test_expect_success \
     'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
 
 ############################################################
-# 16. disallow spaces in tag email
+# 16. allow spaces in tag email like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -270,8 +271,9 @@ tagger T A Gger <tag ger@example.com> 0 +0000
 
 EOF
 
-check_verify_failure 'disallow spaces in tag email' \
-	'^error: char.*: malformed tagger field$'
+test_expect_success 'allow spaces in tag email like fsck' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 17. disallow missing tag timestamp
@@ -285,7 +287,7 @@ tagger T A Gger <tagger@example.com>__
 EOF
 
 check_verify_failure 'disallow missing tag timestamp' \
-	'^error: char.*: missing tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 18. detect invalid tag timestamp1
@@ -299,7 +301,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
 EOF
 
 check_verify_failure 'detect invalid tag timestamp1' \
-	'^error: char.*: missing tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 19. detect invalid tag timestamp2
@@ -313,7 +315,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
 EOF
 
 check_verify_failure 'detect invalid tag timestamp2' \
-	'^error: char.*: malformed tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 20. detect invalid tag timezone1
@@ -327,7 +329,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
 EOF
 
 check_verify_failure 'detect invalid tag timezone1' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 ############################################################
 # 21. detect invalid tag timezone2
@@ -341,10 +343,10 @@ tagger T A Gger <tagger@example.com> 1206478233 +  30
 EOF
 
 check_verify_failure 'detect invalid tag timezone2' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 ############################################################
-# 22. detect invalid tag timezone3
+# 22. allow invalid tag timezone3 (the maximum is -1200/+1400)
 
 cat >tag.sig <<EOF
 object $head
@@ -354,8 +356,9 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
 
 EOF
 
-check_verify_failure 'detect invalid tag timezone3' \
-	'^error: char.*: malformed tag timezone$'
+test_expect_success 'allow invalid tag timezone' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 23. detect invalid header entry
@@ -370,7 +373,21 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error: char.*: trailing garbage in tag header$'
+	'^error:.* extraHeaderEntry:'
+
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+
+
+this line comes after an extra newline
+EOF
+
+test_expect_success \
+    'allow extra newlines at start of body' \
+    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
 
 ############################################################
 # 24. create valid tag
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 08/10] mktag doc: update to explain why to use this
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (8 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 07/10] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 09/10] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 10/10] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the mktag documentation to compare itself to the similar
"hash-object -t tag" command. Before this someone reading the
documentation wouldn't have much of an idea what the difference
was.

Let's make it clear that it's to do with slightly different fsck
validation logic, and cross-link the "mktag" and "hash-object"
documentation to aid discover-ability.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-hash-object.txt |  4 ++++
 Documentation/git-mktag.txt       | 27 +++++++++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index df9e2c58bdb..c535661ced8 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -58,6 +58,10 @@ OPTIONS
 	stress-testing Git itself or reproducing characteristics of corrupt or
 	bogus objects encountered in the wild.
 
+SEE ALSO
+--------
+linkgit:git-mktag[1]
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index a158428eb9f..b164ab563bd 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -3,7 +3,7 @@ git-mktag(1)
 
 NAME
 ----
-git-mktag - Creates a tag object
+git-mktag - Creates a tag object with extra validation
 
 
 SYNOPSIS
@@ -13,10 +13,25 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Reads a tag contents on standard input and creates a tag object
-that can also be used to sign other objects.
 
-The output is the new tag's <object> identifier.
+Reads a tag contents on standard input and creates a tag object. The
+output is the new tag's <object> identifier.
+
+This command is mostly equivalent to linkgit:git-hash-object[1]
+invoked with `-t tag -w --stdin`. I.e. both of these will create and
+write a tag found in `my-tag`:
+
+    git mktag <my-tag
+    git hash-object -t tag -w --stdin <my-tag
+
+The difference is that mktag will die before writing the tag if the
+tag doesn't pass a linkgit:git-fsck[1] check.
+
+The "fsck" check done mktag is is stricter than what
+linkgit:git-fsck[1] would run by default in that all `fsck.<msg-id>`
+messages are promoted from warnings to errors (so e.g. a missing
+"tagger" line is an error). Extra headers in the object are also an
+error under mktag, but ignored by linkgit:git-fsck[1].
 
 Tag Format
 ----------
@@ -34,6 +49,10 @@ exists, is separated by a blank line from the header.  The
 message part may contain a signature that Git itself doesn't
 care about, but that can be verified with gpg.
 
+SEE ALSO
+--------
+linkgit:git-hash-object[1],
+
 GIT
 ---
 Part of the linkgit:git[1] suite
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 09/10] fsck: make fsck_config() re-usable
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (9 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 08/10] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  2020-12-09 20:01             ` [PATCH v3 10/10] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Move the fsck_config() function from builtin/fsck.c to fsck.[ch]. This
allows for re-using it in other tools that expose fsck logic and want
to support its configuration variables.

A logical continuation of this change would be to use a common
function for all of {fetch,receive}.fsck.* and fsck.*. See
5d477a334a6 (fsck (receive-pack): allow demoting errors to warnings,
2015-06-22) and my own 1362df0d413 (fetch: implement fetch.fsck.*,
2018-07-27) for the relevant code.

However, those routines want to not parse the fsck.skipList into OIDs,
but rather pass them along with the --strict option to another
process. It would be possible to refactor that whole thing so we
support e.g. a "fetch." prefix, then just keep track of the skiplist
as a filename instead of parsing it, and learn to spew that all out
from our internal structures into something we can append to the
--strict option.

But instead I'm planning to re-use this in "mktag", which'll just
re-use these "fsck.*" variables as-is.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/fsck.c | 20 +-------------------
 fsck.c         | 25 +++++++++++++++++++++++++
 fsck.h         |  7 +++++++
 3 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index fbf26cafcfd..821e7798c70 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -73,25 +73,7 @@ static const char *printable_type(const struct object_id *oid,
 
 static int fsck_config(const char *var, const char *value, void *cb)
 {
-	if (strcmp(var, "fsck.skiplist") == 0) {
-		const char *path;
-		struct strbuf sb = STRBUF_INIT;
-
-		if (git_config_pathname(&path, var, value))
-			return 1;
-		strbuf_addf(&sb, "skiplist=%s", path);
-		free((char *)path);
-		fsck_set_msg_types(&fsck_obj_options, sb.buf);
-		strbuf_release(&sb);
-		return 0;
-	}
-
-	if (skip_prefix(var, "fsck.", &var)) {
-		fsck_set_msg_type(&fsck_obj_options, var, value);
-		return 0;
-	}
-
-	return git_default_config(var, value, cb);
+	return fsck_config_internal(var, value, cb, &fsck_obj_options);
 }
 
 static int objerror(struct object *obj, const char *err)
diff --git a/fsck.c b/fsck.c
index bed5e20e03b..9067a290a2e 100644
--- a/fsck.c
+++ b/fsck.c
@@ -1310,3 +1310,28 @@ int fsck_finish(struct fsck_options *options)
 	oidset_clear(&gitmodules_done);
 	return ret;
 }
+
+int fsck_config_internal(const char *var, const char *value, void *cb,
+			 struct fsck_options *options)
+{
+	if (strcmp(var, "fsck.skiplist") == 0) {
+		const char *path;
+		struct strbuf sb = STRBUF_INIT;
+
+		if (git_config_pathname(&path, var, value))
+			return 1;
+		strbuf_addf(&sb, "skiplist=%s", path);
+		free((char *)path);
+		fsck_set_msg_types(options, sb.buf);
+		strbuf_release(&sb);
+		return 0;
+	}
+
+	if (skip_prefix(var, "fsck.", &var)) {
+		fsck_set_msg_type(options, var, value);
+		return 0;
+	}
+
+	return git_default_config(var, value, cb);
+}
+
diff --git a/fsck.h b/fsck.h
index 29ee4c45e87..423c467feb7 100644
--- a/fsck.h
+++ b/fsck.h
@@ -103,4 +103,11 @@ void fsck_put_object_name(struct fsck_options *options,
 const char *fsck_describe_object(struct fsck_options *options,
 				 const struct object_id *oid);
 
+/*
+ * git_config() callback for use by fsck-y tools that want to support
+ * fsck.<msg> fsck.skipList etc.
+ */
+int fsck_config_internal(const char *var, const char *value, void *cb,
+			 struct fsck_options *options);
+
 #endif
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v3 10/10] mktag: allow turning off fsck.extraHeaderEntry
  2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
                               ` (10 preceding siblings ...)
  2020-12-09 20:01             ` [PATCH v3 09/10] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
@ 2020-12-09 20:01             ` Ævar Arnfjörð Bjarmason
  11 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-09 20:01 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

In earlier commits mktag learned to use the fsck machinery, at which
point we needed to add fsck.extraHeaderEntry so it could be as strict
about extra headers as it's been ever since it was implemented.

But it's not nice to need to switch away from "mktag" to "hash-object"
+ manual "fsck" just because you'd like to have an extra header. So
let's support turning it off by getting "fsck.*" variables from the
config.

Pedantically speaking it's still not possible to make "mktag" behave
just like "hash-object -t tag" does, since we're unconditionally going
to check the referenced object in verify_object_in_tag(), which is our
own check, and not one that exists in fsck.c.

But the spirit of "this works like fsck" is preserved, in that if you
created such a tag with "hash-object" and did a full "fsck" on the
repository it would also error out about that invalid object, it just
wouldn't emit the same message as fsck does.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt |  9 +++++++--
 builtin/mktag.c             | 11 ++++++++++-
 t/t3800-mktag.sh            | 14 ++++++++++++++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index b164ab563bd..e1506dde561 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -30,8 +30,13 @@ tag doesn't pass a linkgit:git-fsck[1] check.
 The "fsck" check done mktag is is stricter than what
 linkgit:git-fsck[1] would run by default in that all `fsck.<msg-id>`
 messages are promoted from warnings to errors (so e.g. a missing
-"tagger" line is an error). Extra headers in the object are also an
-error under mktag, but ignored by linkgit:git-fsck[1].
+"tagger" line is an error).
+
+Extra headers in the object are also an error under mktag, but ignored
+by linkgit:git-fsck[1]. This extra check can be turned off by setting
+the appropriate `fsck.<msg-id>` varible:
+
+    git -c fsck.extraHeaderEntry=ignore mktag <my-tag-with-headers
 
 Tag Format
 ----------
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 5765cde0032..c1398ccf133 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -3,6 +3,14 @@
 #include "replace-object.h"
 #include "object-store.h"
 #include "fsck.h"
+#include "config.h"
+
+static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
+
+static int mktag_config(const char *var, const char *value, void *cb)
+{
+	return fsck_config_internal(var, value, cb, &fsck_options);
+}
 
 static int mktag_fsck_error_func(struct fsck_options *o,
 				 const struct object_id *oid,
@@ -53,7 +61,6 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	struct strbuf buf = STRBUF_INIT;
-	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 	struct object_id tagged_oid;
 	int tagged_type;
 	struct object_id result;
@@ -66,6 +73,8 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 
 	fsck_options.error_func = mktag_fsck_error_func;
 	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
+	/* config might set fsck.extraHeaderEntry=* again */
+	git_config(mktag_config, NULL);
 	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
 				&tagged_oid, &tagged_type))
 		die("tag on stdin did not pass our strict fsck check");
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 19b3c1bca9c..59082e06277 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -375,6 +375,20 @@ EOF
 check_verify_failure 'detect invalid header entry' \
 	'^error:.* extraHeaderEntry:'
 
+test_expect_success 'invalid header entry config & fsck' '
+	test_must_fail git mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
+	git fsck &&
+	env GIT_TEST_GETTEXT_POISON=false \
+		git -c fsck.extraHeaderEntry=warn fsck 2>err &&
+	grep "warning .*extraHeaderEntry:" err &&
+	test_must_fail env GIT_TEST_GETTEXT_POISON=false \
+		git -c fsck.extraHeaderEntry=error 2>err fsck &&
+	grep "error .* extraHeaderEntry:" err
+'
+
 cat >tag.sig <<EOF
 object $head
 type commit
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: [PATCH v3 00/10] make "mktag" use fsck_tag()
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
@ 2020-12-09 22:30               ` Junio C Hamano
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                 ` (20 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-09 22:30 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> This version should address all the comments Junio made on v2. Changes:
>
>  * The whole "extra" fsck option is gone, I just didn't realize I
>    could set the new check to "ignore", and then manually promote it.
>
>  * Ejected "mktag: reword write_object_file() error". It was the same
>    phrasing as "git tag" uses, let's just keep it.
>
>  * Clarifications in docs/commit messages
>
>  * There's 2 extra patches at the end now which take the first steps
>    into making "git mktag" more of a normal builtin. It reads fsck.*
>    config variables, so you can turn off that "no extra headers" check
>    through the normal fsck.<msg-id>=ignore config.
>
>    It should also be moved to getopts, and we could make it support
>    --no-strict to have the same idea of error/warning as fsck itself,
>    but that's #leftoverbits, along with moving it to i18n.
>
>    It would be nice to have patches 1-8 merged down if they're deemed
>    ready, and if 9-10 aren't deemed wanted just discard them. I think
>    it makes sense though...

Thanks.  I haven't read the individual patches, but spotted an
obvious "is is" typo in the doc while scanning through the end
result of applying all of them.

 Documentation/git-mktag.txt | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git c/Documentation/git-mktag.txt w/Documentation/git-mktag.txt
index e1506dde56..2c1afedef6 100644
--- c/Documentation/git-mktag.txt
+++ w/Documentation/git-mktag.txt
@@ -27,10 +27,9 @@ write a tag found in `my-tag`:
 The difference is that mktag will die before writing the tag if the
 tag doesn't pass a linkgit:git-fsck[1] check.
 
-The "fsck" check done mktag is is stricter than what
-linkgit:git-fsck[1] would run by default in that all `fsck.<msg-id>`
-messages are promoted from warnings to errors (so e.g. a missing
-"tagger" line is an error).
+The "fsck" check done mktag is stricter than what linkgit:git-fsck[1]
+would run by default in that all `fsck.<msg-id>` messages are promoted
+from warnings to errors (so e.g. a missing "tagger" line is an error).
 
 Extra headers in the object are also an error under mktag, but ignored
 by linkgit:git-fsck[1]. This extra check can be turned off by setting

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

* [PATCH v4 00/20] make "mktag" use fsck_tag() & more
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
  2020-12-09 22:30               ` Junio C Hamano
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23 13:54                 ` Junio C Hamano
                                   ` (24 more replies)
  2020-12-23  1:35               ` [PATCH v4 01/20] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
                                 ` (19 subsequent siblings)
  21 siblings, 25 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

So, when re-rolling this with Junio's small fixup this grew in scope a
bit, but should paradoxically be easier to deal with even though it's
2x the size now. Read on:

Ævar Arnfjörð Bjarmason (20):
  mktag doc: say <hash> not <sha1>
  mktag doc: grammar fix, when exists -> when it exists
  mktag doc: update to explain why to use this
  mktag tests: don't needlessly use a subshell
  mktag tests: remove needless SHA-1 hardcoding
  mktag tests: improve verify_object() test coverage
  mktag tests: don't pipe to stderr needlessly
  mktag tests: don't create "mytag" twice
  mktag tests: stress test whitespace handling
  mktag tests: test "hash-object" compatibility

I re-arranged this series so the doc/test patches for existing
behavior all come first now. There's some new patches there (see
range-diff), but all rather easy-to review fixes or tests for existing
behavior.

  mktag: use default strbuf_read() hint
  mktag: remove redundant braces in one-line body "if"
  mktag: use puts(str) instead of printf("%s\n", str)

Trivial coding style changes, the puts() patch is new.

  mktag: use fsck instead of custom verify_tag()

Still the real meat of the series, unchanged in any meaningful way,
except in (as seen in the range-diff) carrying forward doc/test
changes made earlier.

  fsck: make fsck_config() re-usable
  mktag: allow turning off fsck.extraHeaderEntry

ditto unchanged.

  mktag: allow omitting the header/body \n separator

I discovered a regression in mktag in git since 2008 where it refuses
to accept input without an empty newline separating the body & message
in cases where there's no message.

Now we again accept the same input as hash-object, and with the new
"hash-object" test integration earlier in the series we're confident
that mktag & hash-object do the same thing in all these cases.

  mktag: convert to parse-options
  mktag: mark strings for translation
  mktag: add a --no-strict option

The #leftoverbits I suggested in v3 of converting to parse-options &
doing i18n for mktag, and finally supporting --no-strict so you can
make it behave like "fsck" does in its default mode.

 Documentation/git-hash-object.txt |   4 +
 Documentation/git-mktag.txt       |  42 +++++-
 builtin/fsck.c                    |  20 +--
 builtin/mktag.c                   | 235 +++++++++++-------------------
 fsck.c                            |  59 +++++++-
 fsck.h                            |  16 ++
 parse-options.h                   |   1 +
 t/t1006-cat-file.sh               |   2 +-
 t/t3800-mktag.sh                  | 211 +++++++++++++++++++++------
 9 files changed, 361 insertions(+), 229 deletions(-)

Range-diff:
 1:  aee3f52a47 =  1:  a31c305cfc mktag doc: say <hash> not <sha1>
 -:  ---------- >  2:  81cb4cba5c mktag doc: grammar fix, when exists -> when it exists
 8:  fa04664f7f !  3:  b4bc6f894c mktag doc: update to explain why to use this
    @@ Commit message
         documentation wouldn't have much of an idea what the difference
         was.
     
    -    Let's make it clear that it's to do with slightly different fsck
    -    validation logic, and cross-link the "mktag" and "hash-object"
    -    documentation to aid discover-ability.
    +    Let's allude to our own validation logic, and cross-link the "mktag"
    +    and "hash-object" documentation to aid discover-ability. A follow-up
    +    change to migrate "mktag" to use "fsck" validation will make the part
    +    about validation logic clearer.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ Documentation/git-mktag.txt: SYNOPSIS
     +    git hash-object -t tag -w --stdin <my-tag
     +
     +The difference is that mktag will die before writing the tag if the
    -+tag doesn't pass a linkgit:git-fsck[1] check.
    -+
    -+The "fsck" check done mktag is is stricter than what
    -+linkgit:git-fsck[1] would run by default in that all `fsck.<msg-id>`
    -+messages are promoted from warnings to errors (so e.g. a missing
    -+"tagger" line is an error). Extra headers in the object are also an
    -+error under mktag, but ignored by linkgit:git-fsck[1].
    ++tag doesn't pass a sanity check.
      
      Tag Format
      ----------
 4:  1f06b9c0cf =  4:  acb94e0289 mktag tests: don't needlessly use a subshell
 5:  5d1cb73ca3 =  5:  4ae76ec5e3 mktag tests: remove needless SHA-1 hardcoding
 6:  cf86f4ca37 =  6:  9effb4532b mktag tests: improve verify_object() test coverage
 -:  ---------- >  7:  b81d31a917 mktag tests: don't pipe to stderr needlessly
 -:  ---------- >  8:  11f59718b4 mktag tests: don't create "mytag" twice
 -:  ---------- >  9:  dd6b012b0c mktag tests: stress test whitespace handling
 -:  ---------- > 10:  56c6b562fd mktag tests: test "hash-object" compatibility
 2:  6e98557709 = 11:  1e2e4ec269 mktag: use default strbuf_read() hint
 3:  8e5fe08f15 = 12:  be2ab3edab mktag: remove redundant braces in one-line body "if"
 -:  ---------- > 13:  d8514df970 mktag: use puts(str) instead of printf("%s\n", str)
 7:  5812ee53c9 ! 14:  346d73cc97 mktag: use fsck instead of custom verify_tag()
    @@ Commit message
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    + ## Documentation/git-mktag.txt ##
    +@@ Documentation/git-mktag.txt: write a tag found in `my-tag`:
    +     git hash-object -t tag -w --stdin <my-tag
    + 
    + The difference is that mktag will die before writing the tag if the
    +-tag doesn't pass a sanity check.
    ++tag doesn't pass a linkgit:git-fsck[1] check.
    ++
    ++The "fsck" check done mktag is stricter than what linkgit:git-fsck[1]
    ++would run by default in that all `fsck.<msg-id>` messages are promoted
    ++from warnings to errors (so e.g. a missing "tagger" line is an error).
    ++
    ++Extra headers in the object are also an error under mktag, but ignored
    ++by linkgit:git-fsck[1]
    + 
    + Tag Format
    + ----------
    +
      ## builtin/mktag.c ##
     @@
      #include "tag.h"
    @@ builtin/mktag.c
     +
     +	buffer = read_object_file(tagged_oid, &type, &size);
     +	if (!buffer)
    -+		die("could not read tagged object '%s'\n",
    ++		die("could not read tagged object '%s'",
     +		    oid_to_hex(tagged_oid));
     +	if (type != *tagged_type)
    -+		die("object '%s' tagged as '%s', but is a '%s' type\n",
    ++		die("object '%s' tagged as '%s', but is a '%s' type",
     +		    oid_to_hex(tagged_oid),
     +		    type_name(*tagged_type), type_name(type));
     +
    @@ t/t3800-mktag.sh: tagger  <> 0 +0000
      
     -check_verify_failure 'disallow missing tag author name' \
     -	'^error: char.*: missing tagger name$'
    -+test_expect_success 'allow missing tag author name' '
    -+	git mktag <tag.sig
    -+'
    ++test_expect_mktag_success 'allow missing tag author name'
      
      ############################################################
      # 14. disallow missing tag author name
    @@ t/t3800-mktag.sh: tagger T A Gger <
      
      ############################################################
      # 15. allow empty tag email
    -@@ t/t3800-mktag.sh: test_expect_success \
    -     'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
    +@@ t/t3800-mktag.sh: EOF
    + test_expect_mktag_success 'allow empty tag email'
      
      ############################################################
     -# 16. disallow spaces in tag email
    @@ t/t3800-mktag.sh: tagger T A Gger <tag ger@example.com> 0 +0000
      
     -check_verify_failure 'disallow spaces in tag email' \
     -	'^error: char.*: malformed tagger field$'
    -+test_expect_success 'allow spaces in tag email like fsck' '
    -+	git mktag <tag.sig
    -+'
    ++test_expect_mktag_success 'allow spaces in tag email like fsck'
      
      ############################################################
      # 17. disallow missing tag timestamp
    @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 -1430
      
     -check_verify_failure 'detect invalid tag timezone3' \
     -	'^error: char.*: malformed tag timezone$'
    -+test_expect_success 'allow invalid tag timezone' '
    -+	git mktag <tag.sig
    -+'
    ++test_expect_mktag_success 'allow invalid tag timezone'
      
      ############################################################
      # 23. detect invalid header entry
    @@ t/t3800-mktag.sh: this line should not be here
      check_verify_failure 'detect invalid header entry' \
     -	'^error: char.*: trailing garbage in tag header$'
     +	'^error:.* extraHeaderEntry:'
    -+
    -+cat >tag.sig <<EOF
    -+object $head
    -+type commit
    -+tag mytag
    -+tagger T A Gger <tagger@example.com> 1206478233 -0500
    -+
    -+
    -+this line comes after an extra newline
    -+EOF
    -+
    -+test_expect_success \
    -+    'allow extra newlines at start of body' \
    -+    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
    + 
    + cat >tag.sig <<EOF
    + object $head
    +@@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 -0500$space
    + EOF
    + 
    + check_verify_failure 'extra whitespace at end of headers' \
    +-	'^error: char.*: malformed tag timezone$'
    ++	'^error:.* badTimezone:'
    + 
    + cat >tag.sig <<EOF
    + object $head
    +@@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 -0500
    + EOF
    + 
    + check_verify_failure 'disallow no header / body newline separator' \
    +-	'^error: char.*: trailing garbage in tag header$'
    ++	'^error:.* extraHeaderEntry:'
      
      ############################################################
      # 24. create valid tag
 9:  30eff9170f = 15:  0e7994d8fc fsck: make fsck_config() re-usable
10:  11139ec2b8 ! 16:  5e8046022b mktag: allow turning off fsck.extraHeaderEntry
    @@ Commit message
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Documentation/git-mktag.txt ##
    -@@ Documentation/git-mktag.txt: tag doesn't pass a linkgit:git-fsck[1] check.
    - The "fsck" check done mktag is is stricter than what
    - linkgit:git-fsck[1] would run by default in that all `fsck.<msg-id>`
    - messages are promoted from warnings to errors (so e.g. a missing
    --"tagger" line is an error). Extra headers in the object are also an
    --error under mktag, but ignored by linkgit:git-fsck[1].
    -+"tagger" line is an error).
    -+
    -+Extra headers in the object are also an error under mktag, but ignored
    +@@ Documentation/git-mktag.txt: would run by default in that all `fsck.<msg-id>` messages are promoted
    + from warnings to errors (so e.g. a missing "tagger" line is an error).
    + 
    + Extra headers in the object are also an error under mktag, but ignored
    +-by linkgit:git-fsck[1]
     +by linkgit:git-fsck[1]. This extra check can be turned off by setting
     +the appropriate `fsck.<msg-id>` varible:
     +
 -:  ---------- > 17:  32698e1d00 mktag: allow omitting the header/body \n separator
 -:  ---------- > 18:  b6a22f2f99 mktag: convert to parse-options
 -:  ---------- > 19:  7fc0b81df7 mktag: mark strings for translation
 -:  ---------- > 20:  6fa443d528 mktag: add a --no-strict option
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 01/20] mktag doc: say <hash> not <sha1>
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
  2020-12-09 22:30               ` Junio C Hamano
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:35               ` [PATCH v4 02/20] mktag doc: grammar fix, when exists -> when it exists Ævar Arnfjörð Bjarmason
                                 ` (18 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the "mktag" documentation to refer to the input hash as just
"hash", not "sha1". This command has supported SHA-256 for a while
now.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index fa6a756123..a158428eb9 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -23,7 +23,7 @@ Tag Format
 A tag signature file, to be fed to this command's standard input,
 has a very simple fixed format: four lines of
 
-  object <sha1>
+  object <hash>
   type <typename>
   tag <tagname>
   tagger <tagger>
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 02/20] mktag doc: grammar fix, when exists -> when it exists
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (2 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 01/20] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:35               ` [PATCH v4 03/20] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
                                 ` (17 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Amend the wording of documentation added in 6cfec03680 (mktag:
minimally update the description., 2007-06-10). It makes more sense to
say "when it exists" here, as we're referring to "the message".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index a158428eb9..1b0667e372 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -29,7 +29,7 @@ has a very simple fixed format: four lines of
   tagger <tagger>
 
 followed by some 'optional' free-form message (some tags created
-by older Git may not have `tagger` line).  The message, when
+by older Git may not have `tagger` line).  The message, when it
 exists, is separated by a blank line from the header.  The
 message part may contain a signature that Git itself doesn't
 care about, but that can be verified with gpg.
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 03/20] mktag doc: update to explain why to use this
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (3 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 02/20] mktag doc: grammar fix, when exists -> when it exists Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:57                 ` Junio C Hamano
  2020-12-23  1:35               ` [PATCH v4 04/20] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
                                 ` (16 subsequent siblings)
  21 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the mktag documentation to compare itself to the similar
"hash-object -t tag" command. Before this someone reading the
documentation wouldn't have much of an idea what the difference
was.

Let's allude to our own validation logic, and cross-link the "mktag"
and "hash-object" documentation to aid discover-ability. A follow-up
change to migrate "mktag" to use "fsck" validation will make the part
about validation logic clearer.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-hash-object.txt |  4 ++++
 Documentation/git-mktag.txt       | 21 +++++++++++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.txt
index df9e2c58bd..c535661ced 100644
--- a/Documentation/git-hash-object.txt
+++ b/Documentation/git-hash-object.txt
@@ -58,6 +58,10 @@ OPTIONS
 	stress-testing Git itself or reproducing characteristics of corrupt or
 	bogus objects encountered in the wild.
 
+SEE ALSO
+--------
+linkgit:git-mktag[1]
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 1b0667e372..adc63f6d4e 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -3,7 +3,7 @@ git-mktag(1)
 
 NAME
 ----
-git-mktag - Creates a tag object
+git-mktag - Creates a tag object with extra validation
 
 
 SYNOPSIS
@@ -13,10 +13,19 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Reads a tag contents on standard input and creates a tag object
-that can also be used to sign other objects.
 
-The output is the new tag's <object> identifier.
+Reads a tag contents on standard input and creates a tag object. The
+output is the new tag's <object> identifier.
+
+This command is mostly equivalent to linkgit:git-hash-object[1]
+invoked with `-t tag -w --stdin`. I.e. both of these will create and
+write a tag found in `my-tag`:
+
+    git mktag <my-tag
+    git hash-object -t tag -w --stdin <my-tag
+
+The difference is that mktag will die before writing the tag if the
+tag doesn't pass a sanity check.
 
 Tag Format
 ----------
@@ -34,6 +43,10 @@ exists, is separated by a blank line from the header.  The
 message part may contain a signature that Git itself doesn't
 care about, but that can be verified with gpg.
 
+SEE ALSO
+--------
+linkgit:git-hash-object[1],
+
 GIT
 ---
 Part of the linkgit:git[1] suite
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 04/20] mktag tests: don't needlessly use a subshell
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (4 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 03/20] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:35               ` [PATCH v4 05/20] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
                                 ` (15 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The use of a subshell dates back to e9b20943b77 (t/t3800: do not use a
temporary file to hold expected result., 2008-01-04). It's not needed
anymore, if it ever was.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index d696aa4e52..0e411e3c45 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -14,7 +14,7 @@ test_description='git mktag: tag object verify test'
 check_verify_failure () {
 	expect="$2"
 	test_expect_success "$1" '
-		( test_must_fail git mktag <tag.sig 2>message ) &&
+		test_must_fail git mktag <tag.sig 2>message &&
 		grep "$expect" message
 	'
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 05/20] mktag tests: remove needless SHA-1 hardcoding
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (5 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 04/20] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:35               ` [PATCH v4 06/20] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
                                 ` (14 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the tests amended in acb49d1cc8b (t3800: make hash-size
independent, 2019-08-18) even more to make them independent of either
SHA-1 or SHA-256.

Some of these tests were failing for the wrong reasons. The first one
being modified here would fail because the line starts with "xxxxxx"
instead of "object", the rest of the line doesn't matter.

Let's just put a valid hash on the rest of the line anyway to narrow
the test down for just the s/object/xxxxxx/ case.

The second one being modified here would fail under
GIT_TEST_DEFAULT_HASH=sha256 because <some sha-1 length garbage> is an
invalid SHA-256, but we should really be testing <some sha-256 length
garbage> when under SHA-256.

This doesn't really matter since we should be able to trust other
parts of the code to validate things in the 0-9a-f range, but let's
keep it for good measure.

There's a later test which tests an invalid SHA which looks like a
valid one, to stress the "We refuse to tag something we can't
verify[...]" logic in mktag.c.

But here we're testing for a SHA-length string which contains
characters outside of the /[0-9a-f]/i set.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0e411e3c45..a22a0954d5 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -43,7 +43,7 @@ check_verify_failure 'Tag object length check' \
 #  2. object line label check
 
 cat >tag.sig <<EOF
-xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
+xxxxxx $head
 type tag
 tag mytag
 tagger . <> 0 +0000
@@ -53,10 +53,10 @@ EOF
 check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
 
 ############################################################
-#  3. object line SHA1 check
+#  3. object line hash check
 
 cat >tag.sig <<EOF
-object zz9e9b33986b1c2670fff52c5067603117b3e895
+object $(echo $head | tr 0-9a-f z)
 type tag
 tag mytag
 tagger . <> 0 +0000
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 06/20] mktag tests: improve verify_object() test coverage
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (6 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 05/20] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  2:04                 ` Junio C Hamano
  2020-12-23  1:35               ` [PATCH v4 07/20] mktag tests: don't pipe to stderr needlessly Ævar Arnfjörð Bjarmason
                                 ` (13 subsequent siblings)
  21 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

The verify_object() function in "mktag.c" is tasked with ensuring that
our tag refers to a valid object.

The existing test for this might fail because it was also testing that
"type taggg" didn't refer to a valid object type (it should be "type
tag"), or because we referred to a valid object but got the type
wrong.

Let's split these tests up, so we're testing all combinations of a
non-existing object and in invalid/wrong "type" lines.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index a22a0954d5..9ae1b0bb0a 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -125,19 +125,52 @@ check_verify_failure '"type" line type-name length check' \
 	'^error: char.*: type too long$'
 
 ############################################################
-#  9. verify object (SHA1/type) check
+#  9. verify object (hash/type) check
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
+type tag
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
+	'^error: char7: could not verify object.*$'
+
+cat >tag.sig <<EOF
+object $head
 type tagggg
 tag mytag
 tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure 'verify object (SHA1/type) check' \
+check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
+	'^fatal: invalid object type'
+
+cat >tag.sig <<EOF
+object $(test_oid deadbeef)
+type tagggg
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
 	'^error: char7: could not verify object.*$'
 
+cat >tag.sig <<EOF
+object $head
+type tree
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
+	'^error: char7: could not verify object'
+
 ############################################################
 # 10. verify tag-name check
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 07/20] mktag tests: don't pipe to stderr needlessly
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (7 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 06/20] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  2:10                 ` Junio C Hamano
  2020-12-23  1:35               ` [PATCH v4 08/20] mktag tests: don't create "mytag" twice Ævar Arnfjörð Bjarmason
                                 ` (12 subsequent siblings)
  21 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Remove the piping of stderr to "message" in the valid tag test. This
pattern seems to have been copy/pasted from the failure case in
446c6faec6 (New tests and en-passant modifications to mktag.,
2006-07-29).

Nothing is piped to "message" here, and in the event of the test
failing it only serves to hide the error.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 9ae1b0bb0a..bbd148618e 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -257,7 +257,7 @@ EOF
 
 test_expect_success \
     'allow empty tag email' \
-    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
+    'git mktag <tag.sig >.git/refs/tags/mytag'
 
 ############################################################
 # 16. disallow spaces in tag email
@@ -385,7 +385,7 @@ EOF
 
 test_expect_success \
     'create valid tag' \
-    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
+    'git mktag <tag.sig >.git/refs/tags/mytag'
 
 ############################################################
 # 25. check mytag
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 08/20] mktag tests: don't create "mytag" twice
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (8 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 07/20] mktag tests: don't pipe to stderr needlessly Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  2:18                 ` Junio C Hamano
  2020-12-23  1:35               ` [PATCH v4 09/20] mktag tests: stress test whitespace handling Ævar Arnfjörð Bjarmason
                                 ` (11 subsequent siblings)
  21 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change a test added in e0aaf781f6 (mktag.c: improve verification of
tagger field and tests, 2008-03-27) to not create "mytag", which
should only be created and verified at the end in an earlier test
added in 446c6faec6 (New tests and en-passant modifications to mktag.,
2006-07-29).

While we're at it let's prevent a similar logic error from creeping
into the test by asserting that "mytag" doesn't exist before we create
it. Let's do this by moving the test to use "update-ref", instead of
our own homebrew ad-hoc refstore update.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index bbd148618e..b6dcdbebe6 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -257,7 +257,7 @@ EOF
 
 test_expect_success \
     'allow empty tag email' \
-    'git mktag <tag.sig >.git/refs/tags/mytag'
+    'git mktag <tag.sig'
 
 ############################################################
 # 16. disallow spaces in tag email
@@ -383,16 +383,9 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 
 EOF
 
-test_expect_success \
-    'create valid tag' \
-    'git mktag <tag.sig >.git/refs/tags/mytag'
-
-############################################################
-# 25. check mytag
-
-test_expect_success \
-    'check mytag' \
-    'git tag -l | grep mytag'
-
+test_expect_success 'create valid tag' '
+	git mktag <tag.sig >hash &&
+	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero)
+'
 
 test_done
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 09/20] mktag tests: stress test whitespace handling
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (9 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 08/20] mktag tests: don't create "mytag" twice Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  2:27                 ` Junio C Hamano
  2020-12-23  1:35               ` [PATCH v4 10/20] mktag tests: test "hash-object" compatibility Ævar Arnfjörð Bjarmason
                                 ` (10 subsequent siblings)
  21 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Add tests for various whitespace edge cases around the header/body
boundary, such as two newlines separating the header and body, a space
at the end of the "tagger" line before the header etc.

Add a test showing that we insist that an empty body must be preceded
by an empty line. This test for a long-standing regression which goes
against the command's documented behavior. It'll be addressed in a
follow-up change.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index b6dcdbebe6..f339321be8 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -372,6 +372,54 @@ EOF
 check_verify_failure 'detect invalid header entry' \
 	'^error: char.*: trailing garbage in tag header$'
 
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+
+
+this line comes after an extra newline
+EOF
+
+test_expect_success 'allow extra newlines at start of body' '
+	git mktag <tag.sig
+'
+
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+
+EOF
+
+test_expect_success 'allow extra newlines at end of headers' '
+	git mktag <tag.sig
+'
+
+space=' '
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500$space
+
+EOF
+
+check_verify_failure 'extra whitespace at end of headers' \
+	'^error: char.*: malformed tag timezone$'
+
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+EOF
+
+check_verify_failure 'disallow no header / body newline separator' \
+	'^error: char.*: trailing garbage in tag header$'
+
 ############################################################
 # 24. create valid tag
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 10/20] mktag tests: test "hash-object" compatibility
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (10 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 09/20] mktag tests: stress test whitespace handling Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  2:29                 ` Junio C Hamano
  2020-12-23  1:35               ` [PATCH v4 11/20] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
                                 ` (9 subsequent siblings)
  21 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change all the successful "mktag" tests to test that "hash-object"
produces the same hash for the input, and that fsck passes for
both.

This tests e.g. that "mktag" doesn't trim its input or otherwise munge
it in a way that "hash-object" doesn't.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index f339321be8..c6826762d9 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -19,6 +19,16 @@ check_verify_failure () {
 	'
 }
 
+test_expect_mktag_success() {
+	test_expect_success "$1" '
+		git hash-object -t tag -w --stdin <tag.sig >expected &&
+		git fsck --strict &&
+		git mktag <tag.sig >hash &&
+		git fsck --strict &&
+		test_cmp expected hash
+	'
+}
+
 ###########################################################
 # first create a commit, so we have a valid object/type
 # for the tag.
@@ -255,9 +265,7 @@ tagger T A Gger <> 0 +0000
 
 EOF
 
-test_expect_success \
-    'allow empty tag email' \
-    'git mktag <tag.sig'
+test_expect_mktag_success 'allow empty tag email'
 
 ############################################################
 # 16. disallow spaces in tag email
@@ -382,9 +390,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 this line comes after an extra newline
 EOF
 
-test_expect_success 'allow extra newlines at start of body' '
-	git mktag <tag.sig
-'
+test_expect_mktag_success 'allow extra newlines at start of body'
 
 cat >tag.sig <<EOF
 object $head
@@ -394,9 +400,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 
 EOF
 
-test_expect_success 'allow extra newlines at end of headers' '
-	git mktag <tag.sig
-'
+test_expect_mktag_success 'allow extra newlines at end of headers'
 
 space=' '
 cat >tag.sig <<EOF
@@ -431,8 +435,8 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 
 EOF
 
-test_expect_success 'create valid tag' '
-	git mktag <tag.sig >hash &&
+test_expect_mktag_success 'create valid tag object'
+test_expect_success 'create valid tag name' '
 	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero)
 '
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 11/20] mktag: use default strbuf_read() hint
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (11 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 10/20] mktag tests: test "hash-object" compatibility Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:35               ` [PATCH v4 12/20] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
                                 ` (8 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the hardcoded hint of 2^12 to 0. The default strbuf hint is
perfectly fine here, and the only reason we were hardcoding it is
because it survived migration from a pre-strbuf fixed-sized buffer.

See fd17f5b5f77 (Replace all read_fd use with strbuf_read, and get rid
of it., 2007-09-10) for that migration.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4982d3a93e..ff7ac8e0e5 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,7 +161,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 4096) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0) {
 		die_errno("could not read from stdin");
 	}
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 12/20] mktag: remove redundant braces in one-line body "if"
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (12 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 11/20] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:35               ` [PATCH v4 13/20] mktag: use puts(str) instead of printf("%s\n", str) Ævar Arnfjörð Bjarmason
                                 ` (7 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

This minor stylistic churn is usually something we'd avoid, but if we
don't do this then the file after changes in subsequent commits will
only have this minor style inconsistency, so let's change this while
we're at it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index ff7ac8e0e5..97ca5f28b1 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,9 +161,8 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 0) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
-	}
 
 	/* Verify it for some basic sanity: it needs to start with
 	   "object <sha1>\ntype\ntagger " */
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 13/20] mktag: use puts(str) instead of printf("%s\n", str)
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (13 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 12/20] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:35               ` [PATCH v4 14/20] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
                                 ` (6 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

This introduces no functional change, but refactors the print-out of
the hash at the end to do the same thing with less code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 97ca5f28b1..d89a3c201d 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -173,6 +173,6 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 		die("unable to write tag file");
 
 	strbuf_release(&buf);
-	printf("%s\n", oid_to_hex(&result));
+	puts(oid_to_hex(&result));
 	return 0;
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 14/20] mktag: use fsck instead of custom verify_tag()
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (14 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 13/20] mktag: use puts(str) instead of printf("%s\n", str) Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:35               ` Ævar Arnfjörð Bjarmason
  2020-12-23 13:34                 ` Junio C Hamano
  2020-12-23  1:36               ` [PATCH v4 15/20] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
                                 ` (5 subsequent siblings)
  21 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:35 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change the validation logic in "mktag" to use fsck's fsck_tag()
instead of its own custom parser. Curiously the logic for both dates
back to the same commit[1]. Let's unify them so we're not maintaining
two sets functions to verify that a tag is OK.

The behavior of fsck_tag() and the old "mktag" code being removed here
is different in few aspects.

I think it makes sense to remove some of those checks, namely:

 A. fsck only cares that the timezone matches [-+][0-9]{4}. The mktag
    code disallowed values larger than 1400.

    Yes there's currently no timezone with a greater offset[2], but
    since we allow any number of non-offical timezones (e.g. +1234)
    passing this through seems fine. Git also won't break in the
    future if e.g. French Polynesia decides it needs to outdo the Line
    Islands when it comes to timezone extravagance.

 B. fsck allows missing author names such as "tagger <email>", mktag
    wouldn't, but would allow e.g. "tagger [2 spaces] <email>" (but
    not "tagger [1 space] <email>"). Now we allow all of these.

 C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
    allows it.

In some ways fsck_tag() is stricter than "mktag" was, namely:

 D. fsck disallows zero-padded dates, but mktag didn't care. So
    e.g. the timestamp "0000000000 +0000" produces an error now. A
    test in "t1006-cat-file.sh" relied on this, it's been changed to
    use "hash-object" (without fsck) instead.

There was one check I deemed worth keeping by porting it over to
fsck_tag():

 E. "mktag" did not allow any custom headers, and by extension (as an
    empty commit is allowed) also forbade an extra stray trailing
    newline after the headers it knew about.

    Add a new check in the "ignore" category to fsck and use it. This
    somewhat abuses the facility added in efaba7cc77f (fsck:
    optionally ignore specific fsck issues completely, 2015-06-22).

    This is somewhat of hack, but probably the least invasive change
    we can make here. The fsck command will shuffle these categories
    around, e.g. under --strict the "info" becomes a "warn" and "warn"
    becomes "error". Existing users of fsck's (and others,
    e.g. index-pack) --strict option rely on this.

    So we need to put something into a category that'll be ignored by
    all existing users of the API. Pretending that
    fsck.extraHeaderEntry=error ("ignore" by default) was set serves
    to do this for us.

1. ec4465adb38 (Add "tag" objects that can be used to sign other
   objects., 2005-04-25)

2. https://en.wikipedia.org/wiki/List_of_UTC_time_offsets

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt |   9 +-
 builtin/mktag.c             | 196 +++++++++---------------------------
 fsck.c                      |  32 +++++-
 fsck.h                      |   9 ++
 t/t1006-cat-file.sh         |   2 +-
 t/t3800-mktag.sh            |  63 ++++++------
 6 files changed, 127 insertions(+), 184 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index adc63f6d4e..03cd63d9f6 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -25,7 +25,14 @@ write a tag found in `my-tag`:
     git hash-object -t tag -w --stdin <my-tag
 
 The difference is that mktag will die before writing the tag if the
-tag doesn't pass a sanity check.
+tag doesn't pass a linkgit:git-fsck[1] check.
+
+The "fsck" check done mktag is stricter than what linkgit:git-fsck[1]
+would run by default in that all `fsck.<msg-id>` messages are promoted
+from warnings to errors (so e.g. a missing "tagger" line is an error).
+
+Extra headers in the object are also an error under mktag, but ignored
+by linkgit:git-fsck[1]
 
 Tag Format
 ----------
diff --git a/builtin/mktag.c b/builtin/mktag.c
index d89a3c201d..4dd35bc79e 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -2,160 +2,60 @@
 #include "tag.h"
 #include "replace-object.h"
 #include "object-store.h"
+#include "fsck.h"
 
-/*
- * A signature file has a very simple fixed format: four lines
- * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
- * "tagger <committer>", followed by a blank line, a free-form tag
- * message and a signature block that git itself doesn't care about,
- * but that can be verified with gpg or similar.
- *
- * The first four lines are guaranteed to be at least 83 bytes:
- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
- * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
- * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
- * the shortest possible tagger-line.
- */
-
-/*
- * We refuse to tag something we can't verify. Just because.
- */
-static int verify_object(const struct object_id *oid, const char *expected_type)
+static int mktag_fsck_error_func(struct fsck_options *o,
+				 const struct object_id *oid,
+				 enum object_type object_type,
+				 int msg_type, const char *message)
 {
-	int ret = -1;
-	enum object_type type;
-	unsigned long size;
-	void *buffer = read_object_file(oid, &type, &size);
-	const struct object_id *repl = lookup_replace_object(the_repository, oid);
-
-	if (buffer) {
-		if (type == type_from_string(expected_type)) {
-			ret = check_object_signature(the_repository, repl,
-						     buffer, size,
-						     expected_type);
-		}
-		free(buffer);
+	switch (msg_type) {
+	case FSCK_WARN:
+	case FSCK_ERROR:
+		/*
+		 * We treat both warnings and errors as errors, things
+		 * like missing "tagger" lines are "only" warnings
+		 * under fsck, we've always considered them an error.
+		 */
+		fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message);
+		return 1;
+	default:
+		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
+		    msg_type);
 	}
-	return ret;
 }
 
-static int verify_tag(char *buffer, unsigned long size)
+static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 {
-	int typelen;
-	char type[20];
-	struct object_id oid;
-	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
-	size_t len;
-
-	if (size < 84)
-		return error("wanna fool me ? you obviously got the size wrong !");
-
-	buffer[size] = 0;
-
-	/* Verify object line */
-	object = buffer;
-	if (memcmp(object, "object ", 7))
-		return error("char%d: does not start with \"object \"", 0);
-
-	if (parse_oid_hex(object + 7, &oid, &p))
-		return error("char%d: could not get SHA1 hash", 7);
-
-	/* Verify type line */
-	type_line = p + 1;
-	if (memcmp(type_line - 1, "\ntype ", 6))
-		return error("char%d: could not find \"\\ntype \"", 47);
-
-	/* Verify tag-line */
-	tag_line = strchr(type_line, '\n');
-	if (!tag_line)
-		return error("char%"PRIuMAX": could not find next \"\\n\"",
-				(uintmax_t) (type_line - buffer));
-	tag_line++;
-	if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
-		return error("char%"PRIuMAX": no \"tag \" found",
-				(uintmax_t) (tag_line - buffer));
-
-	/* Get the actual type */
-	typelen = tag_line - type_line - strlen("type \n");
-	if (typelen >= sizeof(type))
-		return error("char%"PRIuMAX": type too long",
-				(uintmax_t) (type_line+5 - buffer));
-
-	memcpy(type, type_line+5, typelen);
-	type[typelen] = 0;
-
-	/* Verify that the object matches */
-	if (verify_object(&oid, type))
-		return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));
-
-	/* Verify the tag-name: we don't allow control characters or spaces in it */
-	tag_line += 4;
-	for (;;) {
-		unsigned char c = *tag_line++;
-		if (c == '\n')
-			break;
-		if (c > ' ')
-			continue;
-		return error("char%"PRIuMAX": could not verify tag name",
-				(uintmax_t) (tag_line - buffer));
-	}
-
-	/* Verify the tagger line */
-	tagger_line = tag_line;
-
-	if (memcmp(tagger_line, "tagger ", 7))
-		return error("char%"PRIuMAX": could not find \"tagger \"",
-			(uintmax_t) (tagger_line - buffer));
-
-	/*
-	 * Check for correct form for name and email
-	 * i.e. " <" followed by "> " on _this_ line
-	 * No angle brackets within the name or email address fields.
-	 * No spaces within the email address field.
-	 */
-	tagger_line += 7;
-	if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
-		strpbrk(tagger_line, "<>\n") != lb+1 ||
-		strpbrk(lb+2, "><\n ") != rb)
-		return error("char%"PRIuMAX": malformed tagger field",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* Check for author name, at least one character, space is acceptable */
-	if (lb == tagger_line)
-		return error("char%"PRIuMAX": missing tagger name",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* timestamp, 1 or more digits followed by space */
-	tagger_line = rb + 2;
-	if (!(len = strspn(tagger_line, "0123456789")))
-		return error("char%"PRIuMAX": missing tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += len;
-	if (*tagger_line != ' ')
-		return error("char%"PRIuMAX": malformed tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line++;
-
-	/* timezone, 5 digits [+-]hhmm, max. 1400 */
-	if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
-	      strspn(tagger_line+1, "0123456789") == 4 &&
-	      tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
-		return error("char%"PRIuMAX": malformed tag timezone",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += 6;
-
-	/* Verify the blank line separating the header from the body */
-	if (*tagger_line != '\n')
-		return error("char%"PRIuMAX": trailing garbage in tag header",
-			(uintmax_t) (tagger_line - buffer));
+	int ret;
+	enum object_type type;
+	unsigned long size;
+	void *buffer;
+	const struct object_id *repl;
+
+	buffer = read_object_file(tagged_oid, &type, &size);
+	if (!buffer)
+		die("could not read tagged object '%s'",
+		    oid_to_hex(tagged_oid));
+	if (type != *tagged_type)
+		die("object '%s' tagged as '%s', but is a '%s' type",
+		    oid_to_hex(tagged_oid),
+		    type_name(*tagged_type), type_name(type));
+
+	repl = lookup_replace_object(the_repository, tagged_oid);
+	ret = check_object_signature(the_repository, repl,
+				     buffer, size, type_name(*tagged_type));
+	free(buffer);
 
-	/* The actual stuff afterwards we don't care about.. */
-	return 0;
+	return ret;
 }
 
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	struct strbuf buf = STRBUF_INIT;
+	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
+	struct object_id tagged_oid;
+	int tagged_type;
 	struct object_id result;
 
 	if (argc != 1)
@@ -164,10 +64,14 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
 
-	/* Verify it for some basic sanity: it needs to start with
-	   "object <sha1>\ntype\ntagger " */
-	if (verify_tag(buf.buf, buf.len) < 0)
-		die("invalid tag signature file");
+	fsck_options.error_func = mktag_fsck_error_func;
+	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
+	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
+				&tagged_oid, &tagged_type))
+		die("tag on stdin did not pass our strict fsck check");
+
+	if (verify_object_in_tag(&tagged_oid, &tagged_type))
+		die("tag on stdin did not refer to a valid object");
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
 		die("unable to write tag file");
diff --git a/fsck.c b/fsck.c
index f82e2fe9e3..bed5e20e03 100644
--- a/fsck.c
+++ b/fsck.c
@@ -80,7 +80,9 @@ static struct oidset gitmodules_done = OIDSET_INIT;
 	/* infos (reported as warnings, but ignored by default) */ \
 	FUNC(GITMODULES_PARSE, INFO) \
 	FUNC(BAD_TAG_NAME, INFO) \
-	FUNC(MISSING_TAGGER_ENTRY, INFO)
+	FUNC(MISSING_TAGGER_ENTRY, INFO) \
+	/* ignored (elevated when requested) */ \
+	FUNC(EXTRA_HEADER_ENTRY, IGNORE)
 
 #define MSG_ID(id, msg_type) FSCK_MSG_##id,
 enum fsck_msg_id {
@@ -911,6 +913,16 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		    unsigned long size, struct fsck_options *options)
 {
 	struct object_id tagged_oid;
+	int tagged_type;
+	return fsck_tag_standalone(oid, buffer, size, options, &tagged_oid,
+				   &tagged_type);
+}
+
+int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+			unsigned long size, struct fsck_options *options,
+			struct object_id *tagged_oid,
+			int *tagged_type)
+{
 	int ret = 0;
 	char *eol;
 	struct strbuf sb = STRBUF_INIT;
@@ -924,7 +936,7 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
 		goto done;
 	}
-	if (parse_oid_hex(buffer, &tagged_oid, &p) || *p != '\n') {
+	if (parse_oid_hex(buffer, tagged_oid, &p) || *p != '\n') {
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
 		if (ret)
 			goto done;
@@ -940,7 +952,8 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
 		goto done;
 	}
-	if (type_from_string_gently(buffer, eol - buffer, 1) < 0)
+	*tagged_type = type_from_string_gently(buffer, eol - buffer, 1);
+	if (*tagged_type < 0)
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
 	if (ret)
 		goto done;
@@ -975,6 +988,19 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 	else
 		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
 
+	if (!starts_with(buffer, "\n")) {
+		/*
+		 * The verify_headers() check will allow
+		 * e.g. "[...]tagger <tagger>\nsome
+		 * garbage\n\nmessage" to pass, thinking "some
+		 * garbage" could be a custom header. E.g. "mktag"
+		 * doesn't want any unknown headers.
+		 */
+		ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
+		if (ret)
+			goto done;
+	}
+
 done:
 	strbuf_release(&sb);
 	return ret;
diff --git a/fsck.h b/fsck.h
index 69cf715e79..29ee4c45e8 100644
--- a/fsck.h
+++ b/fsck.h
@@ -62,6 +62,15 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options);
 int fsck_object(struct object *obj, void *data, unsigned long size,
 	struct fsck_options *options);
 
+/*
+ * fsck a tag, and pass info about it back to the caller. This is
+ * exposed fsck_object() internals for git-mktag(1).
+ */
+int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+			unsigned long size, struct fsck_options *options,
+			struct object_id *tagged_oid,
+			int *tag_type);
+
 /*
  * Some fsck checks are context-dependent, and may end up queued; run this
  * after completing all fsck_object() calls in order to resolve any remaining
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 2f501d2dc9..5d2dc99b74 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -166,7 +166,7 @@ tag_content="$tag_header_without_timestamp 0000000000 +0000
 
 $tag_description"
 
-tag_sha1=$(echo_without_newline "$tag_content" | git mktag)
+tag_sha1=$(echo_without_newline "$tag_content" | git hash-object -t tag --stdin -w)
 tag_size=$(strlen "$tag_content")
 
 run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" 1
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index c6826762d9..d20adf0544 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -47,7 +47,7 @@ too short for a tag
 EOF
 
 check_verify_failure 'Tag object length check' \
-	'^error: .*size wrong.*$'
+	'^error:.* missingObject:'
 
 ############################################################
 #  2. object line label check
@@ -60,7 +60,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
+check_verify_failure '"object" line label check' '^error:.* missingObject:'
 
 ############################################################
 #  3. object line hash check
@@ -73,7 +73,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
+check_verify_failure '"object" line check' '^error:.* badObjectSha1:'
 
 ############################################################
 #  4. type line label check
@@ -86,7 +86,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error:.* missingTypeEntry:'
 
 ############################################################
 #  5. type line eol check
@@ -94,7 +94,7 @@ check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
 echo "object $head" >tag.sig
 printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
 
-check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error:.* unterminatedHeader:'
 
 ############################################################
 #  6. tag line label check #1
@@ -108,7 +108,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure '"tag" line label check #1' \
-	'^error: char.*: no "tag " found$'
+	'^error:.* missingTagEntry:'
 
 ############################################################
 #  7. tag line label check #2
@@ -120,7 +120,7 @@ tag
 EOF
 
 check_verify_failure '"tag" line label check #2' \
-	'^error: char.*: no "tag " found$'
+	'^error:.* badType:'
 
 ############################################################
 #  8. type line type-name length check
@@ -132,7 +132,7 @@ tag mytag
 EOF
 
 check_verify_failure '"type" line type-name length check' \
-	'^error: char.*: type too long$'
+	'^error:.* badType:'
 
 ############################################################
 #  9. verify object (hash/type) check
@@ -146,7 +146,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
-	'^error: char7: could not verify object.*$'
+	'^fatal: could not read tagged object'
 
 cat >tag.sig <<EOF
 object $head
@@ -157,7 +157,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
-	'^fatal: invalid object type'
+	'^error:.* badType:'
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
@@ -168,7 +168,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
-	'^error: char7: could not verify object.*$'
+	'^error:.* badType:'
 
 cat >tag.sig <<EOF
 object $head
@@ -179,7 +179,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
-	'^error: char7: could not verify object'
+	'^fatal: object.*tagged as.*tree.*but is.*commit'
 
 ############################################################
 # 10. verify tag-name check
@@ -193,7 +193,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error: char.*: could not verify tag name$'
+	'^error:.* badTagName:'
 
 ############################################################
 # 11. tagger line label check #1
@@ -207,7 +207,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error: char.*: could not find "tagger "$'
+	'^error:.* missingTaggerEntry:'
 
 ############################################################
 # 12. tagger line label check #2
@@ -222,10 +222,10 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error: char.*: could not find "tagger "$'
+	'^error:.* missingTaggerEntry:'
 
 ############################################################
-# 13. disallow missing tag author name
+# 13. allow missing tag author name like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -236,8 +236,7 @@ tagger  <> 0 +0000
 This is filler
 EOF
 
-check_verify_failure 'disallow missing tag author name' \
-	'^error: char.*: missing tagger name$'
+test_expect_mktag_success 'allow missing tag author name'
 
 ############################################################
 # 14. disallow missing tag author name
@@ -252,7 +251,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error: char.*: malformed tagger field$'
+	'^error:.* badEmail:'
 
 ############################################################
 # 15. allow empty tag email
@@ -268,7 +267,7 @@ EOF
 test_expect_mktag_success 'allow empty tag email'
 
 ############################################################
-# 16. disallow spaces in tag email
+# 16. allow spaces in tag email like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -278,8 +277,7 @@ tagger T A Gger <tag ger@example.com> 0 +0000
 
 EOF
 
-check_verify_failure 'disallow spaces in tag email' \
-	'^error: char.*: malformed tagger field$'
+test_expect_mktag_success 'allow spaces in tag email like fsck'
 
 ############################################################
 # 17. disallow missing tag timestamp
@@ -293,7 +291,7 @@ tagger T A Gger <tagger@example.com>__
 EOF
 
 check_verify_failure 'disallow missing tag timestamp' \
-	'^error: char.*: missing tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 18. detect invalid tag timestamp1
@@ -307,7 +305,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
 EOF
 
 check_verify_failure 'detect invalid tag timestamp1' \
-	'^error: char.*: missing tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 19. detect invalid tag timestamp2
@@ -321,7 +319,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
 EOF
 
 check_verify_failure 'detect invalid tag timestamp2' \
-	'^error: char.*: malformed tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 20. detect invalid tag timezone1
@@ -335,7 +333,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
 EOF
 
 check_verify_failure 'detect invalid tag timezone1' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 ############################################################
 # 21. detect invalid tag timezone2
@@ -349,10 +347,10 @@ tagger T A Gger <tagger@example.com> 1206478233 +  30
 EOF
 
 check_verify_failure 'detect invalid tag timezone2' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 ############################################################
-# 22. detect invalid tag timezone3
+# 22. allow invalid tag timezone3 (the maximum is -1200/+1400)
 
 cat >tag.sig <<EOF
 object $head
@@ -362,8 +360,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
 
 EOF
 
-check_verify_failure 'detect invalid tag timezone3' \
-	'^error: char.*: malformed tag timezone$'
+test_expect_mktag_success 'allow invalid tag timezone'
 
 ############################################################
 # 23. detect invalid header entry
@@ -378,7 +375,7 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error: char.*: trailing garbage in tag header$'
+	'^error:.* extraHeaderEntry:'
 
 cat >tag.sig <<EOF
 object $head
@@ -412,7 +409,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500$space
 EOF
 
 check_verify_failure 'extra whitespace at end of headers' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 cat >tag.sig <<EOF
 object $head
@@ -422,7 +419,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 EOF
 
 check_verify_failure 'disallow no header / body newline separator' \
-	'^error: char.*: trailing garbage in tag header$'
+	'^error:.* extraHeaderEntry:'
 
 ############################################################
 # 24. create valid tag
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 15/20] fsck: make fsck_config() re-usable
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (15 preceding siblings ...)
  2020-12-23  1:35               ` [PATCH v4 14/20] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:36               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:36               ` [PATCH v4 16/20] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
                                 ` (4 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:36 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Move the fsck_config() function from builtin/fsck.c to fsck.[ch]. This
allows for re-using it in other tools that expose fsck logic and want
to support its configuration variables.

A logical continuation of this change would be to use a common
function for all of {fetch,receive}.fsck.* and fsck.*. See
5d477a334a6 (fsck (receive-pack): allow demoting errors to warnings,
2015-06-22) and my own 1362df0d413 (fetch: implement fetch.fsck.*,
2018-07-27) for the relevant code.

However, those routines want to not parse the fsck.skipList into OIDs,
but rather pass them along with the --strict option to another
process. It would be possible to refactor that whole thing so we
support e.g. a "fetch." prefix, then just keep track of the skiplist
as a filename instead of parsing it, and learn to spew that all out
from our internal structures into something we can append to the
--strict option.

But instead I'm planning to re-use this in "mktag", which'll just
re-use these "fsck.*" variables as-is.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/fsck.c | 20 +-------------------
 fsck.c         | 25 +++++++++++++++++++++++++
 fsck.h         |  7 +++++++
 3 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index fbf26cafcf..821e7798c7 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -73,25 +73,7 @@ static const char *printable_type(const struct object_id *oid,
 
 static int fsck_config(const char *var, const char *value, void *cb)
 {
-	if (strcmp(var, "fsck.skiplist") == 0) {
-		const char *path;
-		struct strbuf sb = STRBUF_INIT;
-
-		if (git_config_pathname(&path, var, value))
-			return 1;
-		strbuf_addf(&sb, "skiplist=%s", path);
-		free((char *)path);
-		fsck_set_msg_types(&fsck_obj_options, sb.buf);
-		strbuf_release(&sb);
-		return 0;
-	}
-
-	if (skip_prefix(var, "fsck.", &var)) {
-		fsck_set_msg_type(&fsck_obj_options, var, value);
-		return 0;
-	}
-
-	return git_default_config(var, value, cb);
+	return fsck_config_internal(var, value, cb, &fsck_obj_options);
 }
 
 static int objerror(struct object *obj, const char *err)
diff --git a/fsck.c b/fsck.c
index bed5e20e03..9067a290a2 100644
--- a/fsck.c
+++ b/fsck.c
@@ -1310,3 +1310,28 @@ int fsck_finish(struct fsck_options *options)
 	oidset_clear(&gitmodules_done);
 	return ret;
 }
+
+int fsck_config_internal(const char *var, const char *value, void *cb,
+			 struct fsck_options *options)
+{
+	if (strcmp(var, "fsck.skiplist") == 0) {
+		const char *path;
+		struct strbuf sb = STRBUF_INIT;
+
+		if (git_config_pathname(&path, var, value))
+			return 1;
+		strbuf_addf(&sb, "skiplist=%s", path);
+		free((char *)path);
+		fsck_set_msg_types(options, sb.buf);
+		strbuf_release(&sb);
+		return 0;
+	}
+
+	if (skip_prefix(var, "fsck.", &var)) {
+		fsck_set_msg_type(options, var, value);
+		return 0;
+	}
+
+	return git_default_config(var, value, cb);
+}
+
diff --git a/fsck.h b/fsck.h
index 29ee4c45e8..423c467feb 100644
--- a/fsck.h
+++ b/fsck.h
@@ -103,4 +103,11 @@ void fsck_put_object_name(struct fsck_options *options,
 const char *fsck_describe_object(struct fsck_options *options,
 				 const struct object_id *oid);
 
+/*
+ * git_config() callback for use by fsck-y tools that want to support
+ * fsck.<msg> fsck.skipList etc.
+ */
+int fsck_config_internal(const char *var, const char *value, void *cb,
+			 struct fsck_options *options);
+
 #endif
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 16/20] mktag: allow turning off fsck.extraHeaderEntry
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (16 preceding siblings ...)
  2020-12-23  1:36               ` [PATCH v4 15/20] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:36               ` Ævar Arnfjörð Bjarmason
  2020-12-23 22:09                 ` SZEDER Gábor
  2020-12-23  1:36               ` [PATCH v4 17/20] mktag: allow omitting the header/body \n separator Ævar Arnfjörð Bjarmason
                                 ` (3 subsequent siblings)
  21 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:36 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

In earlier commits mktag learned to use the fsck machinery, at which
point we needed to add fsck.extraHeaderEntry so it could be as strict
about extra headers as it's been ever since it was implemented.

But it's not nice to need to switch away from "mktag" to "hash-object"
+ manual "fsck" just because you'd like to have an extra header. So
let's support turning it off by getting "fsck.*" variables from the
config.

Pedantically speaking it's still not possible to make "mktag" behave
just like "hash-object -t tag" does, since we're unconditionally going
to check the referenced object in verify_object_in_tag(), which is our
own check, and not one that exists in fsck.c.

But the spirit of "this works like fsck" is preserved, in that if you
created such a tag with "hash-object" and did a full "fsck" on the
repository it would also error out about that invalid object, it just
wouldn't emit the same message as fsck does.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt |  5 ++++-
 builtin/mktag.c             | 11 ++++++++++-
 t/t3800-mktag.sh            | 14 ++++++++++++++
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 03cd63d9f6..d04657b219 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -32,7 +32,10 @@ would run by default in that all `fsck.<msg-id>` messages are promoted
 from warnings to errors (so e.g. a missing "tagger" line is an error).
 
 Extra headers in the object are also an error under mktag, but ignored
-by linkgit:git-fsck[1]
+by linkgit:git-fsck[1]. This extra check can be turned off by setting
+the appropriate `fsck.<msg-id>` varible:
+
+    git -c fsck.extraHeaderEntry=ignore mktag <my-tag-with-headers
 
 Tag Format
 ----------
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4dd35bc79e..373926d7e0 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -3,6 +3,14 @@
 #include "replace-object.h"
 #include "object-store.h"
 #include "fsck.h"
+#include "config.h"
+
+static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
+
+static int mktag_config(const char *var, const char *value, void *cb)
+{
+	return fsck_config_internal(var, value, cb, &fsck_options);
+}
 
 static int mktag_fsck_error_func(struct fsck_options *o,
 				 const struct object_id *oid,
@@ -53,7 +61,6 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	struct strbuf buf = STRBUF_INIT;
-	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 	struct object_id tagged_oid;
 	int tagged_type;
 	struct object_id result;
@@ -66,6 +73,8 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 
 	fsck_options.error_func = mktag_fsck_error_func;
 	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
+	/* config might set fsck.extraHeaderEntry=* again */
+	git_config(mktag_config, NULL);
 	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
 				&tagged_oid, &tagged_type))
 		die("tag on stdin did not pass our strict fsck check");
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index d20adf0544..1019b42378 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -377,6 +377,20 @@ EOF
 check_verify_failure 'detect invalid header entry' \
 	'^error:.* extraHeaderEntry:'
 
+test_expect_success 'invalid header entry config & fsck' '
+	test_must_fail git mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
+	git fsck &&
+	env GIT_TEST_GETTEXT_POISON=false \
+		git -c fsck.extraHeaderEntry=warn fsck 2>err &&
+	grep "warning .*extraHeaderEntry:" err &&
+	test_must_fail env GIT_TEST_GETTEXT_POISON=false \
+		git -c fsck.extraHeaderEntry=error 2>err fsck &&
+	grep "error .* extraHeaderEntry:" err
+'
+
 cat >tag.sig <<EOF
 object $head
 type commit
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 17/20] mktag: allow omitting the header/body \n separator
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (17 preceding siblings ...)
  2020-12-23  1:36               ` [PATCH v4 16/20] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:36               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:36               ` [PATCH v4 18/20] mktag: convert to parse-options Ævar Arnfjörð Bjarmason
                                 ` (2 subsequent siblings)
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:36 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Change mktag's acceptance rules to accept an empty body without an
empty line after the header again. This fixes an ancient unintended
dregression in "mktag".

When "mktag" was introduced in ec4465adb3 (Add "tag" objects that can
be used to sign other objects., 2005-04-25) the input checks were much
looser. When it was documented it 6cfec03680 (mktag: minimally update
the description., 2007-06-10) it was clearly intended for this \n to
be optional:

    The message, when [it] exists, is separated by a blank line from
    the header.

But then in e0aaf781f6 (mktag.c: improve verification of tagger field
and tests, 2008-03-27) this was made an error, seemingly by
accident. It was just a result of the general header checks, and all
the tests after that patch have a trailing empty line (but did not
before).

Let's allow this again, and tweak the test semantics changed in
e0aaf781f6 to remove the redundant empty line. New tests added in
previous commits of mine already added an explicit test for allowing
the empty line between header and body.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 fsck.c           | 2 ++
 t/t3800-mktag.sh | 6 +++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/fsck.c b/fsck.c
index 9067a290a2..29c1eaca4c 100644
--- a/fsck.c
+++ b/fsck.c
@@ -987,6 +987,8 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
 	}
 	else
 		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
+	if (!*buffer)
+		goto done;
 
 	if (!starts_with(buffer, "\n")) {
 		/*
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 1019b42378..9383f7795b 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -432,8 +432,9 @@ tag mytag
 tagger T A Gger <tagger@example.com> 1206478233 -0500
 EOF
 
-check_verify_failure 'disallow no header / body newline separator' \
-	'^error:.* extraHeaderEntry:'
+test_expect_success 'allow no header / body newline separator' '
+	git mktag <tag.sig
+'
 
 ############################################################
 # 24. create valid tag
@@ -443,7 +444,6 @@ object $head
 type commit
 tag mytag
 tagger T A Gger <tagger@example.com> 1206478233 -0500
-
 EOF
 
 test_expect_mktag_success 'create valid tag object'
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 18/20] mktag: convert to parse-options
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (18 preceding siblings ...)
  2020-12-23  1:36               ` [PATCH v4 17/20] mktag: allow omitting the header/body \n separator Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:36               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:36               ` [PATCH v4 19/20] mktag: mark strings for translation Ævar Arnfjörð Bjarmason
  2020-12-23  1:36               ` [PATCH v4 20/20] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:36 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Convert the "mktag" command to use parse-options.h instead of its own
ad-hoc argc handling. This doesn't matter much in practice since it
doesn't support any options, but removes another special-case in our
codebase, and makes it easier to add options to it in the future.

It does marginally improve the situation for programs that want to
execute git commands in a consistent manner and e.g. always use
--end-of-options. E.g. "gitaly" does that, and has a blacklist of
built-ins that don't support --end-of-options. This is one less
special case for it and other similar programs to support.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c  | 14 ++++++++++++--
 t/t3800-mktag.sh | 12 ++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 373926d7e0..18b8492f4d 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -1,10 +1,16 @@
 #include "builtin.h"
+#include "parse-options.h"
 #include "tag.h"
 #include "replace-object.h"
 #include "object-store.h"
 #include "fsck.h"
 #include "config.h"
 
+static char const * const builtin_mktag_usage[] = {
+	N_("git mktag"),
+	NULL
+};
+
 static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 
 static int mktag_config(const char *var, const char *value, void *cb)
@@ -60,13 +66,17 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
+	static struct option builtin_mktag_options[] = {
+		OPT_END(),
+	};
 	struct strbuf buf = STRBUF_INIT;
 	struct object_id tagged_oid;
 	int tagged_type;
 	struct object_id result;
 
-	if (argc != 1)
-		usage("git mktag");
+	argc = parse_options(argc, argv, NULL,
+			     builtin_mktag_options,
+			     builtin_mktag_usage, 0);
 
 	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 9383f7795b..177ab1682d 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -39,6 +39,18 @@ test_expect_success 'setup' '
 	head=$(git rev-parse --verify HEAD)
 '
 
+test_expect_success 'basic usage' '
+	cat >tag.sig <<-EOF &&
+	object $head
+	type commit
+	tag mytag
+	tagger T A Gger <tagger@example.com> 1206478233 -0500
+	EOF
+	git mktag <tag.sig &&
+	git mktag --end-of-options <tag.sig &&
+	test_expect_code 129 git mktag --unknown-option
+'
+
 ############################################################
 #  1. length check
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 19/20] mktag: mark strings for translation
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (19 preceding siblings ...)
  2020-12-23  1:36               ` [PATCH v4 18/20] mktag: convert to parse-options Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:36               ` Ævar Arnfjörð Bjarmason
  2020-12-23  1:36               ` [PATCH v4 20/20] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
  21 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:36 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Mark the errors mktag might emit for translation. This is a plumbing
command, but the errors it emits are intended to be human-readable.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c  | 16 ++++++++--------
 t/t3800-mktag.sh |  3 ++-
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 18b8492f4d..9b04b61c2b 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -31,10 +31,10 @@ static int mktag_fsck_error_func(struct fsck_options *o,
 		 * like missing "tagger" lines are "only" warnings
 		 * under fsck, we've always considered them an error.
 		 */
-		fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message);
+		fprintf_ln(stderr, _("error: tag input does not pass fsck: %s"), message);
 		return 1;
 	default:
-		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
+		BUG(_("%d (FSCK_IGNORE?) should never trigger this callback"),
 		    msg_type);
 	}
 }
@@ -49,10 +49,10 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 
 	buffer = read_object_file(tagged_oid, &type, &size);
 	if (!buffer)
-		die("could not read tagged object '%s'",
+		die(_("could not read tagged object '%s'"),
 		    oid_to_hex(tagged_oid));
 	if (type != *tagged_type)
-		die("object '%s' tagged as '%s', but is a '%s' type",
+		die(_("object '%s' tagged as '%s', but is a '%s' type"),
 		    oid_to_hex(tagged_oid),
 		    type_name(*tagged_type), type_name(type));
 
@@ -79,7 +79,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 			     builtin_mktag_usage, 0);
 
 	if (strbuf_read(&buf, 0, 0) < 0)
-		die_errno("could not read from stdin");
+		die_errno(_("could not read from stdin"));
 
 	fsck_options.error_func = mktag_fsck_error_func;
 	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
@@ -87,13 +87,13 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	git_config(mktag_config, NULL);
 	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
 				&tagged_oid, &tagged_type))
-		die("tag on stdin did not pass our strict fsck check");
+		die(_("tag on stdin did not pass our strict fsck check"));
 
 	if (verify_object_in_tag(&tagged_oid, &tagged_type))
-		die("tag on stdin did not refer to a valid object");
+		die(_("tag on stdin did not refer to a valid object"));
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
-		die("unable to write tag file");
+		die(_("unable to write tag file"));
 
 	strbuf_release(&buf);
 	puts(oid_to_hex(&result));
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 177ab1682d..2e8b718379 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -14,7 +14,8 @@ test_description='git mktag: tag object verify test'
 check_verify_failure () {
 	expect="$2"
 	test_expect_success "$1" '
-		test_must_fail git mktag <tag.sig 2>message &&
+		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
+			git mktag <tag.sig 2>message &&
 		grep "$expect" message
 	'
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v4 20/20] mktag: add a --no-strict option
  2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
                                 ` (20 preceding siblings ...)
  2020-12-23  1:36               ` [PATCH v4 19/20] mktag: mark strings for translation Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:36               ` Ævar Arnfjörð Bjarmason
  2020-12-23 11:54                 ` Junio C Hamano
  2020-12-23 22:20                 ` SZEDER Gábor
  21 siblings, 2 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-12-23  1:36 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, Ævar Arnfjörð Bjarmason

Now that mktag has been migrated to use the fsck machinery to check
its input, it makes sense to teach it to run in the equivalent of "git
fsck"'s default mode, instead of hardcoding "git fsck --strict". Let's
do that and support the "--no-strict" option.

Since this is a new option we don't need to cater to parse-option.c's
default of automatically supporting --strict. So let's use
PARSE_OPT_NONEG, using a new trivial helper macro.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt |  7 +++++++
 builtin/mktag.c             |  9 +++++++++
 parse-options.h             |  1 +
 t/t3800-mktag.sh            | 35 ++++++++++++++++++++++++-----------
 4 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index d04657b219..05e49b6787 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -11,6 +11,13 @@ SYNOPSIS
 [verse]
 'git mktag'
 
+OPTIONS
+-------
+
+--no-strict::
+	By default mktag turns on the equivalent of
+	linkgit:git-fsck[1] `--strict` mode. This disables it.
+
 DESCRIPTION
 -----------
 
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 9b04b61c2b..a6a4612247 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -10,6 +10,7 @@ static char const * const builtin_mktag_usage[] = {
 	N_("git mktag"),
 	NULL
 };
+static int option_no_strict;
 
 static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 
@@ -25,6 +26,12 @@ static int mktag_fsck_error_func(struct fsck_options *o,
 {
 	switch (msg_type) {
 	case FSCK_WARN:
+		if (option_no_strict) {
+			fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
+			return 0;
+
+		}
+		/* fallthrough */
 	case FSCK_ERROR:
 		/*
 		 * We treat both warnings and errors as errors, things
@@ -67,6 +74,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	static struct option builtin_mktag_options[] = {
+		OPT_NO_BOOL(0, "no-strict", &option_no_strict,
+			    N_("don't do strict fsck checks")),
 		OPT_END(),
 	};
 	struct strbuf buf = STRBUF_INIT;
diff --git a/parse-options.h b/parse-options.h
index 7030d8f3da..90d6a817d7 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -166,6 +166,7 @@ struct option {
 #define OPT_COUNTUP(s, l, v, h)     OPT_COUNTUP_F(s, l, v, h, 0)
 #define OPT_SET_INT(s, l, v, h, i)  OPT_SET_INT_F(s, l, v, h, i, 0)
 #define OPT_BOOL(s, l, v, h)        OPT_BOOL_F(s, l, v, h, 0)
+#define OPT_NO_BOOL(s, l, v, h)     OPT_BOOL_F(s, l, v, h, PARSE_OPT_NONEG)
 #define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
 #define OPT_CMDMODE(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, \
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 2e8b718379..b436ae1e44 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -12,12 +12,16 @@ test_description='git mktag: tag object verify test'
 # given in the expect.pat file.
 
 check_verify_failure () {
-	expect="$2"
-	test_expect_success "$1" '
+	test_expect_success "$1" "
 		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
 			git mktag <tag.sig 2>message &&
-		grep "$expect" message
-	'
+		grep '$2' message &&
+		if test '$3' != '--no-strict'
+		then
+			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&
+			grep '$2' message.no-strict
+		fi
+	"
 }
 
 test_expect_mktag_success() {
@@ -49,7 +53,8 @@ test_expect_success 'basic usage' '
 	EOF
 	git mktag <tag.sig &&
 	git mktag --end-of-options <tag.sig &&
-	test_expect_code 129 git mktag --unknown-option
+	test_expect_code 129 git mktag --unknown-option &&
+	test_expect_code 129 git mktag --strict
 '
 
 ############################################################
@@ -60,7 +65,7 @@ too short for a tag
 EOF
 
 check_verify_failure 'Tag object length check' \
-	'^error:.* missingObject:'
+	'^error:.* missingObject:' 'strict'
 
 ############################################################
 #  2. object line label check
@@ -206,7 +211,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error:.* badTagName:'
+	'^error:.* badTagName:' '--no-strict'
 
 ############################################################
 # 11. tagger line label check #1
@@ -220,7 +225,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error:.* missingTaggerEntry:'
+	'^error:.* missingTaggerEntry:' '--no-strict'
 
 ############################################################
 # 12. tagger line label check #2
@@ -235,7 +240,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error:.* missingTaggerEntry:'
+	'^error:.* missingTaggerEntry:' '--no-strict'
 
 ############################################################
 # 13. allow missing tag author name like fsck
@@ -264,7 +269,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error:.* badEmail:'
+	'^error:.* badEmail:' '--no-strict'
 
 ############################################################
 # 15. allow empty tag email
@@ -388,13 +393,21 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error:.* extraHeaderEntry:'
+	'^error:.* extraHeaderEntry:' '--no-strict'
 
 test_expect_success 'invalid header entry config & fsck' '
 	test_must_fail git mktag <tag.sig &&
+	git mktag --no-strict <tag.sig &&
+
 	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=error mktag --no-strict <tag.sig &&
+
 	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=warn mktag --no-strict <tag.sig &&
+
 	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=ignore mktag --no-strict <tag.sig &&
+
 	git fsck &&
 	env GIT_TEST_GETTEXT_POISON=false \
 		git -c fsck.extraHeaderEntry=warn fsck 2>err &&
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: [PATCH v4 03/20] mktag doc: update to explain why to use this
  2020-12-23  1:35               ` [PATCH v4 03/20] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
@ 2020-12-23  1:57                 ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23  1:57 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change the mktag documentation to compare itself to the similar
> "hash-object -t tag" command. Before this someone reading the
> documentation wouldn't have much of an idea what the difference
> was.
>
> Let's allude to our own validation logic, and cross-link the "mktag"
> and "hash-object" documentation to aid discover-ability. A follow-up
> change to migrate "mktag" to use "fsck" validation will make the part
> about validation logic clearer.

We do not add links to refer to commands like "git commit-tree",
"git mktree" or "git add" just because these other commands can
create commit, tree and blob objects like hash-object does, so
adding a link to mktag in the hash-object documentation feels a
bit fishy, but the extended description in mktag that highlights
the added value of the command over hash-object reads very well.

>  Tag Format
>  ----------
> @@ -34,6 +43,10 @@ exists, is separated by a blank line from the header.  The
>  message part may contain a signature that Git itself doesn't
>  care about, but that can be verified with gpg.
>  
> +SEE ALSO
> +--------
> +linkgit:git-hash-object[1],

Comma,

> +
>  GIT
>  ---
>  Part of the linkgit:git[1] suite

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

* Re: [PATCH v4 06/20] mktag tests: improve verify_object() test coverage
  2020-12-23  1:35               ` [PATCH v4 06/20] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
@ 2020-12-23  2:04                 ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23  2:04 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

>  cat >tag.sig <<EOF
>  object $(test_oid deadbeef)
> +type tag
> +tag mytag
> +tagger . <> 0 +0000
> +
> +EOF
> +
> +check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
> +	'^error: char7: could not verify object.*$'
> +

OK.


> +cat >tag.sig <<EOF
> +object $head
>  type tagggg
>  tag mytag
>  tagger . <> 0 +0000
>  
>  EOF
>  
> -check_verify_failure 'verify object (SHA1/type) check' \
> +check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
> +	'^fatal: invalid object type'

tagggg is "made-up type".  Where did we grab head from?  it is
head=$(git rev-parse --verify HEAD) at the very beginning.  Is that
really a nonexisting object?

> +cat >tag.sig <<EOF
> +object $(test_oid deadbeef)
> +type tagggg
> +tag mytag
> +tagger . <> 0 +0000
> +
> +EOF
> +
> +check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
>  	'^error: char7: could not verify object.*$'

This is the "made-up type, nonexisting object", and previous one is
"made-up type, valid object", no?

> +cat >tag.sig <<EOF
> +object $head
> +type tree
> +tag mytag
> +tagger . <> 0 +0000
> +
> +EOF
> +
> +check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
> +	'^error: char7: could not verify object'

And this is correct.  "type tree" is not a made-up type, and $head
is a valid object but it is not of "type tree".


Somehow I feel as if this patch is trying to see if reviewers are
paying attention to ;-)

Thanks.

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

* Re: [PATCH v4 07/20] mktag tests: don't pipe to stderr needlessly
  2020-12-23  1:35               ` [PATCH v4 07/20] mktag tests: don't pipe to stderr needlessly Ævar Arnfjörð Bjarmason
@ 2020-12-23  2:10                 ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23  2:10 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Remove the piping of stderr to "message" in the valid tag test. This
> pattern seems to have been copy/pasted from the failure case in
> 446c6faec6 (New tests and en-passant modifications to mktag.,
> 2006-07-29).
>
> Nothing is piped to "message" here, and in the event of the test
> failing it only serves to hide the error.

I think the verb "to pipe" specifically means "redirecting the
output to a pipe" and nothing else.

    mktag tests: don't redirect stderr to a file needlessly

    Remove the redirection of stderr to "message" in the valid tag
    tests.  This pattern ... 2006-07-29).  Nobody examines the
    contents of the resulting "message" file, so the net result is
    that error messages cannot be seen in "sh t3800-mktag.sh -v"
    output.

or something like that?

>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t3800-mktag.sh | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index 9ae1b0bb0a..bbd148618e 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -257,7 +257,7 @@ EOF
>  
>  test_expect_success \
>      'allow empty tag email' \
> -    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
> +    'git mktag <tag.sig >.git/refs/tags/mytag'
>  
>  ############################################################
>  # 16. disallow spaces in tag email
> @@ -385,7 +385,7 @@ EOF
>  
>  test_expect_success \
>      'create valid tag' \
> -    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
> +    'git mktag <tag.sig >.git/refs/tags/mytag'
>  
>  ############################################################
>  # 25. check mytag

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

* Re: [PATCH v4 08/20] mktag tests: don't create "mytag" twice
  2020-12-23  1:35               ` [PATCH v4 08/20] mktag tests: don't create "mytag" twice Ævar Arnfjörð Bjarmason
@ 2020-12-23  2:18                 ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23  2:18 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change a test added in e0aaf781f6 (mktag.c: improve verification of
> tagger field and tests, 2008-03-27) to not create "mytag", which
> should only be created and verified at the end in an earlier test
> added in 446c6faec6 (New tests and en-passant modifications to mktag.,
> 2006-07-29).

If mktag fails to create a tag, presumably .git/refs/tags/mytag file
would be left empty.  Wouldn't "git tag -l" notice that it is not a
valid ref and omit it from its output?  I suspect if you corrupt the
contents of tag.sig temporarily while the first of the original
tests were running in such a way that mktag notices a bogosity, the
second half of the original would notice.

Having said that, I like the new way much better.

But do we even need to create the tag with update-ref in the first
place?  What does it check?  The fact that "mktag" only creates an
object and never creates a new ref to point at the newly created
object (hence we expect refs/tags/mytag does not yet exist)?

I am not complaining that it runs update-ref there or creates the
mytag tag.  I am just saying I do not understand what the test wants
to check by doing so.

> While we're at it let's prevent a similar logic error from creeping
> into the test by asserting that "mytag" doesn't exist before we create
> it. Let's do this by moving the test to use "update-ref", instead of
> our own homebrew ad-hoc refstore update.

Great.  I really like this part of the change that future-proofs us.

Thanks.

> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t3800-mktag.sh | 17 +++++------------
>  1 file changed, 5 insertions(+), 12 deletions(-)
>
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index bbd148618e..b6dcdbebe6 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -257,7 +257,7 @@ EOF
>  
>  test_expect_success \
>      'allow empty tag email' \
> -    'git mktag <tag.sig >.git/refs/tags/mytag'
> +    'git mktag <tag.sig'
>  
>  ############################################################
>  # 16. disallow spaces in tag email
> @@ -383,16 +383,9 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
>  
>  EOF
>  
> -test_expect_success \
> -    'create valid tag' \
> -    'git mktag <tag.sig >.git/refs/tags/mytag'
> -
> -############################################################
> -# 25. check mytag
> -
> -test_expect_success \
> -    'check mytag' \
> -    'git tag -l | grep mytag'
> -
> +test_expect_success 'create valid tag' '
> +	git mktag <tag.sig >hash &&
> +	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero)
> +'
>  
>  test_done

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

* Re: [PATCH v4 09/20] mktag tests: stress test whitespace handling
  2020-12-23  1:35               ` [PATCH v4 09/20] mktag tests: stress test whitespace handling Ævar Arnfjörð Bjarmason
@ 2020-12-23  2:27                 ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23  2:27 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> +cat >tag.sig <<EOF
> +object $head
> +type commit
> +tag mytag
> +tagger T A Gger <tagger@example.com> 1206478233 -0500
> +
> +
> +this line comes after an extra newline
> +EOF
> +
> +test_expect_success 'allow extra newlines at start of body' '
> +	git mktag <tag.sig
> +'

OK.

> +cat >tag.sig <<EOF
> +object $head
> +type commit
> +tag mytag
> +tagger T A Gger <tagger@example.com> 1206478233 -0500
> +
> +EOF
> +
> +test_expect_success 'allow extra newlines at end of headers' '
> +	git mktag <tag.sig
> +'

I am not sure what the contrast between "at start of body" and "at
end of headers" means.

Ahh, OK, we are making sure that we "allow a blank line after the
headers before an empty body".

Makes sense (but see below).

> +space=' '
> +cat >tag.sig <<EOF
> +object $head
> +type commit
> +tag mytag
> +tagger T A Gger <tagger@example.com> 1206478233 -0500$space
> +
> +EOF
> +
> +check_verify_failure 'extra whitespace at end of headers' \
> +	'^error: char.*: malformed tag timezone$'

OK.  Presumably all the other header lines forbid trailing space
as a malformed line?

> +cat >tag.sig <<EOF
> +object $head
> +type commit
> +tag mytag
> +tagger T A Gger <tagger@example.com> 1206478233 -0500
> +EOF
> +
> +check_verify_failure 'disallow no header / body newline separator' \
> +	'^error: char.*: trailing garbage in tag header$'

Now I am confused.  This fails because...?   We earlier saw that we
"allow" a blank line after the header when no body is present, but
this says the test fails if a blank line exists after the header
when no body exists.  I do not have any objection to the behaviour
of the command, but doesn't this mean the earlier test was not
labelled correctly?  It may make more sense to move this test next
to the earlier one, and name them

    "require a blank line before even an empty body (1)"
    "require a blank line before even an empty body (2)"

or something?  The earlier one ensures that a payload with such a
blank line is OK, and this one ensures that a payload without such a
blank line causes a failure.

Thanks.


> +
>  ############################################################
>  # 24. create valid tag

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

* Re: [PATCH v4 10/20] mktag tests: test "hash-object" compatibility
  2020-12-23  1:35               ` [PATCH v4 10/20] mktag tests: test "hash-object" compatibility Ævar Arnfjörð Bjarmason
@ 2020-12-23  2:29                 ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23  2:29 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Change all the successful "mktag" tests to test that "hash-object"
> produces the same hash for the input, and that fsck passes for
> both.
>
> This tests e.g. that "mktag" doesn't trim its input or otherwise munge
> it in a way that "hash-object" doesn't.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t3800-mktag.sh | 26 +++++++++++++++-----------
>  1 file changed, 15 insertions(+), 11 deletions(-)
>
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index f339321be8..c6826762d9 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -19,6 +19,16 @@ check_verify_failure () {
>  	'
>  }
>  
> +test_expect_mktag_success() {
> +	test_expect_success "$1" '
> +		git hash-object -t tag -w --stdin <tag.sig >expected &&
> +		git fsck --strict &&
> +		git mktag <tag.sig >hash &&
> +		git fsck --strict &&
> +		test_cmp expected hash
> +	'
> +}

;-)  Nice.

I'll stop here for tonight.  Thanks for working on this.

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

* Re: [PATCH v4 20/20] mktag: add a --no-strict option
  2020-12-23  1:36               ` [PATCH v4 20/20] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
@ 2020-12-23 11:54                 ` Junio C Hamano
  2020-12-23 22:20                 ` SZEDER Gábor
  1 sibling, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23 11:54 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Now that mktag has been migrated to use the fsck machinery to check
> its input, it makes sense to teach it to run in the equivalent of "git
> fsck"'s default mode, instead of hardcoding "git fsck --strict". Let's
> do that and support the "--no-strict" option.
>
> Since this is a new option we don't need to cater to parse-option.c's
> default of automatically supporting --strict. So let's use
> PARSE_OPT_NONEG, using a new trivial helper macro.

Hmph, I would have thought that the internal file-scope static done
like

    static int option_strict = 1;

with OPT_BOOL() would be more natural, than a double negation.

What problem does this new OPT_NO_BOOL() thing solve?


> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  Documentation/git-mktag.txt |  7 +++++++
>  builtin/mktag.c             |  9 +++++++++
>  parse-options.h             |  1 +
>  t/t3800-mktag.sh            | 35 ++++++++++++++++++++++++-----------
>  4 files changed, 41 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
> index d04657b219..05e49b6787 100644
> --- a/Documentation/git-mktag.txt
> +++ b/Documentation/git-mktag.txt
> @@ -11,6 +11,13 @@ SYNOPSIS
>  [verse]
>  'git mktag'
>  
> +OPTIONS
> +-------
> +
> +--no-strict::
> +	By default mktag turns on the equivalent of
> +	linkgit:git-fsck[1] `--strict` mode. This disables it.
> +
>  DESCRIPTION
>  -----------
>  
> diff --git a/builtin/mktag.c b/builtin/mktag.c
> index 9b04b61c2b..a6a4612247 100644
> --- a/builtin/mktag.c
> +++ b/builtin/mktag.c
> @@ -10,6 +10,7 @@ static char const * const builtin_mktag_usage[] = {
>  	N_("git mktag"),
>  	NULL
>  };
> +static int option_no_strict;
>  
>  static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
>  
> @@ -25,6 +26,12 @@ static int mktag_fsck_error_func(struct fsck_options *o,
>  {
>  	switch (msg_type) {
>  	case FSCK_WARN:
> +		if (option_no_strict) {
> +			fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
> +			return 0;
> +
> +		}
> +		/* fallthrough */
>  	case FSCK_ERROR:
>  		/*
>  		 * We treat both warnings and errors as errors, things
> @@ -67,6 +74,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
>  int cmd_mktag(int argc, const char **argv, const char *prefix)
>  {
>  	static struct option builtin_mktag_options[] = {
> +		OPT_NO_BOOL(0, "no-strict", &option_no_strict,
> +			    N_("don't do strict fsck checks")),
>  		OPT_END(),
>  	};
>  	struct strbuf buf = STRBUF_INIT;
> diff --git a/parse-options.h b/parse-options.h
> index 7030d8f3da..90d6a817d7 100644
> --- a/parse-options.h
> +++ b/parse-options.h
> @@ -166,6 +166,7 @@ struct option {
>  #define OPT_COUNTUP(s, l, v, h)     OPT_COUNTUP_F(s, l, v, h, 0)
>  #define OPT_SET_INT(s, l, v, h, i)  OPT_SET_INT_F(s, l, v, h, i, 0)
>  #define OPT_BOOL(s, l, v, h)        OPT_BOOL_F(s, l, v, h, 0)
> +#define OPT_NO_BOOL(s, l, v, h)     OPT_BOOL_F(s, l, v, h, PARSE_OPT_NONEG)
>  #define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \
>  				      (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
>  #define OPT_CMDMODE(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, \
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index 2e8b718379..b436ae1e44 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -12,12 +12,16 @@ test_description='git mktag: tag object verify test'
>  # given in the expect.pat file.
>  
>  check_verify_failure () {
> -	expect="$2"
> -	test_expect_success "$1" '
> +	test_expect_success "$1" "
>  		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
>  			git mktag <tag.sig 2>message &&
> -		grep "$expect" message
> -	'
> +		grep '$2' message &&
> +		if test '$3' != '--no-strict'
> +		then
> +			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&
> +			grep '$2' message.no-strict
> +		fi
> +	"
>  }
>  
>  test_expect_mktag_success() {
> @@ -49,7 +53,8 @@ test_expect_success 'basic usage' '
>  	EOF
>  	git mktag <tag.sig &&
>  	git mktag --end-of-options <tag.sig &&
> -	test_expect_code 129 git mktag --unknown-option
> +	test_expect_code 129 git mktag --unknown-option &&
> +	test_expect_code 129 git mktag --strict
>  '
>  
>  ############################################################
> @@ -60,7 +65,7 @@ too short for a tag
>  EOF
>  
>  check_verify_failure 'Tag object length check' \
> -	'^error:.* missingObject:'
> +	'^error:.* missingObject:' 'strict'
>  
>  ############################################################
>  #  2. object line label check
> @@ -206,7 +211,7 @@ tagger . <> 0 +0000
>  EOF
>  
>  check_verify_failure 'verify tag-name check' \
> -	'^error:.* badTagName:'
> +	'^error:.* badTagName:' '--no-strict'
>  
>  ############################################################
>  # 11. tagger line label check #1
> @@ -220,7 +225,7 @@ This is filler
>  EOF
>  
>  check_verify_failure '"tagger" line label check #1' \
> -	'^error:.* missingTaggerEntry:'
> +	'^error:.* missingTaggerEntry:' '--no-strict'
>  
>  ############################################################
>  # 12. tagger line label check #2
> @@ -235,7 +240,7 @@ This is filler
>  EOF
>  
>  check_verify_failure '"tagger" line label check #2' \
> -	'^error:.* missingTaggerEntry:'
> +	'^error:.* missingTaggerEntry:' '--no-strict'
>  
>  ############################################################
>  # 13. allow missing tag author name like fsck
> @@ -264,7 +269,7 @@ tagger T A Gger <
>  EOF
>  
>  check_verify_failure 'disallow malformed tagger' \
> -	'^error:.* badEmail:'
> +	'^error:.* badEmail:' '--no-strict'
>  
>  ############################################################
>  # 15. allow empty tag email
> @@ -388,13 +393,21 @@ this line should not be here
>  EOF
>  
>  check_verify_failure 'detect invalid header entry' \
> -	'^error:.* extraHeaderEntry:'
> +	'^error:.* extraHeaderEntry:' '--no-strict'
>  
>  test_expect_success 'invalid header entry config & fsck' '
>  	test_must_fail git mktag <tag.sig &&
> +	git mktag --no-strict <tag.sig &&
> +
>  	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
> +	test_must_fail git -c fsck.extraHeaderEntry=error mktag --no-strict <tag.sig &&
> +
>  	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
> +	git -c fsck.extraHeaderEntry=warn mktag --no-strict <tag.sig &&
> +
>  	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
> +	git -c fsck.extraHeaderEntry=ignore mktag --no-strict <tag.sig &&
> +
>  	git fsck &&
>  	env GIT_TEST_GETTEXT_POISON=false \
>  		git -c fsck.extraHeaderEntry=warn fsck 2>err &&

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

* Re: [PATCH v4 14/20] mktag: use fsck instead of custom verify_tag()
  2020-12-23  1:35               ` [PATCH v4 14/20] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
@ 2020-12-23 13:34                 ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23 13:34 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> +static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
>  {
> +	int ret;
> +	enum object_type type;
> +	unsigned long size;
> +	void *buffer;
> +	const struct object_id *repl;
> +
> +	buffer = read_object_file(tagged_oid, &type, &size);
> +	if (!buffer)
> +		die("could not read tagged object '%s'",
> +		    oid_to_hex(tagged_oid));
> +	if (type != *tagged_type)
> +		die("object '%s' tagged as '%s', but is a '%s' type",
> +		    oid_to_hex(tagged_oid),
> +		    type_name(*tagged_type), type_name(type));
> +
> +	repl = lookup_replace_object(the_repository, tagged_oid);
> +	ret = check_object_signature(the_repository, repl,
> +				     buffer, size, type_name(*tagged_type));
> +	free(buffer);

This is not new, but I wonder if the object whose name is repl can
be of different type than the object whose name is tagged_oid, and
what happens when such a replacement is defined.

> +	return ret;
>  }
> ...
> +/*
> + * fsck a tag, and pass info about it back to the caller. This is
> + * exposed fsck_object() internals for git-mktag(1).
> + */
> +int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
> +			unsigned long size, struct fsck_options *options,
> +			struct object_id *tagged_oid,
> +			int *tag_type);
> +

OK.

> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index c6826762d9..d20adf0544 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -47,7 +47,7 @@ too short for a tag
>  EOF

OK.  This seems to show rather nicely what checks got loosened
(and nothing got tightened it seems).

Thanks.  Looking good so far.

>  
>  check_verify_failure 'Tag object length check' \
> -	'^error: .*size wrong.*$'
> +	'^error:.* missingObject:'
>  
>  ############################################################
>  #  2. object line label check
> @@ -60,7 +60,7 @@ tagger . <> 0 +0000
>  
>  EOF
>  
> -check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
> +check_verify_failure '"object" line label check' '^error:.* missingObject:'
>  
>  ############################################################
>  #  3. object line hash check
> @@ -73,7 +73,7 @@ tagger . <> 0 +0000
>  
>  EOF
>  
> -check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
> +check_verify_failure '"object" line check' '^error:.* badObjectSha1:'
>  
>  ############################################################
>  #  4. type line label check
> @@ -86,7 +86,7 @@ tagger . <> 0 +0000
>  
>  EOF
>  
> -check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
> +check_verify_failure '"type" line label check' '^error:.* missingTypeEntry:'
>  
>  ############################################################
>  #  5. type line eol check
> @@ -94,7 +94,7 @@ check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
>  echo "object $head" >tag.sig
>  printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
>  
> -check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
> +check_verify_failure '"type" line eol check' '^error:.* unterminatedHeader:'
>  
>  ############################################################
>  #  6. tag line label check #1
> @@ -108,7 +108,7 @@ tagger . <> 0 +0000
>  EOF
>  
>  check_verify_failure '"tag" line label check #1' \
> -	'^error: char.*: no "tag " found$'
> +	'^error:.* missingTagEntry:'
>  
>  ############################################################
>  #  7. tag line label check #2
> @@ -120,7 +120,7 @@ tag
>  EOF
>  
>  check_verify_failure '"tag" line label check #2' \
> -	'^error: char.*: no "tag " found$'
> +	'^error:.* badType:'
>  
>  ############################################################
>  #  8. type line type-name length check
> @@ -132,7 +132,7 @@ tag mytag
>  EOF
>  
>  check_verify_failure '"type" line type-name length check' \
> -	'^error: char.*: type too long$'
> +	'^error:.* badType:'
>  
>  ############################################################
>  #  9. verify object (hash/type) check
> @@ -146,7 +146,7 @@ tagger . <> 0 +0000
>  EOF
>  
>  check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
> -	'^error: char7: could not verify object.*$'
> +	'^fatal: could not read tagged object'
>  
>  cat >tag.sig <<EOF
>  object $head
> @@ -157,7 +157,7 @@ tagger . <> 0 +0000
>  EOF
>  
>  check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
> -	'^fatal: invalid object type'
> +	'^error:.* badType:'
>  
>  cat >tag.sig <<EOF
>  object $(test_oid deadbeef)
> @@ -168,7 +168,7 @@ tagger . <> 0 +0000
>  EOF
>  
>  check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
> -	'^error: char7: could not verify object.*$'
> +	'^error:.* badType:'
>  
>  cat >tag.sig <<EOF
>  object $head
> @@ -179,7 +179,7 @@ tagger . <> 0 +0000
>  EOF
>  
>  check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
> -	'^error: char7: could not verify object'
> +	'^fatal: object.*tagged as.*tree.*but is.*commit'
>  
>  ############################################################
>  # 10. verify tag-name check
> @@ -193,7 +193,7 @@ tagger . <> 0 +0000
>  EOF
>  
>  check_verify_failure 'verify tag-name check' \
> -	'^error: char.*: could not verify tag name$'
> +	'^error:.* badTagName:'
>  
>  ############################################################
>  # 11. tagger line label check #1
> @@ -207,7 +207,7 @@ This is filler
>  EOF
>  
>  check_verify_failure '"tagger" line label check #1' \
> -	'^error: char.*: could not find "tagger "$'
> +	'^error:.* missingTaggerEntry:'
>  
>  ############################################################
>  # 12. tagger line label check #2
> @@ -222,10 +222,10 @@ This is filler
>  EOF
>  
>  check_verify_failure '"tagger" line label check #2' \
> -	'^error: char.*: could not find "tagger "$'
> +	'^error:.* missingTaggerEntry:'
>  
>  ############################################################
> -# 13. disallow missing tag author name
> +# 13. allow missing tag author name like fsck
>  
>  cat >tag.sig <<EOF
>  object $head
> @@ -236,8 +236,7 @@ tagger  <> 0 +0000
>  This is filler
>  EOF
>  
> -check_verify_failure 'disallow missing tag author name' \
> -	'^error: char.*: missing tagger name$'
> +test_expect_mktag_success 'allow missing tag author name'
>  
>  ############################################################
>  # 14. disallow missing tag author name
> @@ -252,7 +251,7 @@ tagger T A Gger <
>  EOF
>  
>  check_verify_failure 'disallow malformed tagger' \
> -	'^error: char.*: malformed tagger field$'
> +	'^error:.* badEmail:'
>  
>  ############################################################
>  # 15. allow empty tag email
> @@ -268,7 +267,7 @@ EOF
>  test_expect_mktag_success 'allow empty tag email'
>  
>  ############################################################
> -# 16. disallow spaces in tag email
> +# 16. allow spaces in tag email like fsck
>  
>  cat >tag.sig <<EOF
>  object $head
> @@ -278,8 +277,7 @@ tagger T A Gger <tag ger@example.com> 0 +0000
>  
>  EOF
>  
> -check_verify_failure 'disallow spaces in tag email' \
> -	'^error: char.*: malformed tagger field$'
> +test_expect_mktag_success 'allow spaces in tag email like fsck'
>  
>  ############################################################
>  # 17. disallow missing tag timestamp
> @@ -293,7 +291,7 @@ tagger T A Gger <tagger@example.com>__
>  EOF
>  
>  check_verify_failure 'disallow missing tag timestamp' \
> -	'^error: char.*: missing tag timestamp$'
> +	'^error:.* badDate:'
>  
>  ############################################################
>  # 18. detect invalid tag timestamp1
> @@ -307,7 +305,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
>  EOF
>  
>  check_verify_failure 'detect invalid tag timestamp1' \
> -	'^error: char.*: missing tag timestamp$'
> +	'^error:.* badDate:'
>  
>  ############################################################
>  # 19. detect invalid tag timestamp2
> @@ -321,7 +319,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
>  EOF
>  
>  check_verify_failure 'detect invalid tag timestamp2' \
> -	'^error: char.*: malformed tag timestamp$'
> +	'^error:.* badDate:'
>  
>  ############################################################
>  # 20. detect invalid tag timezone1
> @@ -335,7 +333,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
>  EOF
>  
>  check_verify_failure 'detect invalid tag timezone1' \
> -	'^error: char.*: malformed tag timezone$'
> +	'^error:.* badTimezone:'
>  
>  ############################################################
>  # 21. detect invalid tag timezone2
> @@ -349,10 +347,10 @@ tagger T A Gger <tagger@example.com> 1206478233 +  30
>  EOF
>  
>  check_verify_failure 'detect invalid tag timezone2' \
> -	'^error: char.*: malformed tag timezone$'
> +	'^error:.* badTimezone:'
>  
>  ############################################################
> -# 22. detect invalid tag timezone3
> +# 22. allow invalid tag timezone3 (the maximum is -1200/+1400)
>  
>  cat >tag.sig <<EOF
>  object $head
> @@ -362,8 +360,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
>  
>  EOF
>  
> -check_verify_failure 'detect invalid tag timezone3' \
> -	'^error: char.*: malformed tag timezone$'
> +test_expect_mktag_success 'allow invalid tag timezone'
>  
>  ############################################################
>  # 23. detect invalid header entry
> @@ -378,7 +375,7 @@ this line should not be here
>  EOF
>  
>  check_verify_failure 'detect invalid header entry' \
> -	'^error: char.*: trailing garbage in tag header$'
> +	'^error:.* extraHeaderEntry:'
>  
>  cat >tag.sig <<EOF
>  object $head
> @@ -412,7 +409,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500$space
>  EOF
>  
>  check_verify_failure 'extra whitespace at end of headers' \
> -	'^error: char.*: malformed tag timezone$'
> +	'^error:.* badTimezone:'
>  
>  cat >tag.sig <<EOF
>  object $head
> @@ -422,7 +419,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
>  EOF
>  
>  check_verify_failure 'disallow no header / body newline separator' \
> -	'^error: char.*: trailing garbage in tag header$'
> +	'^error:.* extraHeaderEntry:'
>  
>  ############################################################
>  # 24. create valid tag

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

* Re: [PATCH v4 00/20] make "mktag" use fsck_tag() & more
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
@ 2020-12-23 13:54                 ` Junio C Hamano
  2020-12-24  9:16                   ` Junio C Hamano
  2021-01-05 19:42                 ` [PATCH v5 00/23] " Ævar Arnfjörð Bjarmason
                                   ` (23 subsequent siblings)
  24 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2020-12-23 13:54 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> So, when re-rolling this with Junio's small fixup this grew in scope a
> bit, but should paradoxically be easier to deal with even though it's
> 2x the size now. Read on:

The core part didn't change all that much, which made it a bit
easier to see.  I left comments here and there, but the series
mostly looked sensible in general.

Thanks.

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

* Re: [PATCH v4 16/20] mktag: allow turning off fsck.extraHeaderEntry
  2020-12-23  1:36               ` [PATCH v4 16/20] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
@ 2020-12-23 22:09                 ` SZEDER Gábor
  0 siblings, 0 replies; 229+ messages in thread
From: SZEDER Gábor @ 2020-12-23 22:09 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Wed, Dec 23, 2020 at 02:36:01AM +0100, Ævar Arnfjörð Bjarmason wrote:
> In earlier commits mktag learned to use the fsck machinery, at which
> point we needed to add fsck.extraHeaderEntry so it could be as strict
> about extra headers as it's been ever since it was implemented.
> 
> But it's not nice to need to switch away from "mktag" to "hash-object"
> + manual "fsck" just because you'd like to have an extra header. So
> let's support turning it off by getting "fsck.*" variables from the
> config.
> 
> Pedantically speaking it's still not possible to make "mktag" behave
> just like "hash-object -t tag" does, since we're unconditionally going
> to check the referenced object in verify_object_in_tag(), which is our
> own check, and not one that exists in fsck.c.
> 
> But the spirit of "this works like fsck" is preserved, in that if you
> created such a tag with "hash-object" and did a full "fsck" on the
> repository it would also error out about that invalid object, it just
> wouldn't emit the same message as fsck does.
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---

> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index d20adf0544..1019b42378 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -377,6 +377,20 @@ EOF
>  check_verify_failure 'detect invalid header entry' \
>  	'^error:.* extraHeaderEntry:'
>  
> +test_expect_success 'invalid header entry config & fsck' '
> +	test_must_fail git mktag <tag.sig &&
> +	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
> +	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
> +	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
> +	git fsck &&
> +	env GIT_TEST_GETTEXT_POISON=false \

Why this 'env GIT_TEST_GETTEXT_POISON=false' here...

> +		git -c fsck.extraHeaderEntry=warn fsck 2>err &&
> +	grep "warning .*extraHeaderEntry:" err &&

... instead of test_i18ngrep here?

> +	test_must_fail env GIT_TEST_GETTEXT_POISON=false \
> +		git -c fsck.extraHeaderEntry=error 2>err fsck &&
> +	grep "error .* extraHeaderEntry:" err
> +'
> +
>  cat >tag.sig <<EOF
>  object $head
>  type commit
> -- 
> 2.29.2.222.g5d2a92d10f8
> 

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

* Re: [PATCH v4 20/20] mktag: add a --no-strict option
  2020-12-23  1:36               ` [PATCH v4 20/20] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
  2020-12-23 11:54                 ` Junio C Hamano
@ 2020-12-23 22:20                 ` SZEDER Gábor
  1 sibling, 0 replies; 229+ messages in thread
From: SZEDER Gábor @ 2020-12-23 22:20 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Wed, Dec 23, 2020 at 02:36:05AM +0100, Ævar Arnfjörð Bjarmason wrote:
> Now that mktag has been migrated to use the fsck machinery to check
> its input, it makes sense to teach it to run in the equivalent of "git
> fsck"'s default mode, instead of hardcoding "git fsck --strict". Let's
> do that and support the "--no-strict" option.
> 
> Since this is a new option we don't need to cater to parse-option.c's
> default of automatically supporting --strict. So let's use
> PARSE_OPT_NONEG, using a new trivial helper macro.
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>

> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index 2e8b718379..b436ae1e44 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -12,12 +12,16 @@ test_description='git mktag: tag object verify test'
>  # given in the expect.pat file.
>  
>  check_verify_failure () {
> -	expect="$2"
> -	test_expect_success "$1" '
> +	test_expect_success "$1" "
>  		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
>  			git mktag <tag.sig 2>message &&

So this 'git mktag' is always invoked with
GIT_TEST_GETTEXT_POISON=false (instead of, for some reason, using
test_i18ngrep on the next line)...

> -		grep "$expect" message
> -	'
> +		grep '$2' message &&
> +		if test '$3' != '--no-strict'
> +		then
> +			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&

Wouldn't a GIT_TEST_GETTEXT_POISON=false be necessary for this 'git
mktag' as well?  Or, alternatively (preferably?), a test_i18ngrep
below.

> +			grep '$2' message.no-strict
> +		fi
> +	"
>  }
>  
>  test_expect_mktag_success() {

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

* Re: [PATCH v4 00/20] make "mktag" use fsck_tag() & more
  2020-12-23 13:54                 ` Junio C Hamano
@ 2020-12-24  9:16                   ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2020-12-24  9:16 UTC (permalink / raw)
  To: git
  Cc: Ævar Arnfjörð Bjarmason, Jeff King,
	brian m . carlson, Eric Sunshine, Johannes Schindelin

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

> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
>
>> So, when re-rolling this with Junio's small fixup this grew in scope a
>> bit, but should paradoxically be easier to deal with even though it's
>> 2x the size now. Read on:
>
> The core part didn't change all that much, which made it a bit
> easier to see.  I left comments here and there, but the series
> mostly looked sensible in general.

This failure is likely from the "mktag" series:

  https://github.com/git/git/runs/1602776090#step:4:1622 (summary)
  https://github.com/git/git/runs/1602776090#step:5:158 (the first one of them)

Thanks.

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

* [PATCH v5 00/23] make "mktag" use fsck_tag() & more
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
  2020-12-23 13:54                 ` Junio C Hamano
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 01/23] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
                                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

A late re-roll due to the holidays. Thanks all for the feedback on v4,
this should address all of it.

Brief comments on each patch below, and then the range-diff.

Ævar Arnfjörð Bjarmason (23):
  mktag doc: say <hash> not <sha1>
  mktag doc: grammar fix, when exists -> when it exists

No changes.

  mktag doc: update to explain why to use this

Got rid of the cross-linking of mktag and hash-object manpages as
suggested by Junio.

  mktag tests: don't needlessly use a subshell

no changes.

  mktag tests: use "test_commit" helper

NEW: Another trivial mktag test cleanup, make it use test_commit
instead of 3 boilerplate lines in its test. Made a later change
smaller.

  mktag tests: remove needless SHA-1 hardcoding

no changes.

  mktag tests: don't redirect stderr to a file needlessly

Reworded the commit message, and fixed another copy/pasted mktag test
(in the git-replace test file) that used the same pattern.

  mktag tests: don't create "mytag" twice

The commit message notes that testing the tag at the end is pointless,
but now later we'll do something with it...

  mktag tests: run "fsck" after creating "mytag"

...i.e. run fsck to (potentially in the future) check the envelope
v.s. refname.

  mktag tests: stress test whitespace handling

Reworded commit message & test descriptions to make more sense, got
rid of the one $space test, which didn't really add anything.

  mktag tests: test "hash-object" compatibility

Gets rid of the "create tag refname" special case at the end of the
tests by now doing it for every successful tag creation.

  mktag tests: improve verify_object() test coverage

Commit message update, notes that we don't do "git replace" tests.

  mktag tests: test verify_object() with replaced objects

NEW: test mktag with git-replace'd objects.

  mktag: use default strbuf_read() hint
  mktag: remove redundant braces in one-line body "if"
  mktag: use puts(str) instead of printf("%s\n", str)

no changes.

  mktag: use fsck instead of custom verify_tag()

only carried-forward changes from rebasing on the changes above.

  fsck: make fsck_config() re-usable
  mktag: allow turning off fsck.extraHeaderEntry

no changes.

  mktag: allow omitting the header/body \n separator
  mktag: convert to parse-options

ditto carried-forward changes.

  mktag: mark strings for translation
  mktag: add a --no-strict option

Use the more normal OPT_BOOL pattern, and fix a stupid error in
GIT_TEST_GETTEXT_POISON=true testing that broke the CI.

 Documentation/git-mktag.txt |  39 +++++-
 builtin/fsck.c              |  20 +--
 builtin/mktag.c             | 235 +++++++++++++----------------------
 fsck.c                      |  59 ++++++++-
 fsck.h                      |  16 +++
 t/t1006-cat-file.sh         |   2 +-
 t/t3800-mktag.sh            | 236 ++++++++++++++++++++++++++++--------
 t/t6050-replace.sh          |   2 +-
 8 files changed, 375 insertions(+), 234 deletions(-)

Range-diff:
 1:  a31c305cfc6 =  1:  74b035fb842 mktag doc: say <hash> not <sha1>
 2:  81cb4cba5c0 =  2:  202bd33533f mktag doc: grammar fix, when exists -> when it exists
 3:  b4bc6f894cb !  3:  d1f650b6c4c mktag doc: update to explain why to use this
    @@ Commit message
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    - ## Documentation/git-hash-object.txt ##
    -@@ Documentation/git-hash-object.txt: OPTIONS
    - 	stress-testing Git itself or reproducing characteristics of corrupt or
    - 	bogus objects encountered in the wild.
    - 
    -+SEE ALSO
    -+--------
    -+linkgit:git-mktag[1]
    -+
    - GIT
    - ---
    - Part of the linkgit:git[1] suite
    -
      ## Documentation/git-mktag.txt ##
     @@ Documentation/git-mktag.txt: git-mktag(1)
      
    @@ Documentation/git-mktag.txt: SYNOPSIS
      
      Tag Format
      ----------
    -@@ Documentation/git-mktag.txt: exists, is separated by a blank line from the header.  The
    - message part may contain a signature that Git itself doesn't
    - care about, but that can be verified with gpg.
    - 
    -+SEE ALSO
    -+--------
    -+linkgit:git-hash-object[1],
    -+
    - GIT
    - ---
    - Part of the linkgit:git[1] suite
 4:  acb94e02895 =  4:  64432d22952 mktag tests: don't needlessly use a subshell
 -:  ----------- >  5:  57c7bdde80b mktag tests: use "test_commit" helper
 5:  4ae76ec5e3f =  6:  ba581a99c89 mktag tests: remove needless SHA-1 hardcoding
 7:  b81d31a917c !  7:  974d1b9c6ec mktag tests: don't pipe to stderr needlessly
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    mktag tests: don't pipe to stderr needlessly
    +    mktag tests: don't redirect stderr to a file needlessly
     
    -    Remove the piping of stderr to "message" in the valid tag test. This
    -    pattern seems to have been copy/pasted from the failure case in
    -    446c6faec6 (New tests and en-passant modifications to mktag.,
    +    Remove the redirection of stderr to "message" in the valid tag
    +    test. This pattern seems to have been copy/pasted from the failure
    +    case in 446c6faec6 (New tests and en-passant modifications to mktag.,
         2006-07-29).
     
    -    Nothing is piped to "message" here, and in the event of the test
    -    failing it only serves to hide the error.
    +    While I'm at it do the same for the "replace" tests. The tag creation
    +    I'm changing here seems to have been copy/pasted from the "mktag"
    +    tests to those tests in cc400f50112 (mktag: call
    +    "check_sha1_signature" with the replacement sha1, 2009-01-23).
    +
    +    Nobody examines the contents of the resulting "message" file, so the
    +    net result is that error messages cannot be seen in "sh t3800-mktag.sh
    +    -v" output.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ t/t3800-mktag.sh: EOF
      
      ############################################################
      # 25. check mytag
    +
    + ## t/t6050-replace.sh ##
    +@@ t/t6050-replace.sh: tagger T A Gger <> 0 +0000
    + EOF
    + 
    + test_expect_success 'tag replaced commit' '
    +-     git mktag <tag.sig >.git/refs/tags/mytag 2>message
    ++     git mktag <tag.sig >.git/refs/tags/mytag
    + '
    + 
    + test_expect_success '"git fsck" works' '
 8:  11f59718b4b !  8:  73d82dbca24 mktag tests: don't create "mytag" twice
    @@ Commit message
         it. Let's do this by moving the test to use "update-ref", instead of
         our own homebrew ad-hoc refstore update.
     
    +    We're not really testing for anything yet by creating the tag at the
    +    end here. A subsequent commit will change that.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t3800-mktag.sh ##
 -:  ----------- >  9:  0aa8190f404 mktag tests: run "fsck" after creating "mytag"
 9:  dd6b012b0c6 ! 10:  078e73c4221 mktag tests: stress test whitespace handling
    @@ Metadata
      ## Commit message ##
         mktag tests: stress test whitespace handling
     
    -    Add tests for various whitespace edge cases around the header/body
    -    boundary, such as two newlines separating the header and body, a space
    -    at the end of the "tagger" line before the header etc.
    +    Add tests for a couple of whitespace edge cases around the header/body
    +    boundary.
     
    -    Add a test showing that we insist that an empty body must be preceded
    -    by an empty line. This test for a long-standing regression which goes
    -    against the command's documented behavior. It'll be addressed in a
    -    follow-up change.
    +    I consider the requirement for a blank line before the empty body a
    +    bug, it's a long-standing regression which goes against the command's
    +    documented behavior. This bug will be addressed in a follow-up change.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
    @@ t/t3800-mktag.sh: EOF
     +
     +EOF
     +
    -+test_expect_success 'allow extra newlines at end of headers' '
    ++test_expect_success 'require a blank line before an empty body (1)' '
     +	git mktag <tag.sig
     +'
     +
    -+space=' '
    -+cat >tag.sig <<EOF
    -+object $head
    -+type commit
    -+tag mytag
    -+tagger T A Gger <tagger@example.com> 1206478233 -0500$space
    -+
    -+EOF
    -+
    -+check_verify_failure 'extra whitespace at end of headers' \
    -+	'^error: char.*: malformed tag timezone$'
    -+
     +cat >tag.sig <<EOF
     +object $head
     +type commit
    @@ t/t3800-mktag.sh: EOF
     +tagger T A Gger <tagger@example.com> 1206478233 -0500
     +EOF
     +
    -+check_verify_failure 'disallow no header / body newline separator' \
    ++check_verify_failure 'require a blank line before an empty body (2)' \
     +	'^error: char.*: trailing garbage in tag header$'
     +
      ############################################################
10:  56c6b562fd5 ! 11:  83d7ca86b8f mktag tests: test "hash-object" compatibility
    @@ Commit message
         This tests e.g. that "mktag" doesn't trim its input or otherwise munge
         it in a way that "hash-object" doesn't.
     
    +    Since we're doing an "fsck --strict" here at the end let's incorporate
    +    the creation of the "mytag" name into this test, removing the
    +    special-case at the end of the file.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t3800-mktag.sh ##
    @@ t/t3800-mktag.sh: check_verify_failure () {
     +	test_expect_success "$1" '
     +		git hash-object -t tag -w --stdin <tag.sig >expected &&
     +		git fsck --strict &&
    ++
     +		git mktag <tag.sig >hash &&
    -+		git fsck --strict &&
    -+		test_cmp expected hash
    ++		test_cmp expected hash &&
    ++		test_when_finished "git update-ref -d refs/tags/mytag $(cat hash)" &&
    ++		git update-ref refs/tags/mytag $(cat hash) $(test_oid zero) &&
    ++		git fsck --strict	
     +	'
     +}
     +
    @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 -0500
      
      EOF
      
    --test_expect_success 'allow extra newlines at end of headers' '
    +-test_expect_success 'require a blank line before an empty body (1)' '
     -	git mktag <tag.sig
     -'
    -+test_expect_mktag_success 'allow extra newlines at end of headers'
    ++test_expect_mktag_success 'require a blank line before an empty body (1)'
      
    - space=' '
      cat >tag.sig <<EOF
    + object $head
     @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 -0500
      
      EOF
      
     -test_expect_success 'create valid tag' '
     -	git mktag <tag.sig >hash &&
    +-	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero) &&
    +-	git fsck --strict
    +-'
     +test_expect_mktag_success 'create valid tag object'
    -+test_expect_success 'create valid tag name' '
    - 	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero)
    - '
      
    + test_done
 6:  9effb4532bc ! 12:  6cbf9176c35 mktag tests: improve verify_object() test coverage
    @@ Commit message
         Let's split these tests up, so we're testing all combinations of a
         non-existing object and in invalid/wrong "type" lines.
     
    +    We need to provide GIT_TEST_GETTEXT_POISON=false here because the
    +    "invalid object type" error is emitted by
    +    parse_loose_header_extended(), which has that message already marked
    +    for translation. Another option would be to use test_i18ngrep, but I
    +    prefer always running the test, not skipping it under gettext poison
    +    testing.
    +
    +    I'm not testing this in combination with "git replace". That'll be
    +    done in a subsequent commit.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## t/t3800-mktag.sh ##
    +@@ t/t3800-mktag.sh: test_description='git mktag: tag object verify test'
    + check_verify_failure () {
    + 	expect="$2"
    + 	test_expect_success "$1" '
    +-		test_must_fail git mktag <tag.sig 2>message &&
    ++		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
    ++			git mktag <tag.sig 2>message &&
    + 		grep "$expect" message
    + 	'
    + }
     @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
      	'^error: char.*: type too long$'
      
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
      EOF
      
     -check_verify_failure 'verify object (SHA1/type) check' \
    -+check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
    ++check_verify_failure 'verify object (hash/type) check -- made-up type, valid object' \
     +	'^fatal: invalid object type'
     +
     +cat >tag.sig <<EOF
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
     +
     +EOF
     +
    -+check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
    ++check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
      	'^error: char7: could not verify object.*$'
      
     +cat >tag.sig <<EOF
    @@ t/t3800-mktag.sh: check_verify_failure '"type" line type-name length check' \
     +
     +EOF
     +
    -+check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
    ++check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
     +	'^error: char7: could not verify object'
     +
      ############################################################
 -:  ----------- > 13:  ca1567866b0 mktag tests: test verify_object() with replaced objects
11:  1e2e4ec2697 = 14:  ac31d8658f3 mktag: use default strbuf_read() hint
12:  be2ab3edab0 = 15:  e32292af8b4 mktag: remove redundant braces in one-line body "if"
13:  d8514df970c = 16:  405fd2c747d mktag: use puts(str) instead of printf("%s\n", str)
14:  346d73cc972 ! 17:  6edaa992a25 mktag: use fsck instead of custom verify_tag()
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
    - check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
    + check_verify_failure 'verify object (hash/type) check -- made-up type, valid object' \
     -	'^fatal: invalid object type'
     +	'^error:.* badType:'
      
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
    - check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
    + check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
     -	'^error: char7: could not verify object.*$'
     +	'^error:.* badType:'
      
    @@ t/t3800-mktag.sh: tagger . <> 0 +0000
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
      EOF
      
    - check_verify_failure 'verify object (hash/type) check -- incorrect type, valid object' \
    + check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
     -	'^error: char7: could not verify object'
     +	'^fatal: object.*tagged as.*tree.*but is.*commit'
      
    + ############################################################
    + #  9.5. verify object (hash/type) check -- replacement
    +@@ t/t3800-mktag.sh: tagger . <> 0 +0000
    + EOF
    + 
    + check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
    +-	'^error: char7: could not verify object'
    ++	'^fatal: object.*tagged as.*tree.*but is.*blob'
    + 
      ############################################################
      # 10. verify tag-name check
     @@ t/t3800-mktag.sh: tagger . <> 0 +0000
    @@ t/t3800-mktag.sh: this line should not be here
     -	'^error: char.*: trailing garbage in tag header$'
     +	'^error:.* extraHeaderEntry:'
      
    - cat >tag.sig <<EOF
    - object $head
    -@@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 -0500$space
    - EOF
    - 
    - check_verify_failure 'extra whitespace at end of headers' \
    --	'^error: char.*: malformed tag timezone$'
    -+	'^error:.* badTimezone:'
    - 
      cat >tag.sig <<EOF
      object $head
     @@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 -0500
      EOF
      
    - check_verify_failure 'disallow no header / body newline separator' \
    + check_verify_failure 'require a blank line before an empty body (2)' \
     -	'^error: char.*: trailing garbage in tag header$'
     +	'^error:.* extraHeaderEntry:'
      
15:  0e7994d8fc3 = 18:  4c3fbb7ed58 fsck: make fsck_config() re-usable
16:  5e8046022b6 = 19:  32fc2264ec1 mktag: allow turning off fsck.extraHeaderEntry
17:  32698e1d005 ! 20:  32922a42dda mktag: allow omitting the header/body \n separator
    @@ fsck.c: int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
      		/*
     
      ## t/t3800-mktag.sh ##
    +@@ t/t3800-mktag.sh: tagger T A Gger <tagger@example.com> 1206478233 -0500
    + 
    + EOF
    + 
    +-test_expect_mktag_success 'require a blank line before an empty body (1)'
    ++test_expect_mktag_success 'allow a blank line before an empty body (1)'
    + 
    + cat >tag.sig <<EOF
    + object $head
     @@ t/t3800-mktag.sh: tag mytag
      tagger T A Gger <tagger@example.com> 1206478233 -0500
      EOF
      
    --check_verify_failure 'disallow no header / body newline separator' \
    +-check_verify_failure 'require a blank line before an empty body (2)' \
     -	'^error:.* extraHeaderEntry:'
    -+test_expect_success 'allow no header / body newline separator' '
    -+	git mktag <tag.sig
    -+'
    ++test_expect_mktag_success 'allow no blank line before an empty body (2)'
      
      ############################################################
      # 24. create valid tag
18:  b6a22f2f992 ! 21:  3c991dda02b mktag: convert to parse-options
    @@ builtin/mktag.c: static int verify_object_in_tag(struct object_id *tagged_oid, i
     
      ## t/t3800-mktag.sh ##
     @@ t/t3800-mktag.sh: test_expect_success 'setup' '
    - 	head=$(git rev-parse --verify HEAD)
    + 	blob=$(git rev-parse --verify HEAD:B.t)
      '
      
     +test_expect_success 'basic usage' '
19:  7fc0b81df7d ! 22:  16db5858a08 mktag: mark strings for translation
    @@ builtin/mktag.c: int cmd_mktag(int argc, const char **argv, const char *prefix)
      
      	strbuf_release(&buf);
      	puts(oid_to_hex(&result));
    -
    - ## t/t3800-mktag.sh ##
    -@@ t/t3800-mktag.sh: test_description='git mktag: tag object verify test'
    - check_verify_failure () {
    - 	expect="$2"
    - 	test_expect_success "$1" '
    --		test_must_fail git mktag <tag.sig 2>message &&
    -+		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
    -+			git mktag <tag.sig 2>message &&
    - 		grep "$expect" message
    - 	'
    - }
20:  6fa443d528c ! 23:  94d6aca6962 mktag: add a --no-strict option
    @@ Documentation/git-mktag.txt: SYNOPSIS
     +OPTIONS
     +-------
     +
    -+--no-strict::
    ++--strict::
     +	By default mktag turns on the equivalent of
    -+	linkgit:git-fsck[1] `--strict` mode. This disables it.
    ++	linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to
    ++	disable it.
     +
      DESCRIPTION
      -----------
    @@ builtin/mktag.c: static char const * const builtin_mktag_usage[] = {
      	N_("git mktag"),
      	NULL
      };
    -+static int option_no_strict;
    ++static int option_strict = 1;
      
      static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
      
    @@ builtin/mktag.c: static int mktag_fsck_error_func(struct fsck_options *o,
      {
      	switch (msg_type) {
      	case FSCK_WARN:
    -+		if (option_no_strict) {
    ++		if (!option_strict) {
     +			fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
     +			return 0;
     +
    @@ builtin/mktag.c: static int verify_object_in_tag(struct object_id *tagged_oid, i
      int cmd_mktag(int argc, const char **argv, const char *prefix)
      {
      	static struct option builtin_mktag_options[] = {
    -+		OPT_NO_BOOL(0, "no-strict", &option_no_strict,
    -+			    N_("don't do strict fsck checks")),
    ++		OPT_BOOL(0, "strict", &option_strict,
    ++			 N_("enable more strict checking")),
      		OPT_END(),
      	};
      	struct strbuf buf = STRBUF_INIT;
     
    - ## parse-options.h ##
    -@@ parse-options.h: struct option {
    - #define OPT_COUNTUP(s, l, v, h)     OPT_COUNTUP_F(s, l, v, h, 0)
    - #define OPT_SET_INT(s, l, v, h, i)  OPT_SET_INT_F(s, l, v, h, i, 0)
    - #define OPT_BOOL(s, l, v, h)        OPT_BOOL_F(s, l, v, h, 0)
    -+#define OPT_NO_BOOL(s, l, v, h)     OPT_BOOL_F(s, l, v, h, PARSE_OPT_NONEG)
    - #define OPT_HIDDEN_BOOL(s, l, v, h) { OPTION_SET_INT, (s), (l), (v), NULL, \
    - 				      (h), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1}
    - #define OPT_CMDMODE(s, l, v, h, i)  { OPTION_SET_INT, (s), (l), (v), NULL, \
    -
      ## t/t3800-mktag.sh ##
     @@ t/t3800-mktag.sh: test_description='git mktag: tag object verify test'
      # given in the expect.pat file.
    @@ t/t3800-mktag.sh: test_description='git mktag: tag object verify test'
     +		grep '$2' message &&
     +		if test '$3' != '--no-strict'
     +		then
    -+			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&
    ++			test_must_fail env GIT_TEST_GETTEXT_POISON=false \
    ++				git mktag --no-strict <tag.sig 2>message.no-strict &&
     +			grep '$2' message.no-strict
     +		fi
     +	"
      }
      
      test_expect_mktag_success() {
    -@@ t/t3800-mktag.sh: test_expect_success 'basic usage' '
    - 	EOF
    - 	git mktag <tag.sig &&
    - 	git mktag --end-of-options <tag.sig &&
    --	test_expect_code 129 git mktag --unknown-option
    -+	test_expect_code 129 git mktag --unknown-option &&
    -+	test_expect_code 129 git mktag --strict
    - '
    - 
    - ############################################################
     @@ t/t3800-mktag.sh: too short for a tag
      EOF
      
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 01/23] mktag doc: say <hash> not <sha1>
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
  2020-12-23 13:54                 ` Junio C Hamano
  2021-01-05 19:42                 ` [PATCH v5 00/23] " Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 02/23] mktag doc: grammar fix, when exists -> when it exists Ævar Arnfjörð Bjarmason
                                   ` (21 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change the "mktag" documentation to refer to the input hash as just
"hash", not "sha1". This command has supported SHA-256 for a while
now.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index fa6a7561236..a158428eb9f 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -23,7 +23,7 @@ Tag Format
 A tag signature file, to be fed to this command's standard input,
 has a very simple fixed format: four lines of
 
-  object <sha1>
+  object <hash>
   type <typename>
   tag <tagname>
   tagger <tagger>
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 02/23] mktag doc: grammar fix, when exists -> when it exists
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (2 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 01/23] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 03/23] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
                                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Amend the wording of documentation added in 6cfec03680 (mktag:
minimally update the description., 2007-06-10). It makes more sense to
say "when it exists" here, as we're referring to "the message".

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index a158428eb9f..1b0667e372a 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -29,7 +29,7 @@ has a very simple fixed format: four lines of
   tagger <tagger>
 
 followed by some 'optional' free-form message (some tags created
-by older Git may not have `tagger` line).  The message, when
+by older Git may not have `tagger` line).  The message, when it
 exists, is separated by a blank line from the header.  The
 message part may contain a signature that Git itself doesn't
 care about, but that can be verified with gpg.
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 03/23] mktag doc: update to explain why to use this
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (3 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 02/23] mktag doc: grammar fix, when exists -> when it exists Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 04/23] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
                                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change the mktag documentation to compare itself to the similar
"hash-object -t tag" command. Before this someone reading the
documentation wouldn't have much of an idea what the difference
was.

Let's allude to our own validation logic, and cross-link the "mktag"
and "hash-object" documentation to aid discover-ability. A follow-up
change to migrate "mktag" to use "fsck" validation will make the part
about validation logic clearer.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 1b0667e372a..20af1915e9e 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -3,7 +3,7 @@ git-mktag(1)
 
 NAME
 ----
-git-mktag - Creates a tag object
+git-mktag - Creates a tag object with extra validation
 
 
 SYNOPSIS
@@ -13,10 +13,19 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Reads a tag contents on standard input and creates a tag object
-that can also be used to sign other objects.
 
-The output is the new tag's <object> identifier.
+Reads a tag contents on standard input and creates a tag object. The
+output is the new tag's <object> identifier.
+
+This command is mostly equivalent to linkgit:git-hash-object[1]
+invoked with `-t tag -w --stdin`. I.e. both of these will create and
+write a tag found in `my-tag`:
+
+    git mktag <my-tag
+    git hash-object -t tag -w --stdin <my-tag
+
+The difference is that mktag will die before writing the tag if the
+tag doesn't pass a sanity check.
 
 Tag Format
 ----------
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 04/23] mktag tests: don't needlessly use a subshell
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (4 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 03/23] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 05/23] mktag tests: use "test_commit" helper Ævar Arnfjörð Bjarmason
                                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

The use of a subshell dates back to e9b20943b77 (t/t3800: do not use a
temporary file to hold expected result., 2008-01-04). It's not needed
anymore, if it ever was.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index d696aa4e52e..0e411e3c45f 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -14,7 +14,7 @@ test_description='git mktag: tag object verify test'
 check_verify_failure () {
 	expect="$2"
 	test_expect_success "$1" '
-		( test_must_fail git mktag <tag.sig 2>message ) &&
+		test_must_fail git mktag <tag.sig 2>message &&
 		grep "$expect" message
 	'
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 05/23] mktag tests: use "test_commit" helper
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (5 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 04/23] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 06/23] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
                                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Replace ad-hoc setup of a single commit in the "mktag" tests with our
standard helper pattern. The old setup dated back to 446c6faec69 (New
tests and en-passant modifications to mktag., 2006-07-29) before the
helper existed.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0e411e3c45f..dd21a1247a2 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -23,9 +23,7 @@ check_verify_failure () {
 # first create a commit, so we have a valid object/type
 # for the tag.
 test_expect_success 'setup' '
-	echo Hello >A &&
-	git update-index --add A &&
-	git commit -m "Initial commit" &&
+	test_commit A &&
 	head=$(git rev-parse --verify HEAD)
 '
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 06/23] mktag tests: remove needless SHA-1 hardcoding
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (6 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 05/23] mktag tests: use "test_commit" helper Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 07/23] mktag tests: don't redirect stderr to a file needlessly Ævar Arnfjörð Bjarmason
                                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change the tests amended in acb49d1cc8b (t3800: make hash-size
independent, 2019-08-18) even more to make them independent of either
SHA-1 or SHA-256.

Some of these tests were failing for the wrong reasons. The first one
being modified here would fail because the line starts with "xxxxxx"
instead of "object", the rest of the line doesn't matter.

Let's just put a valid hash on the rest of the line anyway to narrow
the test down for just the s/object/xxxxxx/ case.

The second one being modified here would fail under
GIT_TEST_DEFAULT_HASH=sha256 because <some sha-1 length garbage> is an
invalid SHA-256, but we should really be testing <some sha-256 length
garbage> when under SHA-256.

This doesn't really matter since we should be able to trust other
parts of the code to validate things in the 0-9a-f range, but let's
keep it for good measure.

There's a later test which tests an invalid SHA which looks like a
valid one, to stress the "We refuse to tag something we can't
verify[...]" logic in mktag.c.

But here we're testing for a SHA-length string which contains
characters outside of the /[0-9a-f]/i set.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index dd21a1247a2..e1a2892f58b 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -41,7 +41,7 @@ check_verify_failure 'Tag object length check' \
 #  2. object line label check
 
 cat >tag.sig <<EOF
-xxxxxx 139e9b33986b1c2670fff52c5067603117b3e895
+xxxxxx $head
 type tag
 tag mytag
 tagger . <> 0 +0000
@@ -51,10 +51,10 @@ EOF
 check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
 
 ############################################################
-#  3. object line SHA1 check
+#  3. object line hash check
 
 cat >tag.sig <<EOF
-object zz9e9b33986b1c2670fff52c5067603117b3e895
+object $(echo $head | tr 0-9a-f z)
 type tag
 tag mytag
 tagger . <> 0 +0000
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 07/23] mktag tests: don't redirect stderr to a file needlessly
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (7 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 06/23] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 08/23] mktag tests: don't create "mytag" twice Ævar Arnfjörð Bjarmason
                                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Remove the redirection of stderr to "message" in the valid tag
test. This pattern seems to have been copy/pasted from the failure
case in 446c6faec6 (New tests and en-passant modifications to mktag.,
2006-07-29).

While I'm at it do the same for the "replace" tests. The tag creation
I'm changing here seems to have been copy/pasted from the "mktag"
tests to those tests in cc400f50112 (mktag: call
"check_sha1_signature" with the replacement sha1, 2009-01-23).

Nobody examines the contents of the resulting "message" file, so the
net result is that error messages cannot be seen in "sh t3800-mktag.sh
-v" output.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh   | 4 ++--
 t/t6050-replace.sh | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index e1a2892f58b..c542c3e1a8e 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -222,7 +222,7 @@ EOF
 
 test_expect_success \
     'allow empty tag email' \
-    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
+    'git mktag <tag.sig >.git/refs/tags/mytag'
 
 ############################################################
 # 16. disallow spaces in tag email
@@ -350,7 +350,7 @@ EOF
 
 test_expect_success \
     'create valid tag' \
-    'git mktag <tag.sig >.git/refs/tags/mytag 2>message'
+    'git mktag <tag.sig >.git/refs/tags/mytag'
 
 ############################################################
 # 25. check mytag
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index c80dc10b8f1..0dbe086118a 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -129,7 +129,7 @@ tagger T A Gger <> 0 +0000
 EOF
 
 test_expect_success 'tag replaced commit' '
-     git mktag <tag.sig >.git/refs/tags/mytag 2>message
+     git mktag <tag.sig >.git/refs/tags/mytag
 '
 
 test_expect_success '"git fsck" works' '
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 08/23] mktag tests: don't create "mytag" twice
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (8 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 07/23] mktag tests: don't redirect stderr to a file needlessly Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 09/23] mktag tests: run "fsck" after creating "mytag" Ævar Arnfjörð Bjarmason
                                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change a test added in e0aaf781f6 (mktag.c: improve verification of
tagger field and tests, 2008-03-27) to not create "mytag", which
should only be created and verified at the end in an earlier test
added in 446c6faec6 (New tests and en-passant modifications to mktag.,
2006-07-29).

While we're at it let's prevent a similar logic error from creeping
into the test by asserting that "mytag" doesn't exist before we create
it. Let's do this by moving the test to use "update-ref", instead of
our own homebrew ad-hoc refstore update.

We're not really testing for anything yet by creating the tag at the
end here. A subsequent commit will change that.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index c542c3e1a8e..bb300d567db 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -222,7 +222,7 @@ EOF
 
 test_expect_success \
     'allow empty tag email' \
-    'git mktag <tag.sig >.git/refs/tags/mytag'
+    'git mktag <tag.sig'
 
 ############################################################
 # 16. disallow spaces in tag email
@@ -348,16 +348,9 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 
 EOF
 
-test_expect_success \
-    'create valid tag' \
-    'git mktag <tag.sig >.git/refs/tags/mytag'
-
-############################################################
-# 25. check mytag
-
-test_expect_success \
-    'check mytag' \
-    'git tag -l | grep mytag'
-
+test_expect_success 'create valid tag' '
+	git mktag <tag.sig >hash &&
+	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero)
+'
 
 test_done
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 09/23] mktag tests: run "fsck" after creating "mytag"
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (9 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 08/23] mktag tests: don't create "mytag" twice Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 10/23] mktag tests: stress test whitespace handling Ævar Arnfjörð Bjarmason
                                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change the last test in the file to run an "fsck --strict" after
creating the tag at the end.

We're just doing this for good measure to check that fsck behaves as
expected now that there's finally a reference for our valid tag. Other
tests going to be checking this elsewhere, but it's nice to cover all
the edge cases in this test to make it as self-contained as possible.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index bb300d567db..048000cda9a 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -350,7 +350,8 @@ EOF
 
 test_expect_success 'create valid tag' '
 	git mktag <tag.sig >hash &&
-	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero)
+	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero) &&
+	git fsck --strict
 '
 
 test_done
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 10/23] mktag tests: stress test whitespace handling
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (10 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 09/23] mktag tests: run "fsck" after creating "mytag" Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 11/23] mktag tests: test "hash-object" compatibility Ævar Arnfjörð Bjarmason
                                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Add tests for a couple of whitespace edge cases around the header/body
boundary.

I consider the requirement for a blank line before the empty body a
bug, it's a long-standing regression which goes against the command's
documented behavior. This bug will be addressed in a follow-up change.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 048000cda9a..661b62f0912 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -337,6 +337,42 @@ EOF
 check_verify_failure 'detect invalid header entry' \
 	'^error: char.*: trailing garbage in tag header$'
 
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+
+
+this line comes after an extra newline
+EOF
+
+test_expect_success 'allow extra newlines at start of body' '
+	git mktag <tag.sig
+'
+
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+
+EOF
+
+test_expect_success 'require a blank line before an empty body (1)' '
+	git mktag <tag.sig
+'
+
+cat >tag.sig <<EOF
+object $head
+type commit
+tag mytag
+tagger T A Gger <tagger@example.com> 1206478233 -0500
+EOF
+
+check_verify_failure 'require a blank line before an empty body (2)' \
+	'^error: char.*: trailing garbage in tag header$'
+
 ############################################################
 # 24. create valid tag
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 11/23] mktag tests: test "hash-object" compatibility
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (11 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 10/23] mktag tests: stress test whitespace handling Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 12/23] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
                                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change all the successful "mktag" tests to test that "hash-object"
produces the same hash for the input, and that fsck passes for
both.

This tests e.g. that "mktag" doesn't trim its input or otherwise munge
it in a way that "hash-object" doesn't.

Since we're doing an "fsck --strict" here at the end let's incorporate
the creation of the "mytag" name into this test, removing the
special-case at the end of the file.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 661b62f0912..47380292223 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -19,6 +19,19 @@ check_verify_failure () {
 	'
 }
 
+test_expect_mktag_success() {
+	test_expect_success "$1" '
+		git hash-object -t tag -w --stdin <tag.sig >expected &&
+		git fsck --strict &&
+
+		git mktag <tag.sig >hash &&
+		test_cmp expected hash &&
+		test_when_finished "git update-ref -d refs/tags/mytag $(cat hash)" &&
+		git update-ref refs/tags/mytag $(cat hash) $(test_oid zero) &&
+		git fsck --strict	
+	'
+}
+
 ###########################################################
 # first create a commit, so we have a valid object/type
 # for the tag.
@@ -220,9 +233,7 @@ tagger T A Gger <> 0 +0000
 
 EOF
 
-test_expect_success \
-    'allow empty tag email' \
-    'git mktag <tag.sig'
+test_expect_mktag_success 'allow empty tag email'
 
 ############################################################
 # 16. disallow spaces in tag email
@@ -347,9 +358,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 this line comes after an extra newline
 EOF
 
-test_expect_success 'allow extra newlines at start of body' '
-	git mktag <tag.sig
-'
+test_expect_mktag_success 'allow extra newlines at start of body'
 
 cat >tag.sig <<EOF
 object $head
@@ -359,9 +368,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 
 EOF
 
-test_expect_success 'require a blank line before an empty body (1)' '
-	git mktag <tag.sig
-'
+test_expect_mktag_success 'require a blank line before an empty body (1)'
 
 cat >tag.sig <<EOF
 object $head
@@ -384,10 +391,6 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 
 EOF
 
-test_expect_success 'create valid tag' '
-	git mktag <tag.sig >hash &&
-	git update-ref refs/tags/mytag $(cat hash) $(test_oid zero) &&
-	git fsck --strict
-'
+test_expect_mktag_success 'create valid tag object'
 
 test_done
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 12/23] mktag tests: improve verify_object() test coverage
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (12 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 11/23] mktag tests: test "hash-object" compatibility Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-10 13:21                   ` SZEDER Gábor
  2021-01-05 19:42                 ` [PATCH v5 13/23] mktag tests: test verify_object() with replaced objects Ævar Arnfjörð Bjarmason
                                   ` (10 subsequent siblings)
  24 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

The verify_object() function in "mktag.c" is tasked with ensuring that
our tag refers to a valid object.

The existing test for this might fail because it was also testing that
"type taggg" didn't refer to a valid object type (it should be "type
tag"), or because we referred to a valid object but got the type
wrong.

Let's split these tests up, so we're testing all combinations of a
non-existing object and in invalid/wrong "type" lines.

We need to provide GIT_TEST_GETTEXT_POISON=false here because the
"invalid object type" error is emitted by
parse_loose_header_extended(), which has that message already marked
for translation. Another option would be to use test_i18ngrep, but I
prefer always running the test, not skipping it under gettext poison
testing.

I'm not testing this in combination with "git replace". That'll be
done in a subsequent commit.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 40 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 47380292223..ced540035d4 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -14,7 +14,8 @@ test_description='git mktag: tag object verify test'
 check_verify_failure () {
 	expect="$2"
 	test_expect_success "$1" '
-		test_must_fail git mktag <tag.sig 2>message &&
+		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
+			git mktag <tag.sig 2>message &&
 		grep "$expect" message
 	'
 }
@@ -136,19 +137,52 @@ check_verify_failure '"type" line type-name length check' \
 	'^error: char.*: type too long$'
 
 ############################################################
-#  9. verify object (SHA1/type) check
+#  9. verify object (hash/type) check
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
+type tag
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
+	'^error: char7: could not verify object.*$'
+
+cat >tag.sig <<EOF
+object $head
 type tagggg
 tag mytag
 tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure 'verify object (SHA1/type) check' \
+check_verify_failure 'verify object (hash/type) check -- made-up type, valid object' \
+	'^fatal: invalid object type'
+
+cat >tag.sig <<EOF
+object $(test_oid deadbeef)
+type tagggg
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
 	'^error: char7: could not verify object.*$'
 
+cat >tag.sig <<EOF
+object $head
+type tree
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
+	'^error: char7: could not verify object'
+
 ############################################################
 # 10. verify tag-name check
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 13/23] mktag tests: test verify_object() with replaced objects
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (13 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 12/23] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 14/23] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
                                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Add tests to demonstrate what "mktag" does in the face of replaced
objects.

There was an existing test for replaced objects fed to "mktag" added
in cc400f50112 (mktag: call "check_sha1_signature" with the
replacement sha1, 2009-01-23), but that one only tests a
commit->commit mapping. Not a mapping to a different type as like
we're also testing for here. We could remove the "mktag" test in
t6050-replace.sh now if the created tag wasn't being used by a
subsequent "fsck" test.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index ced540035d4..fbaf648491f 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -38,7 +38,11 @@ test_expect_mktag_success() {
 # for the tag.
 test_expect_success 'setup' '
 	test_commit A &&
-	head=$(git rev-parse --verify HEAD)
+	test_commit B &&
+	head=$(git rev-parse --verify HEAD) &&
+	head_parent=$(git rev-parse --verify HEAD~) &&
+	tree=$(git rev-parse HEAD^{tree}) &&
+	blob=$(git rev-parse --verify HEAD:B.t)
 '
 
 ############################################################
@@ -180,6 +184,35 @@ tagger . <> 0 +0000
 
 EOF
 
+check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
+	'^error: char7: could not verify object'
+
+############################################################
+#  9.5. verify object (hash/type) check -- replacement
+
+test_expect_success 'setup replacement of commit -> commit and tree -> blob' '
+	git replace $head_parent $head &&
+	git replace -f $tree $blob
+'
+
+cat >tag.sig <<EOF
+object $head_parent
+type commit
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
+test_expect_mktag_success 'tag to a commit replaced by another commit'
+
+cat >tag.sig <<EOF
+object $tree
+type tree
+tag mytag
+tagger . <> 0 +0000
+
+EOF
+
 check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
 	'^error: char7: could not verify object'
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 14/23] mktag: use default strbuf_read() hint
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (14 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 13/23] mktag tests: test verify_object() with replaced objects Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 15/23] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
                                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change the hardcoded hint of 2^12 to 0. The default strbuf hint is
perfectly fine here, and the only reason we were hardcoding it is
because it survived migration from a pre-strbuf fixed-sized buffer.

See fd17f5b5f77 (Replace all read_fd use with strbuf_read, and get rid
of it., 2007-09-10) for that migration.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4982d3a93ef..ff7ac8e0e5d 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,7 +161,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 4096) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0) {
 		die_errno("could not read from stdin");
 	}
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 15/23] mktag: remove redundant braces in one-line body "if"
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (15 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 14/23] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 16/23] mktag: use puts(str) instead of printf("%s\n", str) Ævar Arnfjörð Bjarmason
                                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

This minor stylistic churn is usually something we'd avoid, but if we
don't do this then the file after changes in subsequent commits will
only have this minor style inconsistency, so let's change this while
we're at it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index ff7ac8e0e5d..97ca5f28b1b 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -161,9 +161,8 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (argc != 1)
 		usage("git mktag");
 
-	if (strbuf_read(&buf, 0, 0) < 0) {
+	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
-	}
 
 	/* Verify it for some basic sanity: it needs to start with
 	   "object <sha1>\ntype\ntagger " */
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 16/23] mktag: use puts(str) instead of printf("%s\n", str)
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (16 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 15/23] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 17/23] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
                                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

This introduces no functional change, but refactors the print-out of
the hash at the end to do the same thing with less code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 97ca5f28b1b..d89a3c201de 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -173,6 +173,6 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 		die("unable to write tag file");
 
 	strbuf_release(&buf);
-	printf("%s\n", oid_to_hex(&result));
+	puts(oid_to_hex(&result));
 	return 0;
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 17/23] mktag: use fsck instead of custom verify_tag()
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (17 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 16/23] mktag: use puts(str) instead of printf("%s\n", str) Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 18/23] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
                                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change the validation logic in "mktag" to use fsck's fsck_tag()
instead of its own custom parser. Curiously the logic for both dates
back to the same commit[1]. Let's unify them so we're not maintaining
two sets functions to verify that a tag is OK.

The behavior of fsck_tag() and the old "mktag" code being removed here
is different in few aspects.

I think it makes sense to remove some of those checks, namely:

 A. fsck only cares that the timezone matches [-+][0-9]{4}. The mktag
    code disallowed values larger than 1400.

    Yes there's currently no timezone with a greater offset[2], but
    since we allow any number of non-offical timezones (e.g. +1234)
    passing this through seems fine. Git also won't break in the
    future if e.g. French Polynesia decides it needs to outdo the Line
    Islands when it comes to timezone extravagance.

 B. fsck allows missing author names such as "tagger <email>", mktag
    wouldn't, but would allow e.g. "tagger [2 spaces] <email>" (but
    not "tagger [1 space] <email>"). Now we allow all of these.

 C. Like B, but "mktag" disallowed spaces in the <email> part, fsck
    allows it.

In some ways fsck_tag() is stricter than "mktag" was, namely:

 D. fsck disallows zero-padded dates, but mktag didn't care. So
    e.g. the timestamp "0000000000 +0000" produces an error now. A
    test in "t1006-cat-file.sh" relied on this, it's been changed to
    use "hash-object" (without fsck) instead.

There was one check I deemed worth keeping by porting it over to
fsck_tag():

 E. "mktag" did not allow any custom headers, and by extension (as an
    empty commit is allowed) also forbade an extra stray trailing
    newline after the headers it knew about.

    Add a new check in the "ignore" category to fsck and use it. This
    somewhat abuses the facility added in efaba7cc77f (fsck:
    optionally ignore specific fsck issues completely, 2015-06-22).

    This is somewhat of hack, but probably the least invasive change
    we can make here. The fsck command will shuffle these categories
    around, e.g. under --strict the "info" becomes a "warn" and "warn"
    becomes "error". Existing users of fsck's (and others,
    e.g. index-pack) --strict option rely on this.

    So we need to put something into a category that'll be ignored by
    all existing users of the API. Pretending that
    fsck.extraHeaderEntry=error ("ignore" by default) was set serves
    to do this for us.

1. ec4465adb38 (Add "tag" objects that can be used to sign other
   objects., 2005-04-25)

2. https://en.wikipedia.org/wiki/List_of_UTC_time_offsets

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt |   9 +-
 builtin/mktag.c             | 196 +++++++++---------------------------
 fsck.c                      |  32 +++++-
 fsck.h                      |   9 ++
 t/t1006-cat-file.sh         |   2 +-
 t/t3800-mktag.sh            |  63 ++++++------
 6 files changed, 127 insertions(+), 184 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 20af1915e9e..fa070e21a0b 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -25,7 +25,14 @@ write a tag found in `my-tag`:
     git hash-object -t tag -w --stdin <my-tag
 
 The difference is that mktag will die before writing the tag if the
-tag doesn't pass a sanity check.
+tag doesn't pass a linkgit:git-fsck[1] check.
+
+The "fsck" check done mktag is stricter than what linkgit:git-fsck[1]
+would run by default in that all `fsck.<msg-id>` messages are promoted
+from warnings to errors (so e.g. a missing "tagger" line is an error).
+
+Extra headers in the object are also an error under mktag, but ignored
+by linkgit:git-fsck[1]
 
 Tag Format
 ----------
diff --git a/builtin/mktag.c b/builtin/mktag.c
index d89a3c201de..4dd35bc79e2 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -2,160 +2,60 @@
 #include "tag.h"
 #include "replace-object.h"
 #include "object-store.h"
+#include "fsck.h"
 
-/*
- * A signature file has a very simple fixed format: four lines
- * of "object <sha1>" + "type <typename>" + "tag <tagname>" +
- * "tagger <committer>", followed by a blank line, a free-form tag
- * message and a signature block that git itself doesn't care about,
- * but that can be verified with gpg or similar.
- *
- * The first four lines are guaranteed to be at least 83 bytes:
- * "object <sha1>\n" is 48 bytes, "type tag\n" at 9 bytes is the
- * shortest possible type-line, "tag .\n" at 6 bytes is the shortest
- * single-character-tag line, and "tagger . <> 0 +0000\n" at 20 bytes is
- * the shortest possible tagger-line.
- */
-
-/*
- * We refuse to tag something we can't verify. Just because.
- */
-static int verify_object(const struct object_id *oid, const char *expected_type)
+static int mktag_fsck_error_func(struct fsck_options *o,
+				 const struct object_id *oid,
+				 enum object_type object_type,
+				 int msg_type, const char *message)
 {
-	int ret = -1;
-	enum object_type type;
-	unsigned long size;
-	void *buffer = read_object_file(oid, &type, &size);
-	const struct object_id *repl = lookup_replace_object(the_repository, oid);
-
-	if (buffer) {
-		if (type == type_from_string(expected_type)) {
-			ret = check_object_signature(the_repository, repl,
-						     buffer, size,
-						     expected_type);
-		}
-		free(buffer);
+	switch (msg_type) {
+	case FSCK_WARN:
+	case FSCK_ERROR:
+		/*
+		 * We treat both warnings and errors as errors, things
+		 * like missing "tagger" lines are "only" warnings
+		 * under fsck, we've always considered them an error.
+		 */
+		fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message);
+		return 1;
+	default:
+		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
+		    msg_type);
 	}
-	return ret;
 }
 
-static int verify_tag(char *buffer, unsigned long size)
+static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 {
-	int typelen;
-	char type[20];
-	struct object_id oid;
-	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
-	size_t len;
-
-	if (size < 84)
-		return error("wanna fool me ? you obviously got the size wrong !");
-
-	buffer[size] = 0;
-
-	/* Verify object line */
-	object = buffer;
-	if (memcmp(object, "object ", 7))
-		return error("char%d: does not start with \"object \"", 0);
-
-	if (parse_oid_hex(object + 7, &oid, &p))
-		return error("char%d: could not get SHA1 hash", 7);
-
-	/* Verify type line */
-	type_line = p + 1;
-	if (memcmp(type_line - 1, "\ntype ", 6))
-		return error("char%d: could not find \"\\ntype \"", 47);
-
-	/* Verify tag-line */
-	tag_line = strchr(type_line, '\n');
-	if (!tag_line)
-		return error("char%"PRIuMAX": could not find next \"\\n\"",
-				(uintmax_t) (type_line - buffer));
-	tag_line++;
-	if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
-		return error("char%"PRIuMAX": no \"tag \" found",
-				(uintmax_t) (tag_line - buffer));
-
-	/* Get the actual type */
-	typelen = tag_line - type_line - strlen("type \n");
-	if (typelen >= sizeof(type))
-		return error("char%"PRIuMAX": type too long",
-				(uintmax_t) (type_line+5 - buffer));
-
-	memcpy(type, type_line+5, typelen);
-	type[typelen] = 0;
-
-	/* Verify that the object matches */
-	if (verify_object(&oid, type))
-		return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));
-
-	/* Verify the tag-name: we don't allow control characters or spaces in it */
-	tag_line += 4;
-	for (;;) {
-		unsigned char c = *tag_line++;
-		if (c == '\n')
-			break;
-		if (c > ' ')
-			continue;
-		return error("char%"PRIuMAX": could not verify tag name",
-				(uintmax_t) (tag_line - buffer));
-	}
-
-	/* Verify the tagger line */
-	tagger_line = tag_line;
-
-	if (memcmp(tagger_line, "tagger ", 7))
-		return error("char%"PRIuMAX": could not find \"tagger \"",
-			(uintmax_t) (tagger_line - buffer));
-
-	/*
-	 * Check for correct form for name and email
-	 * i.e. " <" followed by "> " on _this_ line
-	 * No angle brackets within the name or email address fields.
-	 * No spaces within the email address field.
-	 */
-	tagger_line += 7;
-	if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
-		strpbrk(tagger_line, "<>\n") != lb+1 ||
-		strpbrk(lb+2, "><\n ") != rb)
-		return error("char%"PRIuMAX": malformed tagger field",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* Check for author name, at least one character, space is acceptable */
-	if (lb == tagger_line)
-		return error("char%"PRIuMAX": missing tagger name",
-			(uintmax_t) (tagger_line - buffer));
-
-	/* timestamp, 1 or more digits followed by space */
-	tagger_line = rb + 2;
-	if (!(len = strspn(tagger_line, "0123456789")))
-		return error("char%"PRIuMAX": missing tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += len;
-	if (*tagger_line != ' ')
-		return error("char%"PRIuMAX": malformed tag timestamp",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line++;
-
-	/* timezone, 5 digits [+-]hhmm, max. 1400 */
-	if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
-	      strspn(tagger_line+1, "0123456789") == 4 &&
-	      tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
-		return error("char%"PRIuMAX": malformed tag timezone",
-			(uintmax_t) (tagger_line - buffer));
-	tagger_line += 6;
-
-	/* Verify the blank line separating the header from the body */
-	if (*tagger_line != '\n')
-		return error("char%"PRIuMAX": trailing garbage in tag header",
-			(uintmax_t) (tagger_line - buffer));
+	int ret;
+	enum object_type type;
+	unsigned long size;
+	void *buffer;
+	const struct object_id *repl;
+
+	buffer = read_object_file(tagged_oid, &type, &size);
+	if (!buffer)
+		die("could not read tagged object '%s'",
+		    oid_to_hex(tagged_oid));
+	if (type != *tagged_type)
+		die("object '%s' tagged as '%s', but is a '%s' type",
+		    oid_to_hex(tagged_oid),
+		    type_name(*tagged_type), type_name(type));
+
+	repl = lookup_replace_object(the_repository, tagged_oid);
+	ret = check_object_signature(the_repository, repl,
+				     buffer, size, type_name(*tagged_type));
+	free(buffer);
 
-	/* The actual stuff afterwards we don't care about.. */
-	return 0;
+	return ret;
 }
 
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	struct strbuf buf = STRBUF_INIT;
+	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
+	struct object_id tagged_oid;
+	int tagged_type;
 	struct object_id result;
 
 	if (argc != 1)
@@ -164,10 +64,14 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
 
-	/* Verify it for some basic sanity: it needs to start with
-	   "object <sha1>\ntype\ntagger " */
-	if (verify_tag(buf.buf, buf.len) < 0)
-		die("invalid tag signature file");
+	fsck_options.error_func = mktag_fsck_error_func;
+	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
+	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
+				&tagged_oid, &tagged_type))
+		die("tag on stdin did not pass our strict fsck check");
+
+	if (verify_object_in_tag(&tagged_oid, &tagged_type))
+		die("tag on stdin did not refer to a valid object");
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
 		die("unable to write tag file");
diff --git a/fsck.c b/fsck.c
index f82e2fe9e30..bed5e20e03b 100644
--- a/fsck.c
+++ b/fsck.c
@@ -80,7 +80,9 @@ static struct oidset gitmodules_done = OIDSET_INIT;
 	/* infos (reported as warnings, but ignored by default) */ \
 	FUNC(GITMODULES_PARSE, INFO) \
 	FUNC(BAD_TAG_NAME, INFO) \
-	FUNC(MISSING_TAGGER_ENTRY, INFO)
+	FUNC(MISSING_TAGGER_ENTRY, INFO) \
+	/* ignored (elevated when requested) */ \
+	FUNC(EXTRA_HEADER_ENTRY, IGNORE)
 
 #define MSG_ID(id, msg_type) FSCK_MSG_##id,
 enum fsck_msg_id {
@@ -911,6 +913,16 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		    unsigned long size, struct fsck_options *options)
 {
 	struct object_id tagged_oid;
+	int tagged_type;
+	return fsck_tag_standalone(oid, buffer, size, options, &tagged_oid,
+				   &tagged_type);
+}
+
+int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+			unsigned long size, struct fsck_options *options,
+			struct object_id *tagged_oid,
+			int *tagged_type)
+{
 	int ret = 0;
 	char *eol;
 	struct strbuf sb = STRBUF_INIT;
@@ -924,7 +936,7 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
 		goto done;
 	}
-	if (parse_oid_hex(buffer, &tagged_oid, &p) || *p != '\n') {
+	if (parse_oid_hex(buffer, tagged_oid, &p) || *p != '\n') {
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
 		if (ret)
 			goto done;
@@ -940,7 +952,8 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
 		goto done;
 	}
-	if (type_from_string_gently(buffer, eol - buffer, 1) < 0)
+	*tagged_type = type_from_string_gently(buffer, eol - buffer, 1);
+	if (*tagged_type < 0)
 		ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
 	if (ret)
 		goto done;
@@ -975,6 +988,19 @@ static int fsck_tag(const struct object_id *oid, const char *buffer,
 	else
 		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
 
+	if (!starts_with(buffer, "\n")) {
+		/*
+		 * The verify_headers() check will allow
+		 * e.g. "[...]tagger <tagger>\nsome
+		 * garbage\n\nmessage" to pass, thinking "some
+		 * garbage" could be a custom header. E.g. "mktag"
+		 * doesn't want any unknown headers.
+		 */
+		ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
+		if (ret)
+			goto done;
+	}
+
 done:
 	strbuf_release(&sb);
 	return ret;
diff --git a/fsck.h b/fsck.h
index 69cf715e798..29ee4c45e87 100644
--- a/fsck.h
+++ b/fsck.h
@@ -62,6 +62,15 @@ int fsck_walk(struct object *obj, void *data, struct fsck_options *options);
 int fsck_object(struct object *obj, void *data, unsigned long size,
 	struct fsck_options *options);
 
+/*
+ * fsck a tag, and pass info about it back to the caller. This is
+ * exposed fsck_object() internals for git-mktag(1).
+ */
+int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
+			unsigned long size, struct fsck_options *options,
+			struct object_id *tagged_oid,
+			int *tag_type);
+
 /*
  * Some fsck checks are context-dependent, and may end up queued; run this
  * after completing all fsck_object() calls in order to resolve any remaining
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 2f501d2dc94..5d2dc99b74a 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -166,7 +166,7 @@ tag_content="$tag_header_without_timestamp 0000000000 +0000
 
 $tag_description"
 
-tag_sha1=$(echo_without_newline "$tag_content" | git mktag)
+tag_sha1=$(echo_without_newline "$tag_content" | git hash-object -t tag --stdin -w)
 tag_size=$(strlen "$tag_content")
 
 run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" 1
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index fbaf648491f..0e2a9a883ba 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -53,7 +53,7 @@ too short for a tag
 EOF
 
 check_verify_failure 'Tag object length check' \
-	'^error: .*size wrong.*$'
+	'^error:.* missingObject:'
 
 ############################################################
 #  2. object line label check
@@ -66,7 +66,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line label check' '^error: char0: .*"object "$'
+check_verify_failure '"object" line label check' '^error:.* missingObject:'
 
 ############################################################
 #  3. object line hash check
@@ -79,7 +79,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"object" line SHA1 check' '^error: char7: .*SHA1 hash$'
+check_verify_failure '"object" line check' '^error:.* badObjectSha1:'
 
 ############################################################
 #  4. type line label check
@@ -92,7 +92,7 @@ tagger . <> 0 +0000
 
 EOF
 
-check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
+check_verify_failure '"type" line label check' '^error:.* missingTypeEntry:'
 
 ############################################################
 #  5. type line eol check
@@ -100,7 +100,7 @@ check_verify_failure '"type" line label check' '^error: char.*: .*"\\ntype "$'
 echo "object $head" >tag.sig
 printf "type tagsssssssssssssssssssssssssssssss" >>tag.sig
 
-check_verify_failure '"type" line eol check' '^error: char.*: .*"\\n"$'
+check_verify_failure '"type" line eol check' '^error:.* unterminatedHeader:'
 
 ############################################################
 #  6. tag line label check #1
@@ -114,7 +114,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure '"tag" line label check #1' \
-	'^error: char.*: no "tag " found$'
+	'^error:.* missingTagEntry:'
 
 ############################################################
 #  7. tag line label check #2
@@ -126,7 +126,7 @@ tag
 EOF
 
 check_verify_failure '"tag" line label check #2' \
-	'^error: char.*: no "tag " found$'
+	'^error:.* badType:'
 
 ############################################################
 #  8. type line type-name length check
@@ -138,7 +138,7 @@ tag mytag
 EOF
 
 check_verify_failure '"type" line type-name length check' \
-	'^error: char.*: type too long$'
+	'^error:.* badType:'
 
 ############################################################
 #  9. verify object (hash/type) check
@@ -152,7 +152,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
-	'^error: char7: could not verify object.*$'
+	'^fatal: could not read tagged object'
 
 cat >tag.sig <<EOF
 object $head
@@ -163,7 +163,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- made-up type, valid object' \
-	'^fatal: invalid object type'
+	'^error:.* badType:'
 
 cat >tag.sig <<EOF
 object $(test_oid deadbeef)
@@ -174,7 +174,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
-	'^error: char7: could not verify object.*$'
+	'^error:.* badType:'
 
 cat >tag.sig <<EOF
 object $head
@@ -185,7 +185,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
-	'^error: char7: could not verify object'
+	'^fatal: object.*tagged as.*tree.*but is.*commit'
 
 ############################################################
 #  9.5. verify object (hash/type) check -- replacement
@@ -214,7 +214,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
-	'^error: char7: could not verify object'
+	'^fatal: object.*tagged as.*tree.*but is.*blob'
 
 ############################################################
 # 10. verify tag-name check
@@ -228,7 +228,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error: char.*: could not verify tag name$'
+	'^error:.* badTagName:'
 
 ############################################################
 # 11. tagger line label check #1
@@ -242,7 +242,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error: char.*: could not find "tagger "$'
+	'^error:.* missingTaggerEntry:'
 
 ############################################################
 # 12. tagger line label check #2
@@ -257,10 +257,10 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error: char.*: could not find "tagger "$'
+	'^error:.* missingTaggerEntry:'
 
 ############################################################
-# 13. disallow missing tag author name
+# 13. allow missing tag author name like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -271,8 +271,7 @@ tagger  <> 0 +0000
 This is filler
 EOF
 
-check_verify_failure 'disallow missing tag author name' \
-	'^error: char.*: missing tagger name$'
+test_expect_mktag_success 'allow missing tag author name'
 
 ############################################################
 # 14. disallow missing tag author name
@@ -287,7 +286,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error: char.*: malformed tagger field$'
+	'^error:.* badEmail:'
 
 ############################################################
 # 15. allow empty tag email
@@ -303,7 +302,7 @@ EOF
 test_expect_mktag_success 'allow empty tag email'
 
 ############################################################
-# 16. disallow spaces in tag email
+# 16. allow spaces in tag email like fsck
 
 cat >tag.sig <<EOF
 object $head
@@ -313,8 +312,7 @@ tagger T A Gger <tag ger@example.com> 0 +0000
 
 EOF
 
-check_verify_failure 'disallow spaces in tag email' \
-	'^error: char.*: malformed tagger field$'
+test_expect_mktag_success 'allow spaces in tag email like fsck'
 
 ############################################################
 # 17. disallow missing tag timestamp
@@ -328,7 +326,7 @@ tagger T A Gger <tagger@example.com>__
 EOF
 
 check_verify_failure 'disallow missing tag timestamp' \
-	'^error: char.*: missing tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 18. detect invalid tag timestamp1
@@ -342,7 +340,7 @@ tagger T A Gger <tagger@example.com> Tue Mar 25 15:47:44 2008
 EOF
 
 check_verify_failure 'detect invalid tag timestamp1' \
-	'^error: char.*: missing tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 19. detect invalid tag timestamp2
@@ -356,7 +354,7 @@ tagger T A Gger <tagger@example.com> 2008-03-31T12:20:15-0500
 EOF
 
 check_verify_failure 'detect invalid tag timestamp2' \
-	'^error: char.*: malformed tag timestamp$'
+	'^error:.* badDate:'
 
 ############################################################
 # 20. detect invalid tag timezone1
@@ -370,7 +368,7 @@ tagger T A Gger <tagger@example.com> 1206478233 GMT
 EOF
 
 check_verify_failure 'detect invalid tag timezone1' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 ############################################################
 # 21. detect invalid tag timezone2
@@ -384,10 +382,10 @@ tagger T A Gger <tagger@example.com> 1206478233 +  30
 EOF
 
 check_verify_failure 'detect invalid tag timezone2' \
-	'^error: char.*: malformed tag timezone$'
+	'^error:.* badTimezone:'
 
 ############################################################
-# 22. detect invalid tag timezone3
+# 22. allow invalid tag timezone3 (the maximum is -1200/+1400)
 
 cat >tag.sig <<EOF
 object $head
@@ -397,8 +395,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -1430
 
 EOF
 
-check_verify_failure 'detect invalid tag timezone3' \
-	'^error: char.*: malformed tag timezone$'
+test_expect_mktag_success 'allow invalid tag timezone'
 
 ############################################################
 # 23. detect invalid header entry
@@ -413,7 +410,7 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error: char.*: trailing garbage in tag header$'
+	'^error:.* extraHeaderEntry:'
 
 cat >tag.sig <<EOF
 object $head
@@ -445,7 +442,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 EOF
 
 check_verify_failure 'require a blank line before an empty body (2)' \
-	'^error: char.*: trailing garbage in tag header$'
+	'^error:.* extraHeaderEntry:'
 
 ############################################################
 # 24. create valid tag
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 18/23] fsck: make fsck_config() re-usable
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (18 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 17/23] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 19/23] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
                                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Move the fsck_config() function from builtin/fsck.c to fsck.[ch]. This
allows for re-using it in other tools that expose fsck logic and want
to support its configuration variables.

A logical continuation of this change would be to use a common
function for all of {fetch,receive}.fsck.* and fsck.*. See
5d477a334a6 (fsck (receive-pack): allow demoting errors to warnings,
2015-06-22) and my own 1362df0d413 (fetch: implement fetch.fsck.*,
2018-07-27) for the relevant code.

However, those routines want to not parse the fsck.skipList into OIDs,
but rather pass them along with the --strict option to another
process. It would be possible to refactor that whole thing so we
support e.g. a "fetch." prefix, then just keep track of the skiplist
as a filename instead of parsing it, and learn to spew that all out
from our internal structures into something we can append to the
--strict option.

But instead I'm planning to re-use this in "mktag", which'll just
re-use these "fsck.*" variables as-is.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/fsck.c | 20 +-------------------
 fsck.c         | 25 +++++++++++++++++++++++++
 fsck.h         |  7 +++++++
 3 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index fbf26cafcfd..821e7798c70 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -73,25 +73,7 @@ static const char *printable_type(const struct object_id *oid,
 
 static int fsck_config(const char *var, const char *value, void *cb)
 {
-	if (strcmp(var, "fsck.skiplist") == 0) {
-		const char *path;
-		struct strbuf sb = STRBUF_INIT;
-
-		if (git_config_pathname(&path, var, value))
-			return 1;
-		strbuf_addf(&sb, "skiplist=%s", path);
-		free((char *)path);
-		fsck_set_msg_types(&fsck_obj_options, sb.buf);
-		strbuf_release(&sb);
-		return 0;
-	}
-
-	if (skip_prefix(var, "fsck.", &var)) {
-		fsck_set_msg_type(&fsck_obj_options, var, value);
-		return 0;
-	}
-
-	return git_default_config(var, value, cb);
+	return fsck_config_internal(var, value, cb, &fsck_obj_options);
 }
 
 static int objerror(struct object *obj, const char *err)
diff --git a/fsck.c b/fsck.c
index bed5e20e03b..9067a290a2e 100644
--- a/fsck.c
+++ b/fsck.c
@@ -1310,3 +1310,28 @@ int fsck_finish(struct fsck_options *options)
 	oidset_clear(&gitmodules_done);
 	return ret;
 }
+
+int fsck_config_internal(const char *var, const char *value, void *cb,
+			 struct fsck_options *options)
+{
+	if (strcmp(var, "fsck.skiplist") == 0) {
+		const char *path;
+		struct strbuf sb = STRBUF_INIT;
+
+		if (git_config_pathname(&path, var, value))
+			return 1;
+		strbuf_addf(&sb, "skiplist=%s", path);
+		free((char *)path);
+		fsck_set_msg_types(options, sb.buf);
+		strbuf_release(&sb);
+		return 0;
+	}
+
+	if (skip_prefix(var, "fsck.", &var)) {
+		fsck_set_msg_type(options, var, value);
+		return 0;
+	}
+
+	return git_default_config(var, value, cb);
+}
+
diff --git a/fsck.h b/fsck.h
index 29ee4c45e87..423c467feb7 100644
--- a/fsck.h
+++ b/fsck.h
@@ -103,4 +103,11 @@ void fsck_put_object_name(struct fsck_options *options,
 const char *fsck_describe_object(struct fsck_options *options,
 				 const struct object_id *oid);
 
+/*
+ * git_config() callback for use by fsck-y tools that want to support
+ * fsck.<msg> fsck.skipList etc.
+ */
+int fsck_config_internal(const char *var, const char *value, void *cb,
+			 struct fsck_options *options);
+
 #endif
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 19/23] mktag: allow turning off fsck.extraHeaderEntry
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (19 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 18/23] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 20/23] mktag: allow omitting the header/body \n separator Ævar Arnfjörð Bjarmason
                                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

In earlier commits mktag learned to use the fsck machinery, at which
point we needed to add fsck.extraHeaderEntry so it could be as strict
about extra headers as it's been ever since it was implemented.

But it's not nice to need to switch away from "mktag" to "hash-object"
+ manual "fsck" just because you'd like to have an extra header. So
let's support turning it off by getting "fsck.*" variables from the
config.

Pedantically speaking it's still not possible to make "mktag" behave
just like "hash-object -t tag" does, since we're unconditionally going
to check the referenced object in verify_object_in_tag(), which is our
own check, and not one that exists in fsck.c.

But the spirit of "this works like fsck" is preserved, in that if you
created such a tag with "hash-object" and did a full "fsck" on the
repository it would also error out about that invalid object, it just
wouldn't emit the same message as fsck does.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt |  5 ++++-
 builtin/mktag.c             | 11 ++++++++++-
 t/t3800-mktag.sh            | 14 ++++++++++++++
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index fa070e21a0b..79813ff8df0 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -32,7 +32,10 @@ would run by default in that all `fsck.<msg-id>` messages are promoted
 from warnings to errors (so e.g. a missing "tagger" line is an error).
 
 Extra headers in the object are also an error under mktag, but ignored
-by linkgit:git-fsck[1]
+by linkgit:git-fsck[1]. This extra check can be turned off by setting
+the appropriate `fsck.<msg-id>` varible:
+
+    git -c fsck.extraHeaderEntry=ignore mktag <my-tag-with-headers
 
 Tag Format
 ----------
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 4dd35bc79e2..373926d7e0c 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -3,6 +3,14 @@
 #include "replace-object.h"
 #include "object-store.h"
 #include "fsck.h"
+#include "config.h"
+
+static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
+
+static int mktag_config(const char *var, const char *value, void *cb)
+{
+	return fsck_config_internal(var, value, cb, &fsck_options);
+}
 
 static int mktag_fsck_error_func(struct fsck_options *o,
 				 const struct object_id *oid,
@@ -53,7 +61,6 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	struct strbuf buf = STRBUF_INIT;
-	struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 	struct object_id tagged_oid;
 	int tagged_type;
 	struct object_id result;
@@ -66,6 +73,8 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 
 	fsck_options.error_func = mktag_fsck_error_func;
 	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
+	/* config might set fsck.extraHeaderEntry=* again */
+	git_config(mktag_config, NULL);
 	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
 				&tagged_oid, &tagged_type))
 		die("tag on stdin did not pass our strict fsck check");
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0e2a9a883ba..dccf4503235 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -412,6 +412,20 @@ EOF
 check_verify_failure 'detect invalid header entry' \
 	'^error:.* extraHeaderEntry:'
 
+test_expect_success 'invalid header entry config & fsck' '
+	test_must_fail git mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
+	git fsck &&
+	env GIT_TEST_GETTEXT_POISON=false \
+		git -c fsck.extraHeaderEntry=warn fsck 2>err &&
+	grep "warning .*extraHeaderEntry:" err &&
+	test_must_fail env GIT_TEST_GETTEXT_POISON=false \
+		git -c fsck.extraHeaderEntry=error 2>err fsck &&
+	grep "error .* extraHeaderEntry:" err
+'
+
 cat >tag.sig <<EOF
 object $head
 type commit
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 20/23] mktag: allow omitting the header/body \n separator
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (20 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 19/23] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 21/23] mktag: convert to parse-options Ævar Arnfjörð Bjarmason
                                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Change mktag's acceptance rules to accept an empty body without an
empty line after the header again. This fixes an ancient unintended
dregression in "mktag".

When "mktag" was introduced in ec4465adb3 (Add "tag" objects that can
be used to sign other objects., 2005-04-25) the input checks were much
looser. When it was documented it 6cfec03680 (mktag: minimally update
the description., 2007-06-10) it was clearly intended for this \n to
be optional:

    The message, when [it] exists, is separated by a blank line from
    the header.

But then in e0aaf781f6 (mktag.c: improve verification of tagger field
and tests, 2008-03-27) this was made an error, seemingly by
accident. It was just a result of the general header checks, and all
the tests after that patch have a trailing empty line (but did not
before).

Let's allow this again, and tweak the test semantics changed in
e0aaf781f6 to remove the redundant empty line. New tests added in
previous commits of mine already added an explicit test for allowing
the empty line between header and body.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 fsck.c           | 2 ++
 t/t3800-mktag.sh | 6 ++----
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fsck.c b/fsck.c
index 9067a290a2e..29c1eaca4cf 100644
--- a/fsck.c
+++ b/fsck.c
@@ -987,6 +987,8 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
 	}
 	else
 		ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
+	if (!*buffer)
+		goto done;
 
 	if (!starts_with(buffer, "\n")) {
 		/*
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index dccf4503235..601b064e97a 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -446,7 +446,7 @@ tagger T A Gger <tagger@example.com> 1206478233 -0500
 
 EOF
 
-test_expect_mktag_success 'require a blank line before an empty body (1)'
+test_expect_mktag_success 'allow a blank line before an empty body (1)'
 
 cat >tag.sig <<EOF
 object $head
@@ -455,8 +455,7 @@ tag mytag
 tagger T A Gger <tagger@example.com> 1206478233 -0500
 EOF
 
-check_verify_failure 'require a blank line before an empty body (2)' \
-	'^error:.* extraHeaderEntry:'
+test_expect_mktag_success 'allow no blank line before an empty body (2)'
 
 ############################################################
 # 24. create valid tag
@@ -466,7 +465,6 @@ object $head
 type commit
 tag mytag
 tagger T A Gger <tagger@example.com> 1206478233 -0500
-
 EOF
 
 test_expect_mktag_success 'create valid tag object'
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 21/23] mktag: convert to parse-options
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (21 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 20/23] mktag: allow omitting the header/body \n separator Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 22/23] mktag: mark strings for translation Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 23/23] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Convert the "mktag" command to use parse-options.h instead of its own
ad-hoc argc handling. This doesn't matter much in practice since it
doesn't support any options, but removes another special-case in our
codebase, and makes it easier to add options to it in the future.

It does marginally improve the situation for programs that want to
execute git commands in a consistent manner and e.g. always use
--end-of-options. E.g. "gitaly" does that, and has a blacklist of
built-ins that don't support --end-of-options. This is one less
special case for it and other similar programs to support.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c  | 14 ++++++++++++--
 t/t3800-mktag.sh | 12 ++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 373926d7e0c..18b8492f4d4 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -1,10 +1,16 @@
 #include "builtin.h"
+#include "parse-options.h"
 #include "tag.h"
 #include "replace-object.h"
 #include "object-store.h"
 #include "fsck.h"
 #include "config.h"
 
+static char const * const builtin_mktag_usage[] = {
+	N_("git mktag"),
+	NULL
+};
+
 static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 
 static int mktag_config(const char *var, const char *value, void *cb)
@@ -60,13 +66,17 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
+	static struct option builtin_mktag_options[] = {
+		OPT_END(),
+	};
 	struct strbuf buf = STRBUF_INIT;
 	struct object_id tagged_oid;
 	int tagged_type;
 	struct object_id result;
 
-	if (argc != 1)
-		usage("git mktag");
+	argc = parse_options(argc, argv, NULL,
+			     builtin_mktag_options,
+			     builtin_mktag_usage, 0);
 
 	if (strbuf_read(&buf, 0, 0) < 0)
 		die_errno("could not read from stdin");
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 601b064e97a..0ddd0f01cc7 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -45,6 +45,18 @@ test_expect_success 'setup' '
 	blob=$(git rev-parse --verify HEAD:B.t)
 '
 
+test_expect_success 'basic usage' '
+	cat >tag.sig <<-EOF &&
+	object $head
+	type commit
+	tag mytag
+	tagger T A Gger <tagger@example.com> 1206478233 -0500
+	EOF
+	git mktag <tag.sig &&
+	git mktag --end-of-options <tag.sig &&
+	test_expect_code 129 git mktag --unknown-option
+'
+
 ############################################################
 #  1. length check
 
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 22/23] mktag: mark strings for translation
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (22 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 21/23] mktag: convert to parse-options Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-05 19:42                 ` [PATCH v5 23/23] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
  24 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Mark the errors mktag might emit for translation. This is a plumbing
command, but the errors it emits are intended to be human-readable.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 builtin/mktag.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/builtin/mktag.c b/builtin/mktag.c
index 18b8492f4d4..9b04b61c2bb 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -31,10 +31,10 @@ static int mktag_fsck_error_func(struct fsck_options *o,
 		 * like missing "tagger" lines are "only" warnings
 		 * under fsck, we've always considered them an error.
 		 */
-		fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message);
+		fprintf_ln(stderr, _("error: tag input does not pass fsck: %s"), message);
 		return 1;
 	default:
-		BUG("%d (FSCK_IGNORE?) should never trigger this callback",
+		BUG(_("%d (FSCK_IGNORE?) should never trigger this callback"),
 		    msg_type);
 	}
 }
@@ -49,10 +49,10 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 
 	buffer = read_object_file(tagged_oid, &type, &size);
 	if (!buffer)
-		die("could not read tagged object '%s'",
+		die(_("could not read tagged object '%s'"),
 		    oid_to_hex(tagged_oid));
 	if (type != *tagged_type)
-		die("object '%s' tagged as '%s', but is a '%s' type",
+		die(_("object '%s' tagged as '%s', but is a '%s' type"),
 		    oid_to_hex(tagged_oid),
 		    type_name(*tagged_type), type_name(type));
 
@@ -79,7 +79,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 			     builtin_mktag_usage, 0);
 
 	if (strbuf_read(&buf, 0, 0) < 0)
-		die_errno("could not read from stdin");
+		die_errno(_("could not read from stdin"));
 
 	fsck_options.error_func = mktag_fsck_error_func;
 	fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn");
@@ -87,13 +87,13 @@ int cmd_mktag(int argc, const char **argv, const char *prefix)
 	git_config(mktag_config, NULL);
 	if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
 				&tagged_oid, &tagged_type))
-		die("tag on stdin did not pass our strict fsck check");
+		die(_("tag on stdin did not pass our strict fsck check"));
 
 	if (verify_object_in_tag(&tagged_oid, &tagged_type))
-		die("tag on stdin did not refer to a valid object");
+		die(_("tag on stdin did not refer to a valid object"));
 
 	if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0)
-		die("unable to write tag file");
+		die(_("unable to write tag file"));
 
 	strbuf_release(&buf);
 	puts(oid_to_hex(&result));
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v5 23/23] mktag: add a --no-strict option
  2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
                                   ` (23 preceding siblings ...)
  2021-01-05 19:42                 ` [PATCH v5 22/23] mktag: mark strings for translation Ævar Arnfjörð Bjarmason
@ 2021-01-05 19:42                 ` Ævar Arnfjörð Bjarmason
  2021-01-06  1:48                   ` Junio C Hamano
  24 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-05 19:42 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Now that mktag has been migrated to use the fsck machinery to check
its input, it makes sense to teach it to run in the equivalent of "git
fsck"'s default mode, instead of hardcoding "git fsck --strict". Let's
do that and support the "--no-strict" option.

Since this is a new option we don't need to cater to parse-option.c's
default of automatically supporting --strict. So let's use
PARSE_OPT_NONEG, using a new trivial helper macro.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-mktag.txt |  8 ++++++++
 builtin/mktag.c             |  9 +++++++++
 t/t3800-mktag.sh            | 33 +++++++++++++++++++++++----------
 3 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 79813ff8df0..17a2603a600 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -11,6 +11,14 @@ SYNOPSIS
 [verse]
 'git mktag'
 
+OPTIONS
+-------
+
+--strict::
+	By default mktag turns on the equivalent of
+	linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to
+	disable it.
+
 DESCRIPTION
 -----------
 
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 9b04b61c2bb..41a399a69e4 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -10,6 +10,7 @@ static char const * const builtin_mktag_usage[] = {
 	N_("git mktag"),
 	NULL
 };
+static int option_strict = 1;
 
 static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 
@@ -25,6 +26,12 @@ static int mktag_fsck_error_func(struct fsck_options *o,
 {
 	switch (msg_type) {
 	case FSCK_WARN:
+		if (!option_strict) {
+			fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
+			return 0;
+
+		}
+		/* fallthrough */
 	case FSCK_ERROR:
 		/*
 		 * We treat both warnings and errors as errors, things
@@ -67,6 +74,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	static struct option builtin_mktag_options[] = {
+		OPT_BOOL(0, "strict", &option_strict,
+			 N_("enable more strict checking")),
 		OPT_END(),
 	};
 	struct strbuf buf = STRBUF_INIT;
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0ddd0f01cc7..4d76ccbbc19 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -12,12 +12,17 @@ test_description='git mktag: tag object verify test'
 # given in the expect.pat file.
 
 check_verify_failure () {
-	expect="$2"
-	test_expect_success "$1" '
+	test_expect_success "$1" "
 		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
 			git mktag <tag.sig 2>message &&
-		grep "$expect" message
-	'
+		grep '$2' message &&
+		if test '$3' != '--no-strict'
+		then
+			test_must_fail env GIT_TEST_GETTEXT_POISON=false \
+				git mktag --no-strict <tag.sig 2>message.no-strict &&
+			grep '$2' message.no-strict
+		fi
+	"
 }
 
 test_expect_mktag_success() {
@@ -65,7 +70,7 @@ too short for a tag
 EOF
 
 check_verify_failure 'Tag object length check' \
-	'^error:.* missingObject:'
+	'^error:.* missingObject:' 'strict'
 
 ############################################################
 #  2. object line label check
@@ -240,7 +245,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error:.* badTagName:'
+	'^error:.* badTagName:' '--no-strict'
 
 ############################################################
 # 11. tagger line label check #1
@@ -254,7 +259,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error:.* missingTaggerEntry:'
+	'^error:.* missingTaggerEntry:' '--no-strict'
 
 ############################################################
 # 12. tagger line label check #2
@@ -269,7 +274,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error:.* missingTaggerEntry:'
+	'^error:.* missingTaggerEntry:' '--no-strict'
 
 ############################################################
 # 13. allow missing tag author name like fsck
@@ -298,7 +303,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error:.* badEmail:'
+	'^error:.* badEmail:' '--no-strict'
 
 ############################################################
 # 15. allow empty tag email
@@ -422,13 +427,21 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error:.* extraHeaderEntry:'
+	'^error:.* extraHeaderEntry:' '--no-strict'
 
 test_expect_success 'invalid header entry config & fsck' '
 	test_must_fail git mktag <tag.sig &&
+	git mktag --no-strict <tag.sig &&
+
 	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=error mktag --no-strict <tag.sig &&
+
 	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=warn mktag --no-strict <tag.sig &&
+
 	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=ignore mktag --no-strict <tag.sig &&
+
 	git fsck &&
 	env GIT_TEST_GETTEXT_POISON=false \
 		git -c fsck.extraHeaderEntry=warn fsck 2>err &&
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: [PATCH v5 23/23] mktag: add a --no-strict option
  2021-01-05 19:42                 ` [PATCH v5 23/23] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
@ 2021-01-06  1:48                   ` Junio C Hamano
  2021-01-06 11:47                     ` [PATCH v6 23/23] mktag: add a --[no-]strict option Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2021-01-06  1:48 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Now that mktag has been migrated to use the fsck machinery to check
> its input, it makes sense to teach it to run in the equivalent of "git
> fsck"'s default mode, instead of hardcoding "git fsck --strict". Let's
> do that and support the "--no-strict" option.
>
> Since this is a new option we don't need to cater to parse-option.c's
> default of automatically supporting --strict. So let's use
> PARSE_OPT_NONEG, using a new trivial helper macro.

I do not understand the last paragraph.

    git mktag --no-strict --strict --no-strict

should follow the usual "the last one wins" rule, so I would say
that supporting "--strict", whether it is done automatically as a
natural consequence of use of parse-options or not, would be a good
thing (also I so not see PARSE_OPT_NONEG in this patch).  Perhaps
the log message (and the title) needs updating?

    mktag: add a --[no-]strict option

    Now that mktag has been migrated to use the fsck machinery to
    check its input, it makes sense to teach it to run in the
    equivalent of "git fsck"'s default mode.  For cases where mktag
    is used to (re)create a tag object using data from an existing
    and malformed tag object, the validation may optionally have to
    be loosened.  Teach the command to take the "--[no-]strict"
    option to do so.

or something?

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

* [PATCH v6 23/23] mktag: add a --[no-]strict option
  2021-01-06  1:48                   ` Junio C Hamano
@ 2021-01-06 11:47                     ` Ævar Arnfjörð Bjarmason
  2021-01-06 22:21                       ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-06 11:47 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Now that mktag has been migrated to use the fsck machinery to check
its input, it makes sense to teach it to run in the equivalent of "git
fsck"'s default mode.

For cases where mktag is used to (re)create a tag object using data
from an existing and malformed tag object, the validation may
optionally have to be loosened. Teach the command to take the
"--[no-]strict" option to do so.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---

On Wed, Jan 06 2021, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
>
>> Now that mktag has been migrated to use the fsck machinery to check
>> its input, it makes sense to teach it to run in the equivalent of "git
>> fsck"'s default mode, instead of hardcoding "git fsck --strict". Let's
>> do that and support the "--no-strict" option.
>>
>> Since this is a new option we don't need to cater to parse-option.c's
>> default of automatically supporting --strict. So let's use
>> PARSE_OPT_NONEG, using a new trivial helper macro.
>
> I do not understand the last paragraph.

I forgot to update the commit message when changing this from
v4->v5. Here's a v6 of just this patch (to save on list traffic) with
an updated commit message. Thanks!

 Documentation/git-mktag.txt |  8 ++++++++
 builtin/mktag.c             |  9 +++++++++
 t/t3800-mktag.sh            | 33 +++++++++++++++++++++++----------
 3 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
index 79813ff8df0..17a2603a600 100644
--- a/Documentation/git-mktag.txt
+++ b/Documentation/git-mktag.txt
@@ -11,6 +11,14 @@ SYNOPSIS
 [verse]
 'git mktag'
 
+OPTIONS
+-------
+
+--strict::
+	By default mktag turns on the equivalent of
+	linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to
+	disable it.
+
 DESCRIPTION
 -----------
 
diff --git a/builtin/mktag.c b/builtin/mktag.c
index 9b04b61c2bb..41a399a69e4 100644
--- a/builtin/mktag.c
+++ b/builtin/mktag.c
@@ -10,6 +10,7 @@ static char const * const builtin_mktag_usage[] = {
 	N_("git mktag"),
 	NULL
 };
+static int option_strict = 1;
 
 static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
 
@@ -25,6 +26,12 @@ static int mktag_fsck_error_func(struct fsck_options *o,
 {
 	switch (msg_type) {
 	case FSCK_WARN:
+		if (!option_strict) {
+			fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
+			return 0;
+
+		}
+		/* fallthrough */
 	case FSCK_ERROR:
 		/*
 		 * We treat both warnings and errors as errors, things
@@ -67,6 +74,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
 int cmd_mktag(int argc, const char **argv, const char *prefix)
 {
 	static struct option builtin_mktag_options[] = {
+		OPT_BOOL(0, "strict", &option_strict,
+			 N_("enable more strict checking")),
 		OPT_END(),
 	};
 	struct strbuf buf = STRBUF_INIT;
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0ddd0f01cc7..4d76ccbbc19 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -12,12 +12,17 @@ test_description='git mktag: tag object verify test'
 # given in the expect.pat file.
 
 check_verify_failure () {
-	expect="$2"
-	test_expect_success "$1" '
+	test_expect_success "$1" "
 		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
 			git mktag <tag.sig 2>message &&
-		grep "$expect" message
-	'
+		grep '$2' message &&
+		if test '$3' != '--no-strict'
+		then
+			test_must_fail env GIT_TEST_GETTEXT_POISON=false \
+				git mktag --no-strict <tag.sig 2>message.no-strict &&
+			grep '$2' message.no-strict
+		fi
+	"
 }
 
 test_expect_mktag_success() {
@@ -65,7 +70,7 @@ too short for a tag
 EOF
 
 check_verify_failure 'Tag object length check' \
-	'^error:.* missingObject:'
+	'^error:.* missingObject:' 'strict'
 
 ############################################################
 #  2. object line label check
@@ -240,7 +245,7 @@ tagger . <> 0 +0000
 EOF
 
 check_verify_failure 'verify tag-name check' \
-	'^error:.* badTagName:'
+	'^error:.* badTagName:' '--no-strict'
 
 ############################################################
 # 11. tagger line label check #1
@@ -254,7 +259,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #1' \
-	'^error:.* missingTaggerEntry:'
+	'^error:.* missingTaggerEntry:' '--no-strict'
 
 ############################################################
 # 12. tagger line label check #2
@@ -269,7 +274,7 @@ This is filler
 EOF
 
 check_verify_failure '"tagger" line label check #2' \
-	'^error:.* missingTaggerEntry:'
+	'^error:.* missingTaggerEntry:' '--no-strict'
 
 ############################################################
 # 13. allow missing tag author name like fsck
@@ -298,7 +303,7 @@ tagger T A Gger <
 EOF
 
 check_verify_failure 'disallow malformed tagger' \
-	'^error:.* badEmail:'
+	'^error:.* badEmail:' '--no-strict'
 
 ############################################################
 # 15. allow empty tag email
@@ -422,13 +427,21 @@ this line should not be here
 EOF
 
 check_verify_failure 'detect invalid header entry' \
-	'^error:.* extraHeaderEntry:'
+	'^error:.* extraHeaderEntry:' '--no-strict'
 
 test_expect_success 'invalid header entry config & fsck' '
 	test_must_fail git mktag <tag.sig &&
+	git mktag --no-strict <tag.sig &&
+
 	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
+	test_must_fail git -c fsck.extraHeaderEntry=error mktag --no-strict <tag.sig &&
+
 	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=warn mktag --no-strict <tag.sig &&
+
 	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
+	git -c fsck.extraHeaderEntry=ignore mktag --no-strict <tag.sig &&
+
 	git fsck &&
 	env GIT_TEST_GETTEXT_POISON=false \
 		git -c fsck.extraHeaderEntry=warn fsck 2>err &&
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: [PATCH v6 23/23] mktag: add a --[no-]strict option
  2021-01-06 11:47                     ` [PATCH v6 23/23] mktag: add a --[no-]strict option Ævar Arnfjörð Bjarmason
@ 2021-01-06 22:21                       ` Junio C Hamano
  2021-01-07  7:45                         ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2021-01-06 22:21 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Now that mktag has been migrated to use the fsck machinery to check
> its input, it makes sense to teach it to run in the equivalent of "git
> fsck"'s default mode.
>
> For cases where mktag is used to (re)create a tag object using data
> from an existing and malformed tag object, the validation may
> optionally have to be loosened. Teach the command to take the
> "--[no-]strict" option to do so.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>
> On Wed, Jan 06 2021, Junio C Hamano wrote:
>
>> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
>>
>>> Now that mktag has been migrated to use the fsck machinery to check
>>> its input, it makes sense to teach it to run in the equivalent of "git
>>> fsck"'s default mode, instead of hardcoding "git fsck --strict". Let's
>>> do that and support the "--no-strict" option.
>>>
>>> Since this is a new option we don't need to cater to parse-option.c's
>>> default of automatically supporting --strict. So let's use
>>> PARSE_OPT_NONEG, using a new trivial helper macro.
>>
>> I do not understand the last paragraph.
>
> I forgot to update the commit message when changing this from
> v4->v5. Here's a v6 of just this patch (to save on list traffic) with
> an updated commit message. Thanks!

Okay.  I actually was expecting to hear the reason why the approach
taken in v4 to use PARSE_OPT_NONEG is a good one, but I take the
change of approach in v5 as the sign that you now agree with me that
a plain vanilla bool that happens to default to true is easier to
manage.

Will replace.  Thanks.

>
>  Documentation/git-mktag.txt |  8 ++++++++
>  builtin/mktag.c             |  9 +++++++++
>  t/t3800-mktag.sh            | 33 +++++++++++++++++++++++----------
>  3 files changed, 40 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
> index 79813ff8df0..17a2603a600 100644
> --- a/Documentation/git-mktag.txt
> +++ b/Documentation/git-mktag.txt
> @@ -11,6 +11,14 @@ SYNOPSIS
>  [verse]
>  'git mktag'
>  
> +OPTIONS
> +-------
> +
> +--strict::
> +	By default mktag turns on the equivalent of
> +	linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to
> +	disable it.
> +
>  DESCRIPTION
>  -----------
>  
> diff --git a/builtin/mktag.c b/builtin/mktag.c
> index 9b04b61c2bb..41a399a69e4 100644
> --- a/builtin/mktag.c
> +++ b/builtin/mktag.c
> @@ -10,6 +10,7 @@ static char const * const builtin_mktag_usage[] = {
>  	N_("git mktag"),
>  	NULL
>  };
> +static int option_strict = 1;
>  
>  static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
>  
> @@ -25,6 +26,12 @@ static int mktag_fsck_error_func(struct fsck_options *o,
>  {
>  	switch (msg_type) {
>  	case FSCK_WARN:
> +		if (!option_strict) {
> +			fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
> +			return 0;
> +
> +		}
> +		/* fallthrough */
>  	case FSCK_ERROR:
>  		/*
>  		 * We treat both warnings and errors as errors, things
> @@ -67,6 +74,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
>  int cmd_mktag(int argc, const char **argv, const char *prefix)
>  {
>  	static struct option builtin_mktag_options[] = {
> +		OPT_BOOL(0, "strict", &option_strict,
> +			 N_("enable more strict checking")),
>  		OPT_END(),
>  	};
>  	struct strbuf buf = STRBUF_INIT;
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index 0ddd0f01cc7..4d76ccbbc19 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -12,12 +12,17 @@ test_description='git mktag: tag object verify test'
>  # given in the expect.pat file.
>  
>  check_verify_failure () {
> -	expect="$2"
> -	test_expect_success "$1" '
> +	test_expect_success "$1" "
>  		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
>  			git mktag <tag.sig 2>message &&
> -		grep "$expect" message
> -	'
> +		grep '$2' message &&
> +		if test '$3' != '--no-strict'
> +		then
> +			test_must_fail env GIT_TEST_GETTEXT_POISON=false \
> +				git mktag --no-strict <tag.sig 2>message.no-strict &&
> +			grep '$2' message.no-strict
> +		fi
> +	"
>  }
>  
>  test_expect_mktag_success() {
> @@ -65,7 +70,7 @@ too short for a tag
>  EOF
>  
>  check_verify_failure 'Tag object length check' \
> -	'^error:.* missingObject:'
> +	'^error:.* missingObject:' 'strict'
>  
>  ############################################################
>  #  2. object line label check
> @@ -240,7 +245,7 @@ tagger . <> 0 +0000
>  EOF
>  
>  check_verify_failure 'verify tag-name check' \
> -	'^error:.* badTagName:'
> +	'^error:.* badTagName:' '--no-strict'
>  
>  ############################################################
>  # 11. tagger line label check #1
> @@ -254,7 +259,7 @@ This is filler
>  EOF
>  
>  check_verify_failure '"tagger" line label check #1' \
> -	'^error:.* missingTaggerEntry:'
> +	'^error:.* missingTaggerEntry:' '--no-strict'
>  
>  ############################################################
>  # 12. tagger line label check #2
> @@ -269,7 +274,7 @@ This is filler
>  EOF
>  
>  check_verify_failure '"tagger" line label check #2' \
> -	'^error:.* missingTaggerEntry:'
> +	'^error:.* missingTaggerEntry:' '--no-strict'
>  
>  ############################################################
>  # 13. allow missing tag author name like fsck
> @@ -298,7 +303,7 @@ tagger T A Gger <
>  EOF
>  
>  check_verify_failure 'disallow malformed tagger' \
> -	'^error:.* badEmail:'
> +	'^error:.* badEmail:' '--no-strict'
>  
>  ############################################################
>  # 15. allow empty tag email
> @@ -422,13 +427,21 @@ this line should not be here
>  EOF
>  
>  check_verify_failure 'detect invalid header entry' \
> -	'^error:.* extraHeaderEntry:'
> +	'^error:.* extraHeaderEntry:' '--no-strict'
>  
>  test_expect_success 'invalid header entry config & fsck' '
>  	test_must_fail git mktag <tag.sig &&
> +	git mktag --no-strict <tag.sig &&
> +
>  	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
> +	test_must_fail git -c fsck.extraHeaderEntry=error mktag --no-strict <tag.sig &&
> +
>  	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
> +	git -c fsck.extraHeaderEntry=warn mktag --no-strict <tag.sig &&
> +
>  	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
> +	git -c fsck.extraHeaderEntry=ignore mktag --no-strict <tag.sig &&
> +
>  	git fsck &&
>  	env GIT_TEST_GETTEXT_POISON=false \
>  		git -c fsck.extraHeaderEntry=warn fsck 2>err &&

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

* Re: [PATCH v6 23/23] mktag: add a --[no-]strict option
  2021-01-06 22:21                       ` Junio C Hamano
@ 2021-01-07  7:45                         ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-07  7:45 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin, SZEDER Gábor


On Wed, Jan 06 2021, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
>
>> Now that mktag has been migrated to use the fsck machinery to check
>> its input, it makes sense to teach it to run in the equivalent of "git
>> fsck"'s default mode.
>>
>> For cases where mktag is used to (re)create a tag object using data
>> from an existing and malformed tag object, the validation may
>> optionally have to be loosened. Teach the command to take the
>> "--[no-]strict" option to do so.
>>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>>
>> On Wed, Jan 06 2021, Junio C Hamano wrote:
>>
>>> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
>>>
>>>> Now that mktag has been migrated to use the fsck machinery to check
>>>> its input, it makes sense to teach it to run in the equivalent of "git
>>>> fsck"'s default mode, instead of hardcoding "git fsck --strict". Let's
>>>> do that and support the "--no-strict" option.
>>>>
>>>> Since this is a new option we don't need to cater to parse-option.c's
>>>> default of automatically supporting --strict. So let's use
>>>> PARSE_OPT_NONEG, using a new trivial helper macro.
>>>
>>> I do not understand the last paragraph.
>>
>> I forgot to update the commit message when changing this from
>> v4->v5. Here's a v6 of just this patch (to save on list traffic) with
>> an updated commit message. Thanks!
>
> Okay.  I actually was expecting to hear the reason why the approach
> taken in v4 to use PARSE_OPT_NONEG is a good one, but I take the
> change of approach in v5 as the sign that you now agree with me that
> a plain vanilla bool that happens to default to true is easier to
> manage.

There was no good reason. I couldn't find whether &no_var with "no-OPT"
options & PARSE_OPT_NONEG was the preferred pattern or &var with a
default of 1 with "OPT". There's a few examples of the former in the
codebase, but I'm happy to go with the latter.

>>
>>  Documentation/git-mktag.txt |  8 ++++++++
>>  builtin/mktag.c             |  9 +++++++++
>>  t/t3800-mktag.sh            | 33 +++++++++++++++++++++++----------
>>  3 files changed, 40 insertions(+), 10 deletions(-)
>>
>> diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt
>> index 79813ff8df0..17a2603a600 100644
>> --- a/Documentation/git-mktag.txt
>> +++ b/Documentation/git-mktag.txt
>> @@ -11,6 +11,14 @@ SYNOPSIS
>>  [verse]
>>  'git mktag'
>>  
>> +OPTIONS
>> +-------
>> +
>> +--strict::
>> +	By default mktag turns on the equivalent of
>> +	linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to
>> +	disable it.
>> +
>>  DESCRIPTION
>>  -----------
>>  
>> diff --git a/builtin/mktag.c b/builtin/mktag.c
>> index 9b04b61c2bb..41a399a69e4 100644
>> --- a/builtin/mktag.c
>> +++ b/builtin/mktag.c
>> @@ -10,6 +10,7 @@ static char const * const builtin_mktag_usage[] = {
>>  	N_("git mktag"),
>>  	NULL
>>  };
>> +static int option_strict = 1;
>>  
>>  static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
>>  
>> @@ -25,6 +26,12 @@ static int mktag_fsck_error_func(struct fsck_options *o,
>>  {
>>  	switch (msg_type) {
>>  	case FSCK_WARN:
>> +		if (!option_strict) {
>> +			fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
>> +			return 0;
>> +
>> +		}
>> +		/* fallthrough */
>>  	case FSCK_ERROR:
>>  		/*
>>  		 * We treat both warnings and errors as errors, things
>> @@ -67,6 +74,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
>>  int cmd_mktag(int argc, const char **argv, const char *prefix)
>>  {
>>  	static struct option builtin_mktag_options[] = {
>> +		OPT_BOOL(0, "strict", &option_strict,
>> +			 N_("enable more strict checking")),
>>  		OPT_END(),
>>  	};
>>  	struct strbuf buf = STRBUF_INIT;
>> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
>> index 0ddd0f01cc7..4d76ccbbc19 100755
>> --- a/t/t3800-mktag.sh
>> +++ b/t/t3800-mktag.sh
>> @@ -12,12 +12,17 @@ test_description='git mktag: tag object verify test'
>>  # given in the expect.pat file.
>>  
>>  check_verify_failure () {
>> -	expect="$2"
>> -	test_expect_success "$1" '
>> +	test_expect_success "$1" "
>>  		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
>>  			git mktag <tag.sig 2>message &&
>> -		grep "$expect" message
>> -	'
>> +		grep '$2' message &&
>> +		if test '$3' != '--no-strict'
>> +		then
>> +			test_must_fail env GIT_TEST_GETTEXT_POISON=false \
>> +				git mktag --no-strict <tag.sig 2>message.no-strict &&
>> +			grep '$2' message.no-strict
>> +		fi
>> +	"
>>  }
>>  
>>  test_expect_mktag_success() {
>> @@ -65,7 +70,7 @@ too short for a tag
>>  EOF
>>  
>>  check_verify_failure 'Tag object length check' \
>> -	'^error:.* missingObject:'
>> +	'^error:.* missingObject:' 'strict'
>>  
>>  ############################################################
>>  #  2. object line label check
>> @@ -240,7 +245,7 @@ tagger . <> 0 +0000
>>  EOF
>>  
>>  check_verify_failure 'verify tag-name check' \
>> -	'^error:.* badTagName:'
>> +	'^error:.* badTagName:' '--no-strict'
>>  
>>  ############################################################
>>  # 11. tagger line label check #1
>> @@ -254,7 +259,7 @@ This is filler
>>  EOF
>>  
>>  check_verify_failure '"tagger" line label check #1' \
>> -	'^error:.* missingTaggerEntry:'
>> +	'^error:.* missingTaggerEntry:' '--no-strict'
>>  
>>  ############################################################
>>  # 12. tagger line label check #2
>> @@ -269,7 +274,7 @@ This is filler
>>  EOF
>>  
>>  check_verify_failure '"tagger" line label check #2' \
>> -	'^error:.* missingTaggerEntry:'
>> +	'^error:.* missingTaggerEntry:' '--no-strict'
>>  
>>  ############################################################
>>  # 13. allow missing tag author name like fsck
>> @@ -298,7 +303,7 @@ tagger T A Gger <
>>  EOF
>>  
>>  check_verify_failure 'disallow malformed tagger' \
>> -	'^error:.* badEmail:'
>> +	'^error:.* badEmail:' '--no-strict'
>>  
>>  ############################################################
>>  # 15. allow empty tag email
>> @@ -422,13 +427,21 @@ this line should not be here
>>  EOF
>>  
>>  check_verify_failure 'detect invalid header entry' \
>> -	'^error:.* extraHeaderEntry:'
>> +	'^error:.* extraHeaderEntry:' '--no-strict'
>>  
>>  test_expect_success 'invalid header entry config & fsck' '
>>  	test_must_fail git mktag <tag.sig &&
>> +	git mktag --no-strict <tag.sig &&
>> +
>>  	test_must_fail git -c fsck.extraHeaderEntry=error mktag <tag.sig &&
>> +	test_must_fail git -c fsck.extraHeaderEntry=error mktag --no-strict <tag.sig &&
>> +
>>  	test_must_fail git -c fsck.extraHeaderEntry=warn mktag <tag.sig &&
>> +	git -c fsck.extraHeaderEntry=warn mktag --no-strict <tag.sig &&
>> +
>>  	git -c fsck.extraHeaderEntry=ignore mktag <tag.sig &&
>> +	git -c fsck.extraHeaderEntry=ignore mktag --no-strict <tag.sig &&
>> +
>>  	git fsck &&
>>  	env GIT_TEST_GETTEXT_POISON=false \
>>  		git -c fsck.extraHeaderEntry=warn fsck 2>err &&


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

* Re: [PATCH v5 12/23] mktag tests: improve verify_object() test coverage
  2021-01-05 19:42                 ` [PATCH v5 12/23] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
@ 2021-01-10 13:21                   ` SZEDER Gábor
  2021-01-10 18:59                     ` Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false? Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: SZEDER Gábor @ 2021-01-10 13:21 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Tue, Jan 05, 2021 at 08:42:41PM +0100, Ævar Arnfjörð Bjarmason wrote:
> The verify_object() function in "mktag.c" is tasked with ensuring that
> our tag refers to a valid object.
> 
> The existing test for this might fail because it was also testing that
> "type taggg" didn't refer to a valid object type (it should be "type
> tag"), or because we referred to a valid object but got the type
> wrong.
> 
> Let's split these tests up, so we're testing all combinations of a
> non-existing object and in invalid/wrong "type" lines.
> 
> We need to provide GIT_TEST_GETTEXT_POISON=false here because the
> "invalid object type" error is emitted by
> parse_loose_header_extended(), which has that message already marked
> for translation. Another option would be to use test_i18ngrep, but I
> prefer always running the test, not skipping it under gettext poison
> testing.

This is fairly unconvincing.  Why do you prefer it that way?  What is
so special in these tests of 'git mktags' that could possibly warrant
this special treatment WRT gettext poisoning, as opposed to the other
~1500 invocations of test_i18n{grep,cmp}?

> I'm not testing this in combination with "git replace". That'll be
> done in a subsequent commit.
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t3800-mktag.sh | 40 +++++++++++++++++++++++++++++++++++++---
>  1 file changed, 37 insertions(+), 3 deletions(-)
> 
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index 47380292223..ced540035d4 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -14,7 +14,8 @@ test_description='git mktag: tag object verify test'
>  check_verify_failure () {
>  	expect="$2"
>  	test_expect_success "$1" '
> -		test_must_fail git mktag <tag.sig 2>message &&
> +		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
> +			git mktag <tag.sig 2>message &&
>  		grep "$expect" message
>  	'
>  }
> @@ -136,19 +137,52 @@ check_verify_failure '"type" line type-name length check' \
>  	'^error: char.*: type too long$'
>  
>  ############################################################
> -#  9. verify object (SHA1/type) check
> +#  9. verify object (hash/type) check
>  
>  cat >tag.sig <<EOF
>  object $(test_oid deadbeef)
> +type tag
> +tag mytag
> +tagger . <> 0 +0000
> +
> +EOF
> +
> +check_verify_failure 'verify object (hash/type) check -- correct type, nonexisting object' \
> +	'^error: char7: could not verify object.*$'
> +
> +cat >tag.sig <<EOF
> +object $head
>  type tagggg
>  tag mytag
>  tagger . <> 0 +0000
>  
>  EOF
>  
> -check_verify_failure 'verify object (SHA1/type) check' \
> +check_verify_failure 'verify object (hash/type) check -- made-up type, valid object' \
> +	'^fatal: invalid object type'
> +
> +cat >tag.sig <<EOF
> +object $(test_oid deadbeef)
> +type tagggg
> +tag mytag
> +tagger . <> 0 +0000
> +
> +EOF
> +
> +check_verify_failure 'verify object (hash/type) check -- made-up type, nonexisting object' \
>  	'^error: char7: could not verify object.*$'
>  
> +cat >tag.sig <<EOF
> +object $head
> +type tree
> +tag mytag
> +tagger . <> 0 +0000
> +
> +EOF
> +
> +check_verify_failure 'verify object (hash/type) check -- mismatched type, valid object' \
> +	'^error: char7: could not verify object'
> +
>  ############################################################
>  # 10. verify tag-name check
>  
> -- 
> 2.29.2.222.g5d2a92d10f8
> 

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

* Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false?
  2021-01-10 13:21                   ` SZEDER Gábor
@ 2021-01-10 18:59                     ` Ævar Arnfjörð Bjarmason
  2021-01-10 20:12                       ` Junio C Hamano
  2021-01-20 15:21                       ` SZEDER Gábor
  0 siblings, 2 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-10 18:59 UTC (permalink / raw)
  To: SZEDER Gábor
  Cc: git, Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin


On Sun, Jan 10 2021, SZEDER Gábor wrote:

> On Tue, Jan 05, 2021 at 08:42:41PM +0100, Ævar Arnfjörð Bjarmason wrote:
>> The verify_object() function in "mktag.c" is tasked with ensuring that
>> our tag refers to a valid object.
>> 
>> The existing test for this might fail because it was also testing that
>> "type taggg" didn't refer to a valid object type (it should be "type
>> tag"), or because we referred to a valid object but got the type
>> wrong.
>> 
>> Let's split these tests up, so we're testing all combinations of a
>> non-existing object and in invalid/wrong "type" lines.
>> 
>> We need to provide GIT_TEST_GETTEXT_POISON=false here because the
>> "invalid object type" error is emitted by
>> parse_loose_header_extended(), which has that message already marked
>> for translation. Another option would be to use test_i18ngrep, but I
>> prefer always running the test, not skipping it under gettext poison
>> testing.
>
> This is fairly unconvincing.  Why do you prefer it that way?  What is
> so special in these tests of 'git mktags' that could possibly warrant
> this special treatment WRT gettext poisoning, as opposed to the other
> ~1500 invocations of test_i18n{grep,cmp}?

You prodded me about this and Johannes also did off-list. So given that
this is already in "next" I think it's best to let usage in this mktag
series land as-is.

I promise I'll follow-up with something to (at least start to) fix this
generally one way or the other on "master" after that. It's a trivial
part of this particular series.

I.e. either document & migrate away from test_i18ngrep (mostly, in some
cases it's still convenient), or git rid of this and the few existing
GIT_TEST_GETTEXT_POISON=false uses.

Anyway, as both the initial author of this poison facility & of its
current runtime incarnation in git.git, some context on it:

The need for test_i18ngrep was always a wart. When I submitted the
initial i18n patches a big selling point at the time to a (rightly so)
skeptical audience on the Git ML was that it could almost entirely be
turned off at compile-time, and that we had something in place to make
sure we didn't introduce plumbing bugs by overtranslating.

For a while the mass-i18n patches were about as noisy on-list as the
sha256 conversion patches were in more recenty memory.

So if you look through the history you'll see that first we skipped
whole tests with the C_LOCALE_OUTPUT prereq, and then test_i18ngrep was
a more granular way to do that:

    git some-command >output && 
    test_i18ngrep "c locale string" output

But since 6cdccfce1e0 (i18n: make GETTEXT_POISON a runtime option,
2018-11-08) this hasn't been needed. But yes, we have a bit under 10
years of test_i18ngrep usage in the test suite now.

But that stuff is the wart, and purely a historical artifact of this
having once been compile-time only. We don't do this sort of thing with
any other GIT_TEST_* option, e.g. we have tests like:

    t/t5512-ls-remote.sh:   GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
    t/t5512-ls-remote.sh-   test_cmp expect actual &&

Not:

    t/t5512-ls-remote.sh:   git ls-remote --symref --heads . >actual &&
    t/t5512-ls-remote.sh-   test_protocolv0cmp expect actual &&

Because that doesn't make sense. If we know we're testing protocol v0
here why wouldn't we just pass that as a parameter in the test? Same for
GIT_TEST_GETTEXT_POISON=false.

But yes. looking at e.g. po/README now I dropped the ball on following
through with some documentation etc. about this at the time.

I have also wondered if a better approach at this point isn't to just
remove the thing entirely. We're just doing incremental i18n-ization at
this point, so the odds that it's catching accidental plumbing
translations is rather low compared to 2011-era git.git.

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

* Re: Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false?
  2021-01-10 18:59                     ` Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false? Ævar Arnfjörð Bjarmason
@ 2021-01-10 20:12                       ` Junio C Hamano
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
  2021-01-20 15:21                       ` SZEDER Gábor
  1 sibling, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2021-01-10 20:12 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: SZEDER Gábor, git, Jeff King, brian m . carlson,
	Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> You prodded me about this and Johannes also did off-list. So given that
> this is already in "next" I think it's best to let usage in this mktag
> series land as-is.

For an issue like this "test_i18ngrep or not?" that would end up
giving a useful hint to future developers, a follow-up commit with
an explanation why test_i18ngrep is preferred (or not) would be a
great way to go forward (if the "fix" is needed in the first place,
that is).  It is easy to add a patch to fix things up while a series
is cooking in 'next', without having to remember doing so after the
series hits 'master'.

>     git some-command >output && 
>     test_i18ngrep "c locale string" output
>
> But since 6cdccfce1e0 (i18n: make GETTEXT_POISON a runtime option,
> 2018-11-08) this hasn't been needed.

I did not immediately see why that commit changes any equation, but
I am inclined to say that your argument makes sort-of sense, if not
100%, to me.  POISON test is not about testing features that ought
to work (that is what non-POISON tests are for).  The primary
objective of POISON test is to ensure that we didn't over-localize;
if all the output from some-command is expected to be fully
localized, between the above and

	GIT_TEST_GETTEXT_POISON=no git some-command >output &&
	grep "c locale string" output

there wouldn't be much difference.

But if the output contains strings, some of which are expected to be
localized (e.g. human facing messages) and some are not (e.g.
protocol dump), and the test output is inspected for both types of
strings, it would not be an equivalent test.

Having said that, it may be OK that a mixed-output-command is tested
only in C locale without localization.  Our tests do *not* make sure
that the strings that ought to be localized are indeed localized
anyway, so as long as the inspection of the output string does not
check for string that are *not* to be localized, we won't break the
primary objective of having POISON tests.

In any case, if you want to push forward in that direction to use
more GIT_TEST_* settings in the test to replace i18ncmp/grep, please
make sure you propose something easier to read than "GETTEXT_POISON"
for the environment variable name.  It is overly long and makes the
tests unreadable by pushing the part of the command that are more
important off of the right edge of the screen.

Thanks.

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

* Re: Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false?
  2021-01-10 20:12                       ` Junio C Hamano
@ 2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
  2021-01-11 13:14                           ` [PATCH 0/2] Makefile & gettext.c: remove warning & long comment Ævar Arnfjörð Bjarmason
                                             ` (10 more replies)
  0 siblings, 11 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11  8:43 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: SZEDER Gábor, git, Jeff King, brian m . carlson,
	Eric Sunshine, Johannes Schindelin


On Sun, Jan 10 2021, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> You prodded me about this and Johannes also did off-list. So given that
>> this is already in "next" I think it's best to let usage in this mktag
>> series land as-is.
>
> For an issue like this "test_i18ngrep or not?" that would end up
> giving a useful hint to future developers, a follow-up commit with
> an explanation why test_i18ngrep is preferred (or not) would be a
> great way to go forward (if the "fix" is needed in the first place,
> that is).  It is easy to add a patch to fix things up while a series
> is cooking in 'next', without having to remember doing so after the
> series hits 'master'.
>
>>     git some-command >output && 
>>     test_i18ngrep "c locale string" output
>>
>> But since 6cdccfce1e0 (i18n: make GETTEXT_POISON a runtime option,
>> 2018-11-08) this hasn't been needed.
>
> I did not immediately see why that commit changes any equation, but
> I am inclined to say that your argument makes sort-of sense, if not
> 100%, to me.  POISON test is not about testing features that ought
> to work (that is what non-POISON tests are for).  The primary
> objective of POISON test is to ensure that we didn't over-localize;
> if all the output from some-command is expected to be fully
> localized, between the above and
>
> 	GIT_TEST_GETTEXT_POISON=no git some-command >output &&
> 	grep "c locale string" output
>
> there wouldn't be much difference.
>
> But if the output contains strings, some of which are expected to be
> localized (e.g. human facing messages) and some are not (e.g.
> protocol dump), and the test output is inspected for both types of
> strings, it would not be an equivalent test.

*nod* we have a few tests like that, but most of it is "run git & do one
 grep".

> Having said that, it may be OK that a mixed-output-command is tested
> only in C locale without localization.  Our tests do *not* make sure
> that the strings that ought to be localized are indeed localized
> anyway, so as long as the inspection of the output string does not
> check for string that are *not* to be localized, we won't break the
> primary objective of having POISON tests.

What do you think about just removing it? I.e. make setting it a noop?

> In any case, if you want to push forward in that direction to use
> more GIT_TEST_* settings in the test to replace i18ncmp/grep, please
> make sure you propose something easier to read than "GETTEXT_POISON"
> for the environment variable name.  It is overly long and makes the
> tests unreadable by pushing the part of the command that are more
> important off of the right edge of the screen.

Yeah, that sucks a bit. The common case though is that the "git"
invocation itself isn't reindented by more than a "\t". E.g. in my patch
upthread:


-		test_must_fail git mktag <tag.sig 2>message &&
+		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
+			git mktag <tag.sig 2>message &&

I wondered if I could support:

    git --lang=C mktag [...]

But the order of argv parsing & gettext setup makes that a bit
inconvenient. The argv parsing itself emits i18n messages, it could be
done in the C code.

Also a pain to pass it over to the Perl + sh side without changing
semantics (simplest would be to setenv(LC_ALL, "C"), but then anything
downstream of us changes too.

Hrm, but I see I never added the "poison" support to the Perl side, just
the SH code.

Now I seem to recall that the last time I looked at this I punted on it
because I thought I'd just wait until the Shell built-ins needing i18n
disappeared, which makes any changes to it easier.

To me it makes sense just to use it. GETTEXT_POISON isn't *that* long of
a name, and any shortening-ing of it seems not worth it to e.g. break
shell history / needing to alter existing C settings etc. again.

It's a typical length for for the GIT_TEST_* variables, so if we think
their use makes tests too verbose it makes sense to re-visit that as a
more general topic.

But I also think it makes more sense to just get rid of it
entirely...

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

* [PATCH 0/2] Makefile & gettext.c: remove warning & long comment
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
@ 2021-01-11 13:14                           ` Ævar Arnfjörð Bjarmason
  2021-01-11 21:06                             ` Junio C Hamano
  2021-01-11 13:14                           ` [PATCH 1/2] Makefile: remove a warning about old GETTEXT_POISON flag Ævar Arnfjörð Bjarmason
                                             ` (9 subsequent siblings)
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 13:14 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy,
	Ævar Arnfjörð Bjarmason

We've got a huge comment in gettext.c that nobody cares about anymore,
remove it, and an old warning in the Makefile while I'm at it.

This doesn't conflict with any other patches I'm about to submit, I
wanted to submit it separately because these are small isolated
non-contentious changes.

Ævar Arnfjörð Bjarmason (2):
  Makefile: remove a warning about old GETTEXT_POISON flag
  gettext.c: remove/reword a mostly-useless comment

 Makefile  |  3 --
 gettext.c | 94 +++++++++----------------------------------------------
 2 files changed, 15 insertions(+), 82 deletions(-)

-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 1/2] Makefile: remove a warning about old GETTEXT_POISON flag
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
  2021-01-11 13:14                           ` [PATCH 0/2] Makefile & gettext.c: remove warning & long comment Ævar Arnfjörð Bjarmason
@ 2021-01-11 13:14                           ` Ævar Arnfjörð Bjarmason
  2021-01-11 13:14                           ` [PATCH 2/2] gettext.c: remove/reword a mostly-useless comment Ævar Arnfjörð Bjarmason
                                             ` (8 subsequent siblings)
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 13:14 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy,
	Ævar Arnfjörð Bjarmason

Remove a migratory warning I added in 6cdccfce1e0 (i18n: make
GETTEXT_POISON a runtime option, 2018-11-08) to give anyone using that
option in their builds a heads-up about the change from compile-time
to runtime introduced in that commit.

It's been more than 2 years since then, anyone who ran into this is
likely to have made a change as a result, so removing this is long
overdue.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Makefile | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/Makefile b/Makefile
index 7b64106930a..5a9a8a00a06 100644
--- a/Makefile
+++ b/Makefile
@@ -1554,9 +1554,6 @@ endif
 ifdef NO_SYMLINK_HEAD
 	BASIC_CFLAGS += -DNO_SYMLINK_HEAD
 endif
-ifdef GETTEXT_POISON
-$(warning The GETTEXT_POISON option has been removed in favor of runtime GIT_TEST_GETTEXT_POISON. See t/README!)
-endif
 ifdef NO_GETTEXT
 	BASIC_CFLAGS += -DNO_GETTEXT
 	USE_GETTEXT_SCHEME ?= fallthrough
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 2/2] gettext.c: remove/reword a mostly-useless comment
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
  2021-01-11 13:14                           ` [PATCH 0/2] Makefile & gettext.c: remove warning & long comment Ævar Arnfjörð Bjarmason
  2021-01-11 13:14                           ` [PATCH 1/2] Makefile: remove a warning about old GETTEXT_POISON flag Ævar Arnfjörð Bjarmason
@ 2021-01-11 13:14                           ` Ævar Arnfjörð Bjarmason
  2021-01-11 14:47                           ` [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility Ævar Arnfjörð Bjarmason
                                             ` (7 subsequent siblings)
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 13:14 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy,
	Ævar Arnfjörð Bjarmason

Mostly remove the comment I added 5e9637c6297 (i18n: add
infrastructure for translating Git with gettext, 2011-11-18). Since
then we had a fix in 9c0495d23e6 (gettext.c: detect the vsnprintf bug
at runtime, 2013-12-01) so we're not running with the "set back to C
locale" hack on any modern system.

So having more than 1/4 of the file taken up by a digression about a
glibc bug that mostly doesn't happen to anyone anymore is just a
needless distraction. Shorten the comment to make a brief mention of
the bug, and where to find more info by looking at the git history for
this now-removed comment.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 gettext.c | 94 +++++++++----------------------------------------------
 1 file changed, 15 insertions(+), 79 deletions(-)

diff --git a/gettext.c b/gettext.c
index 35d2c1218db..1b564216d03 100644
--- a/gettext.c
+++ b/gettext.c
@@ -87,88 +87,24 @@ static int test_vsnprintf(const char *fmt, ...)
 
 static void init_gettext_charset(const char *domain)
 {
-	/*
-	   This trick arranges for messages to be emitted in the user's
-	   requested encoding, but avoids setting LC_CTYPE from the
-	   environment for the whole program.
-
-	   This primarily done to avoid a bug in vsnprintf in the GNU C
-	   Library [1]. which triggered a "your vsnprintf is broken" error
-	   on Git's own repository when inspecting v0.99.6~1 under a UTF-8
-	   locale.
-
-	   That commit contains a ISO-8859-1 encoded author name, which
-	   the locale aware vsnprintf(3) won't interpolate in the format
-	   argument, due to mismatch between the data encoding and the
-	   locale.
-
-	   Even if it wasn't for that bug we wouldn't want to use LC_CTYPE at
-	   this point, because it'd require auditing all the code that uses C
-	   functions whose semantics are modified by LC_CTYPE.
-
-	   But only setting LC_MESSAGES as we do creates a problem, since
-	   we declare the encoding of our PO files[2] the gettext
-	   implementation will try to recode it to the user's locale, but
-	   without LC_CTYPE it'll emit something like this on 'git init'
-	   under the Icelandic locale:
-
-	       Bj? til t?ma Git lind ? /hlagh/.git/
-
-	   Gettext knows about the encoding of our PO file, but we haven't
-	   told it about the user's encoding, so all the non-US-ASCII
-	   characters get encoded to question marks.
-
-	   But we're in luck! We can set LC_CTYPE from the environment
-	   only while we call nl_langinfo and
-	   bind_textdomain_codeset. That suffices to tell gettext what
-	   encoding it should emit in, so it'll now say:
-
-	       Bjó til tóma Git lind í /hlagh/.git/
-
-	   And the equivalent ISO-8859-1 string will be emitted under a
-	   ISO-8859-1 locale.
-
-	   With this change way we get the advantages of setting LC_CTYPE
-	   (talk to the user in his language/encoding), without the major
-	   drawbacks (changed semantics for C functions we rely on).
-
-	   However foreign functions using other message catalogs that
-	   aren't using our neat trick will still have a problem, e.g. if
-	   we have to call perror(3):
-
-	   #include <stdio.h>
-	   #include <locale.h>
-	   #include <errno.h>
-
-	   int main(void)
-	   {
-		   setlocale(LC_MESSAGES, "");
-		   setlocale(LC_CTYPE, "C");
-		   errno = ENODEV;
-		   perror("test");
-		   return 0;
-	   }
-
-	   Running that will give you a message with question marks:
-
-	   $ LANGUAGE= LANG=de_DE.utf8 ./test
-	   test: Kein passendes Ger?t gefunden
-
-	   The vsnprintf bug has been fixed since glibc 2.17.
-
-	   Then we could simply set LC_CTYPE from the environment, which would
-	   make things like the external perror(3) messages work.
-
-	   See t/t0203-gettext-setlocale-sanity.sh's "gettext.c" tests for
-	   regression tests.
-
-	   1. http://sourceware.org/bugzilla/show_bug.cgi?id=6530
-	   2. E.g. "Content-Type: text/plain; charset=UTF-8\n" in po/is.po
-	*/
 	setlocale(LC_CTYPE, "");
 	charset = locale_charset();
 	bind_textdomain_codeset(domain, charset);
-	/* the string is taken from v0.99.6~1 */
+
+	/*
+	 * Work around an old bug fixed in glibc 2.17 (released on
+	 * 2012-12-24), at the cost of potentially making translated
+	 * messages from external functions like perror() emitted in
+	 * the wrong encoding.
+	 *
+	 * The bug affected e.g. git.git's own 7eb93c89651 ([PATCH]
+	 * Simplify git script, 2005-09-07), which is the origin of
+	 * the "David_K\345gedal" test string.
+	 *
+	 * See a much longer comment added to this file in 5e9637c6297
+	 * (i18n: add infrastructure for translating Git with gettext,
+	 * 2011-11-18) for more details.
+	 */
 	if (test_vsnprintf("%.*s", 13, "David_K\345gedal") < 0)
 		setlocale(LC_CTYPE, "C");
 }
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
                                             ` (2 preceding siblings ...)
  2021-01-11 13:14                           ` [PATCH 2/2] gettext.c: remove/reword a mostly-useless comment Ævar Arnfjörð Bjarmason
@ 2021-01-11 14:47                           ` Ævar Arnfjörð Bjarmason
  2021-01-20 15:33                             ` SZEDER Gábor
                                               ` (4 more replies)
  2021-01-11 14:47                           ` [PATCH 1/6] ci: remove GETTEXT_POISON jobs Ævar Arnfjörð Bjarmason
                                             ` (6 subsequent siblings)
  10 siblings, 5 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 14:47 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

As argued upthread and in 2/6 this test setup has outrun its
usefulness.

This series begins to remove it in a way that's very careful about not
stepping on the toes of any other in-flight patches. In particular
"master" isn't anywhere in the diff context here to avoid conflicts
with the series to do that mass-replacement in t/. 

This series merges and tests cleanly in combination with the current
"seen" branch.

At the end we're left with a bunch of tests still using
test_i18n{cmp,grep}, but I think that's preferable to having in-flight
conflicts. It'll be trivial to search-replace those at some point in
the future where we don't have another search-replacement series
amending t/ in-flight.

Ævar Arnfjörð Bjarmason (6):
  ci: remove GETTEXT_POISON jobs
  tests: remove support for GIT_TEST_GETTEXT_POISON
  tests: remove misc use of test_i18n{cmp,grep}
  tests: (almost) remove use of "test_i18ngrep !"
  tests: (almost) remove C_LOCALE_OUTPUT prerequisites
  tests: remove uses of GIT_TEST_GETTEXT_POISON=false

 .github/workflows/main.yml                    |  2 +-
 .travis.yml                                   |  2 +-
 Documentation/MyFirstContribution.txt         |  2 +-
 ci/install-dependencies.sh                    |  2 +-
 ci/lib.sh                                     |  3 +-
 config.c                                      |  9 -----
 .../t/t9363-mw-to-git-export-import.sh        |  2 +-
 gettext.c                                     | 10 -----
 gettext.h                                     |  7 +---
 git-sh-i18n.sh                                | 22 +----------
 po/README                                     | 34 +++++++++-------
 t/README                                      |  6 ---
 t/lib-credential.sh                           |  2 +-
 t/lib-gettext.sh                              |  2 +-
 t/lib-httpd.sh                                |  2 +-
 t/lib-log-graph.sh                            |  4 +-
 t/lib-submodule-update.sh                     |  2 +-
 t/t0000-basic.sh                              |  2 +-
 t/t0017-env-helper.sh                         |  8 ++--
 t/t0020-crlf.sh                               |  6 +--
 t/t0041-usage.sh                              | 12 +++---
 t/t0201-gettext-fallbacks.sh                  |  2 +-
 t/t0205-gettext-poison.sh                     | 39 -------------------
 t/t1060-object-corruption.sh                  |  2 +-
 t/t1091-sparse-checkout-builtin.sh            | 10 ++---
 t/t1305-config-include.sh                     |  4 +-
 t/t1430-bad-ref-name.sh                       |  2 +-
 t/t1450-fsck.sh                               |  4 +-
 t/t1506-rev-parse-diagnosis.sh                |  2 +-
 t/t1512-rev-parse-disambiguation.sh           | 14 +++----
 t/t2019-checkout-ambiguous-ref.sh             |  4 +-
 t/t2020-checkout-detach.sh                    |  4 +-
 t/t2024-checkout-dwim.sh                      |  2 +-
 t/t3404-rebase-interactive.sh                 | 14 +++----
 t/t3415-rebase-autosquash.sh                  | 10 ++---
 t/t3418-rebase-continue.sh                    |  2 +-
 t/t3507-cherry-pick-conflict.sh               |  2 +-
 t/t3600-rm.sh                                 |  2 +-
 t/t3701-add-interactive.sh                    |  2 +-
 t/t4001-diff-rename.sh                        |  2 +-
 t/t4012-diff-binary.sh                        |  4 +-
 t/t4014-format-patch.sh                       |  2 +-
 t/t4018-diff-funcname.sh                      |  8 ++--
 t/t4153-am-resume-override-opts.sh            |  2 +-
 t/t4205-log-pretty-formats.sh                 |  2 +-
 t/t5300-pack-object.sh                        |  4 +-
 t/t5324-split-commit-graph.sh                 |  2 +-
 t/t5411/common-functions.sh                   |  5 +--
 t/t5411/test-0026-push-options.sh             |  3 +-
 t/t5411/test-0027-push-options--porcelain.sh  |  3 +-
 t/t5505-remote.sh                             |  8 ++--
 t/t5510-fetch.sh                              |  6 +--
 t/t5534-push-signed.sh                        |  2 +-
 t/t5541-http-push-smart.sh                    |  4 +-
 t/t5580-unc-paths.sh                          |  2 +-
 t/t5601-clone.sh                              |  2 +-
 t/t5606-clone-options.sh                      |  2 +-
 t/t6001-rev-list-graft.sh                     |  2 +-
 t/t6050-replace.sh                            |  2 +-
 t/t6423-merge-rename-directories.sh           | 14 +++----
 t/t6433-merge-toplevel.sh                     |  2 +-
 t/t6437-submodule-merge.sh                    |  2 +-
 t/t6500-gc.sh                                 |  2 +-
 t/t7201-co.sh                                 |  2 +-
 t/t7300-clean.sh                              |  6 +--
 t/t7400-submodule-basic.sh                    | 16 ++++----
 t/t7414-submodule-mistakes.sh                 |  6 +--
 t/t7415-submodule-names.sh                    |  2 +-
 t/t7416-submodule-dash-url.sh                 |  2 +-
 t/t7502-commit-porcelain.sh                   | 10 ++---
 t/t7508-status.sh                             |  8 ++--
 t/t7518-ident-corner-cases.sh                 |  2 +-
 t/t7519-status-fsmonitor.sh                   |  4 +-
 t/t7520-ignored-hook-warning.sh               |  6 +--
 t/t7601-merge-pull-config.sh                  | 34 ++++++++--------
 t/t7810-grep.sh                               |  4 +-
 t/t7816-grep-binary-pattern.sh                |  2 +-
 t/t9003-help-autocorrect.sh                   |  7 +---
 t/t9800-git-p4-basic.sh                       |  2 +-
 t/t9807-git-p4-submit.sh                      |  2 +-
 t/t9902-completion.sh                         |  1 -
 t/test-lib-functions.sh                       | 23 ++++-------
 t/test-lib.sh                                 | 23 ++---------
 83 files changed, 195 insertions(+), 316 deletions(-)
 delete mode 100755 t/t0205-gettext-poison.sh

-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 1/6] ci: remove GETTEXT_POISON jobs
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
                                             ` (3 preceding siblings ...)
  2021-01-11 14:47                           ` [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility Ævar Arnfjörð Bjarmason
@ 2021-01-11 14:47                           ` Ævar Arnfjörð Bjarmason
  2021-01-12  8:50                             ` SZEDER Gábor
  2021-01-11 14:47                           ` [PATCH 2/6] tests: remove support for GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
                                             ` (5 subsequent siblings)
  10 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 14:47 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

A subsequent commit will remove GETTEXT_POISON entirely, let's start
by removing the CI jobs that enable the option.

We cannot just remove the job because the CI is implicitly depending
on the "poison" job being a sort of "default" job. Let's instead add a
"default" job.

This means we can remove the initial "make test" from the "linux-gcc"
job (it does another one after setting a bunch of GIT_TEST_*
variables).

I'm not doing that because it would conflict with the in-flight
334afbc76fb (tests: mark tests relying on the current default for
`init.defaultBranch`, 2020-11-18) (currently on the "seen" branch, so
the SHA-1 will almost definitely change). It's going to use that "make
test" again for different reasons, so let's preserve it for now.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 .github/workflows/main.yml | 2 +-
 .travis.yml                | 2 +-
 ci/install-dependencies.sh | 2 +-
 ci/lib.sh                  | 3 +--
 4 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index aef6643648..8b52df200f 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -286,7 +286,7 @@ jobs:
           - jobname: osx-gcc
             cc: gcc
             pool: macos-latest
-          - jobname: GETTEXT_POISON
+          - jobname: linux-gcc-default
             cc: gcc
             pool: ubuntu-latest
     env:
diff --git a/.travis.yml b/.travis.yml
index 05f3e3f8d7..908330a0a3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,7 @@ compiler:
 
 matrix:
   include:
-    - env: jobname=GETTEXT_POISON
+    - env: jobname=linux-gcc-default
       os: linux
       compiler:
       addons:
diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
index 0229a77f7d..79c0633a18 100755
--- a/ci/install-dependencies.sh
+++ b/ci/install-dependencies.sh
@@ -72,7 +72,7 @@ Documentation)
 	test -n "$ALREADY_HAVE_ASCIIDOCTOR" ||
 	sudo gem install --version 1.5.8 asciidoctor
 	;;
-linux-gcc-4.8|GETTEXT_POISON)
+linux-gcc-default|linux-gcc-4.8)
 	sudo apt-get -q update
 	sudo apt-get -q -y install $UBUNTU_COMMON_PKGS
 	;;
diff --git a/ci/lib.sh b/ci/lib.sh
index 38c0eac351..d848c036c5 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -220,8 +220,7 @@ osx-clang|osx-gcc)
 	# Travis CI OS X
 	export GIT_SKIP_TESTS="t9810 t9816"
 	;;
-GETTEXT_POISON)
-	export GIT_TEST_GETTEXT_POISON=true
+linux-gcc-default)
 	;;
 Linux32)
 	CC=gcc
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 2/6] tests: remove support for GIT_TEST_GETTEXT_POISON
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
                                             ` (4 preceding siblings ...)
  2021-01-11 14:47                           ` [PATCH 1/6] ci: remove GETTEXT_POISON jobs Ævar Arnfjörð Bjarmason
@ 2021-01-11 14:47                           ` Ævar Arnfjörð Bjarmason
  2021-01-11 21:54                             ` Junio C Hamano
  2021-03-24 23:36                             ` [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
  2021-01-11 14:47                           ` [PATCH 3/6] tests: remove misc use of test_i18n{cmp,grep} Ævar Arnfjörð Bjarmason
                                             ` (4 subsequent siblings)
  10 siblings, 2 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 14:47 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

This removes the ability to inject "poison" gettext() messages via the
GIT_TEST_GETTEXT_POISON special test setup.

I initially added this as a compile-time option in bb946bba761 (i18n:
add GETTEXT_POISON to simulate unfriendly translator, 2011-02-22), and
most recently modified to be toggleable at runtime in
6cdccfce1e0 (i18n: make GETTEXT_POISON a runtime option, 2018-11-08)..

The reason for its removal is that the trade-off of maintaining it
v.s. what it's getting us has long since flipped. When gettext was
integrated in 5e9637c6297 (i18n: add infrastructure for translating
Git with gettext, 2011-11-18) there was understandable concern on the
Git ML that in marking messages for translation en-masse we'd
inadvertently mark plumbing messages. The GETTEXT_POISON facility was
a way to smoke those out via our test suite.

Nowadays however we're done (or almost entirely done) with any marking
of messages for translation. New messages are usually marked by their
authors, who'll know whether it makes sense to translate them or
not. If not any errors in marking the messages are much more likely to
be spotted in review than in the the initial deluge of i18n patches in
the 2011-2012 era.

So let's just remove this. This leaves the test suite in a state where
we still have a lot of test_i18n, C_LOCALE_OUTPUT
etc. uses. Subsequent commits will remove those too.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/MyFirstContribution.txt |  2 +-
 config.c                              |  9 -------
 gettext.c                             | 10 -------
 gettext.h                             |  7 +----
 git-sh-i18n.sh                        | 22 +--------------
 po/README                             | 34 ++++++++++++-----------
 t/README                              |  6 -----
 t/lib-gettext.sh                      |  2 +-
 t/t0017-env-helper.sh                 |  8 +++---
 t/t0205-gettext-poison.sh             | 39 ---------------------------
 t/test-lib-functions.sh               | 23 +++++-----------
 t/test-lib.sh                         | 23 +++-------------
 12 files changed, 38 insertions(+), 147 deletions(-)
 delete mode 100755 t/t0205-gettext-poison.sh

diff --git a/Documentation/MyFirstContribution.txt b/Documentation/MyFirstContribution.txt
index 7c9a037cc2..af0a9da62e 100644
--- a/Documentation/MyFirstContribution.txt
+++ b/Documentation/MyFirstContribution.txt
@@ -664,7 +664,7 @@ mention the right animal somewhere:
 ----
 test_expect_success 'runs correctly with no args and good output' '
 	git psuh >actual &&
-	test_i18ngrep Pony actual
+	grep Pony actual
 '
 ----
 
diff --git a/config.c b/config.c
index 1137bd73af..a8dec9a247 100644
--- a/config.c
+++ b/config.c
@@ -996,15 +996,6 @@ static void die_bad_number(const char *name, const char *value)
 	if (!value)
 		value = "";
 
-	if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
-		/*
-		 * We explicitly *don't* use _() here since it would
-		 * cause an infinite loop with _() needing to call
-		 * use_gettext_poison(). This is why marked up
-		 * translations with N_() above.
-		 */
-		die(bad_numeric, value, name, error_type);
-
 	if (!(cf && cf->name))
 		die(_(bad_numeric), value, name, _(error_type));
 
diff --git a/gettext.c b/gettext.c
index 35d2c1218d..308c4b3129 100644
--- a/gettext.c
+++ b/gettext.c
@@ -65,14 +65,6 @@ const char *get_preferred_languages(void)
 	return NULL;
 }
 
-int use_gettext_poison(void)
-{
-	static int poison_requested = -1;
-	if (poison_requested == -1)
-		poison_requested = git_env_bool("GIT_TEST_GETTEXT_POISON", 0);
-	return poison_requested;
-}
-
 #ifndef NO_GETTEXT
 static int test_vsnprintf(const char *fmt, ...)
 {
@@ -181,8 +173,6 @@ void git_setup_gettext(void)
 	if (!podir)
 		podir = p = system_path(GIT_LOCALE_PATH);
 
-	use_gettext_poison(); /* getenv() reentrancy paranoia */
-
 	if (!is_directory(podir)) {
 		free(p);
 		return;
diff --git a/gettext.h b/gettext.h
index bee52eb113..c8b34fd612 100644
--- a/gettext.h
+++ b/gettext.h
@@ -28,15 +28,12 @@
 
 #define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
 
-int use_gettext_poison(void);
-
 #ifndef NO_GETTEXT
 void git_setup_gettext(void);
 int gettext_width(const char *s);
 #else
 static inline void git_setup_gettext(void)
 {
-	use_gettext_poison(); /* getenv() reentrancy paranoia */
 }
 static inline int gettext_width(const char *s)
 {
@@ -48,14 +45,12 @@ static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
 {
 	if (!*msgid)
 		return "";
-	return use_gettext_poison() ? "# GETTEXT POISON #" : gettext(msgid);
+	return gettext(msgid);
 }
 
 static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2)
 const char *Q_(const char *msgid, const char *plu, unsigned long n)
 {
-	if (use_gettext_poison())
-		return "# GETTEXT POISON #";
 	return ngettext(msgid, plu, n);
 }
 
diff --git a/git-sh-i18n.sh b/git-sh-i18n.sh
index 8eef60b43f..e3d9f4836d 100644
--- a/git-sh-i18n.sh
+++ b/git-sh-i18n.sh
@@ -17,12 +17,7 @@ export TEXTDOMAINDIR
 
 # First decide what scheme to use...
 GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
-if test -n "$GIT_TEST_GETTEXT_POISON" &&
-	    git env--helper --type=bool --default=0 --exit-code \
-		GIT_TEST_GETTEXT_POISON
-then
-	GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
-elif test -n "@@USE_GETTEXT_SCHEME@@"
+if test -n "@@USE_GETTEXT_SCHEME@@"
 then
 	GIT_INTERNAL_GETTEXT_SH_SCHEME="@@USE_GETTEXT_SCHEME@@"
 elif test -n "$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS"
@@ -63,21 +58,6 @@ gettext_without_eval_gettext)
 		)
 	}
 	;;
-poison)
-	# Emit garbage so that tests that incorrectly rely on translatable
-	# strings will fail.
-	gettext () {
-		printf "%s" "# GETTEXT POISON #"
-	}
-
-	eval_gettext () {
-		printf "%s" "# GETTEXT POISON #"
-	}
-
-	eval_ngettext () {
-		printf "%s" "# GETTEXT POISON #"
-	}
-	;;
 *)
 	gettext () {
 		printf "%s" "$1"
diff --git a/po/README b/po/README
index 07595d369b..b9b6c9cb24 100644
--- a/po/README
+++ b/po/README
@@ -284,23 +284,27 @@ Perl:
 Testing marked strings
 ----------------------
 
-Even if you've correctly marked porcelain strings for translation
-something in the test suite might still depend on the US English
-version of the strings, e.g. to grep some error message or other
-output.
+Git's tests are run under LANG=C LC_ALL=C. So the tests do not need be
+changed to account for translations as they're added.
 
-To smoke out issues like these, Git tested with a translation mode that
-emits gibberish on every call to gettext. To use it run the test suite
-with it, e.g.:
+Testing whether marked strings are used by plumbing
+---------------------------------------------------
 
-    cd t && GIT_TEST_GETTEXT_POISON=true prove -j 9 ./t[0-9]*.sh
+It may be useful to use the test suite to smoke out any strings that
+shouldn't be translated, because they are used by plumbing or
+otherwise part of machine-readable output.
 
-If tests break with it you should inspect them manually and see if
-what you're translating is sane, i.e. that you're not translating
+This is most useful in cases where e.g. library function might return
+a string like _("tree"), and the developer marking strings for
+translation wishes to check that they're not inadvertently translating
 plumbing output.
 
-If not you should replace calls to grep with test_i18ngrep, or
-test_cmp calls with test_i18ncmp. If that's not enough you can skip
-the whole test by making it depend on the C_LOCALE_OUTPUT
-prerequisite. See existing test files with this prerequisite for
-examples.
+There used to be a GIT_TEST_GETTEXT_POISON=true test mode to replace
+translated strings with gibberish to facilitate this. Maintaining it
+and annotating tests appropriately was considered too high of a burden
+for its usefulness.
+
+It's still possible to do a one-off test of where a string might be
+used in the tests by simply replacing the "some hardcoded string" with
+something like "POISON ME" locally and running the tests, before
+finally converting it to _("some hardcoded string").
diff --git a/t/README b/t/README
index c730a70770..9a9dded033 100644
--- a/t/README
+++ b/t/README
@@ -358,12 +358,6 @@ whether this mode is active, and e.g. skip some tests that are hard to
 refactor to deal with it. The "SYMLINKS" prerequisite is currently
 excluded as so much relies on it, but this might change in the future.
 
-GIT_TEST_GETTEXT_POISON=<boolean> turns all strings marked for
-translation into gibberish if true. Used for spotting those tests that
-need to be marked with a C_LOCALE_OUTPUT prerequisite when adding more
-strings for translation. See "Testing marked strings" in po/README for
-details.
-
 GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
 test suite. Accept any boolean values that are accepted by git-config.
 
diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh
index 2139b427ca..cc6bb2cdea 100644
--- a/t/lib-gettext.sh
+++ b/t/lib-gettext.sh
@@ -17,7 +17,7 @@ else
 	. "$GIT_BUILD_DIR"/git-sh-i18n
 fi
 
-if test_have_prereq GETTEXT && test_have_prereq C_LOCALE_OUTPUT
+if test_have_prereq GETTEXT
 then
 	# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
 	is_IS_locale=$(locale -a 2>/dev/null |
diff --git a/t/t0017-env-helper.sh b/t/t0017-env-helper.sh
index c1ecf6aeac..4a159f99e4 100755
--- a/t/t0017-env-helper.sh
+++ b/t/t0017-env-helper.sh
@@ -86,14 +86,14 @@ test_expect_success 'env--helper reads config thanks to trace2' '
 	git config -f home/cycle include.path .gitconfig &&
 
 	test_must_fail \
-		env HOME="$(pwd)/home" GIT_TEST_GETTEXT_POISON=false \
+		env HOME="$(pwd)/home" \
 		git config -l 2>err &&
 	grep "exceeded maximum include depth" err &&
 
 	test_must_fail \
-		env HOME="$(pwd)/home" GIT_TEST_GETTEXT_POISON=true \
-		git -C cycle env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON 2>err &&
-	grep "# GETTEXT POISON #" err
+		env HOME="$(pwd)/home" GIT_TEST_ENV_HELPER=true \
+		git -C cycle env--helper --type=bool --default=0 --exit-code GIT_TEST_ENV_HELPER 2>err &&
+	grep "exceeded maximum include depth" err
 '
 
 test_done
diff --git a/t/t0205-gettext-poison.sh b/t/t0205-gettext-poison.sh
deleted file mode 100755
index f9fa16ad83..0000000000
--- a/t/t0205-gettext-poison.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010 Ævar Arnfjörð Bjarmason
-#
-
-test_description='Gettext Shell poison'
-
-GIT_TEST_GETTEXT_POISON=true
-export GIT_TEST_GETTEXT_POISON
-. ./lib-gettext.sh
-
-test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
-    test "$GIT_INTERNAL_GETTEXT_SH_SCHEME" = "poison"
-'
-
-test_expect_success 'gettext: our gettext() fallback has poison semantics' '
-    printf "# GETTEXT POISON #" >expect &&
-    gettext "test" >actual &&
-    test_cmp expect actual &&
-    printf "# GETTEXT POISON #" >expect &&
-    gettext "test more words" >actual &&
-    test_cmp expect actual
-'
-
-test_expect_success 'eval_gettext: our eval_gettext() fallback has poison semantics' '
-    printf "# GETTEXT POISON #" >expect &&
-    eval_gettext "test" >actual &&
-    test_cmp expect actual &&
-    printf "# GETTEXT POISON #" >expect &&
-    eval_gettext "test more words" >actual &&
-    test_cmp expect actual
-'
-
-test_expect_success "gettext: invalid GIT_TEST_GETTEXT_POISON value doesn't infinitely loop" "
-	test_must_fail env GIT_TEST_GETTEXT_POISON=xyz git version 2>error &&
-	grep \"fatal: bad numeric config value 'xyz' for 'GIT_TEST_GETTEXT_POISON': invalid unit\" error
-"
-
-test_done
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 999982fe4a..c7b1d857c4 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -988,19 +988,16 @@ test_cmp_bin () {
 	cmp "$@"
 }
 
-# Use this instead of test_cmp to compare files that contain expected and
-# actual output from git commands that can be translated.  When running
-# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
-# results.
+# Wrapper for test_cmp which used to be used for
+# GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other
+# in-flight changes. Should not be used and will be removed soon.
 test_i18ncmp () {
-	! test_have_prereq C_LOCALE_OUTPUT || test_cmp "$@"
+	test_cmp "$@"
 }
 
-# Use this instead of "grep expected-string actual" to see if the
-# output from a git command that can be translated either contains an
-# expected string, or does not contain an unwanted one.  When running
-# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
-# results.
+# Wrapper for grep which used to be used for
+# GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other
+# in-flight changes. Should not be used and will be removed soon.
 test_i18ngrep () {
 	eval "last_arg=\${$#}"
 
@@ -1013,12 +1010,6 @@ test_i18ngrep () {
 		BUG "too few parameters to test_i18ngrep"
 	fi
 
-	if test_have_prereq !C_LOCALE_OUTPUT
-	then
-		# pretend success
-		return 0
-	fi
-
 	if test "x!" = "x$1"
 	then
 		shift
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 9fa7c1d0f6..c1ff5db2c1 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -404,15 +404,6 @@ TZ=UTC
 export LANG LC_ALL PAGER TZ
 EDITOR=:
 
-# GIT_TEST_GETTEXT_POISON should not influence git commands executed
-# during initialization of test-lib and the test repo. Back it up,
-# unset and then restore after initialization is finished.
-if test -n "$GIT_TEST_GETTEXT_POISON"
-then
-	GIT_TEST_GETTEXT_POISON_ORIG=$GIT_TEST_GETTEXT_POISON
-	unset GIT_TEST_GETTEXT_POISON
-fi
-
 # A call to "unset" with no arguments causes at least Solaris 10
 # /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
 # deriving from the command substitution clustered with the other
@@ -1529,16 +1520,10 @@ test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1
 test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
 
-if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
-then
-	GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
-	export GIT_TEST_GETTEXT_POISON
-	unset GIT_TEST_GETTEXT_POISON_ORIG
-fi
-
-test_lazy_prereq C_LOCALE_OUTPUT '
-	! test_bool_env GIT_TEST_GETTEXT_POISON false
-'
+# Used to be used for GIT_TEST_GETTEXT_POISON=false. Only here as a
+# shim for other in-flight changes. Should not be used and will be
+# removed soon.
+test_set_prereq C_LOCALE_OUTPUT
 
 if test -z "$GIT_TEST_CHECK_CACHE_TREE"
 then
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 3/6] tests: remove misc use of test_i18n{cmp,grep}
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
                                             ` (5 preceding siblings ...)
  2021-01-11 14:47                           ` [PATCH 2/6] tests: remove support for GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
@ 2021-01-11 14:47                           ` Ævar Arnfjörð Bjarmason
  2021-01-11 14:47                           ` [PATCH 4/6] tests: (almost) remove use of "test_i18ngrep !" Ævar Arnfjörð Bjarmason
                                             ` (3 subsequent siblings)
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 14:47 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

Remove miscellaneous use of test_i18n{cmp,grep} from contrib/*,
lib-*.sh and t/*/*.sh etc. noted in an earlier commit we're removing
the GIT_TEST_GETTEXT_POISON=true facility.

This leaves the only users of these functions in t/t[0-9]*.sh tests,
which makes it easier to do a follow-up for-loop search-replacement of
those occurrences at a later date.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh | 2 +-
 t/lib-credential.sh                                  | 2 +-
 t/lib-httpd.sh                                       | 2 +-
 t/lib-log-graph.sh                                   | 4 ++--
 t/lib-submodule-update.sh                            | 2 +-
 t/t5411/test-0026-push-options.sh                    | 3 +--
 t/t5411/test-0027-push-options--porcelain.sh         | 3 +--
 7 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh b/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
index 6187ec67fa..3278334b9b 100755
--- a/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
+++ b/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
@@ -161,7 +161,7 @@ test_expect_success 'git push properly warns about insufficient permissions' '
 		git add foo.forbidden &&
 		git commit -m "add a file" &&
 		git push 2>actual &&
-		test_i18ngrep "foo.forbidden is not a permitted file" actual
+		grep "foo.forbidden is not a permitted file" actual
 	)
 '
 
diff --git a/t/lib-credential.sh b/t/lib-credential.sh
index dea2cbef51..5ea8bc9f1d 100644
--- a/t/lib-credential.sh
+++ b/t/lib-credential.sh
@@ -20,7 +20,7 @@ check() {
 		false
 	fi &&
 	test_cmp expect-stdout stdout &&
-	test_i18ncmp expect-stderr stderr
+	test_cmp expect-stderr stderr
 }
 
 read_chunk() {
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index d2edfa4c50..a3ae0616e6 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -219,7 +219,7 @@ test_http_push_nonff () {
 	'
 
 	test_expect_success 'non-fast-forward push shows help message' '
-		test_i18ngrep "Updates were rejected because" output
+		grep "Updates were rejected because" output
 	'
 
 	test_expect_${EXPECT_CAS_RESULT} 'force with lease aka cas' '
diff --git a/t/lib-log-graph.sh b/t/lib-log-graph.sh
index 1184cceef2..bf952ef920 100644
--- a/t/lib-log-graph.sh
+++ b/t/lib-log-graph.sh
@@ -12,13 +12,13 @@ sanitize_log_output () {
 lib_test_cmp_graph () {
 	git log --graph "$@" >output &&
 	sed 's/ *$//' >output.sanitized <output &&
-	test_i18ncmp expect output.sanitized
+	test_cmp expect output.sanitized
 }
 
 lib_test_cmp_short_graph () {
 	git log --graph --pretty=short "$@" >output &&
 	sanitize_log_output >output.sanitized <output &&
-	test_i18ncmp expect output.sanitized
+	test_cmp expect output.sanitized
 }
 
 lib_test_cmp_colored_graph () {
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index bd3fa3c6da..e04b5c4ba3 100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -830,7 +830,7 @@ test_submodule_recursing_with_args_common () {
 			cd submodule_update &&
 			git branch -t invalid_sub1 origin/invalid_sub1 &&
 			test_must_fail $command invalid_sub1 2>err &&
-			test_i18ngrep sub1 err &&
+			grep sub1 err &&
 			test_superproject_content origin/add_sub1 &&
 			test_submodule_content sub1 origin/add_sub1
 		)
diff --git a/t/t5411/test-0026-push-options.sh b/t/t5411/test-0026-push-options.sh
index e88edb16a4..a03f9ac5c4 100644
--- a/t/t5411/test-0026-push-options.sh
+++ b/t/t5411/test-0026-push-options.sh
@@ -18,8 +18,7 @@ test_expect_success "proc-receive: not support push options ($PROTOCOL)" '
 		HEAD:refs/for/main/topic \
 		>out 2>&1 &&
 	make_user_friendly_and_stable_output <out >actual &&
-	test_i18ngrep "fatal: the receiving end does not support push options" \
-		actual &&
+	grep "fatal: the receiving end does not support push options" actual &&
 	git -C "$upstream" show-ref >out &&
 	make_user_friendly_and_stable_output <out >actual &&
 	cat >expect <<-EOF &&
diff --git a/t/t5411/test-0027-push-options--porcelain.sh b/t/t5411/test-0027-push-options--porcelain.sh
index 3a6561b5ea..e734247d69 100644
--- a/t/t5411/test-0027-push-options--porcelain.sh
+++ b/t/t5411/test-0027-push-options--porcelain.sh
@@ -19,8 +19,7 @@ test_expect_success "proc-receive: not support push options ($PROTOCOL/porcelain
 		HEAD:refs/for/main/topic \
 		>out 2>&1 &&
 	make_user_friendly_and_stable_output <out >actual &&
-	test_i18ngrep "fatal: the receiving end does not support push options" \
-		actual &&
+	grep "fatal: the receiving end does not support push options" actual &&
 	git -C "$upstream" show-ref >out &&
 	make_user_friendly_and_stable_output <out >actual &&
 	cat >expect <<-EOF &&
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 4/6] tests: (almost) remove use of "test_i18ngrep !"
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
                                             ` (6 preceding siblings ...)
  2021-01-11 14:47                           ` [PATCH 3/6] tests: remove misc use of test_i18n{cmp,grep} Ævar Arnfjörð Bjarmason
@ 2021-01-11 14:47                           ` Ævar Arnfjörð Bjarmason
  2021-01-11 14:47                           ` [PATCH 5/6] tests: (almost) remove C_LOCALE_OUTPUT prerequisites Ævar Arnfjörð Bjarmason
                                             ` (2 subsequent siblings)
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 14:47 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

As noted in previous commits we are removing uses of
test_i18ngrep. Let's start with the more rare negated form. This
leaves us with "test_i18ngrep" as a mere wrapper for "grep" at the
end.

Done with:

    cd t &&
    perl -pi -e 's/test_i18ngrep ! /! grep /g' *.sh

I excluded those things that would conflict with other in-flight
changes on the "seen" branch, as well as not removing support from
this invocation from "test_i18ngrep" for those & any other in-flight
and soon-to-be-submitted changes. We can do a later final cleanup and
removal of the unused code in some later change.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0041-usage.sh                    | 12 +++++-----
 t/t1060-object-corruption.sh        |  2 +-
 t/t1091-sparse-checkout-builtin.sh  | 10 ++++-----
 t/t1450-fsck.sh                     |  4 ++--
 t/t1506-rev-parse-diagnosis.sh      |  2 +-
 t/t2019-checkout-ambiguous-ref.sh   |  4 ++--
 t/t2020-checkout-detach.sh          |  4 ++--
 t/t2024-checkout-dwim.sh            |  2 +-
 t/t3418-rebase-continue.sh          |  2 +-
 t/t3507-cherry-pick-conflict.sh     |  2 +-
 t/t3600-rm.sh                       |  2 +-
 t/t4001-diff-rename.sh              |  2 +-
 t/t4014-format-patch.sh             |  2 +-
 t/t4018-diff-funcname.sh            |  8 +++----
 t/t4153-am-resume-override-opts.sh  |  2 +-
 t/t5324-split-commit-graph.sh       |  2 +-
 t/t5505-remote.sh                   |  2 +-
 t/t5510-fetch.sh                    |  2 +-
 t/t5534-push-signed.sh              |  2 +-
 t/t5541-http-push-smart.sh          |  4 ++--
 t/t5580-unc-paths.sh                |  2 +-
 t/t5606-clone-options.sh            |  2 +-
 t/t6001-rev-list-graft.sh           |  2 +-
 t/t6050-replace.sh                  |  2 +-
 t/t6423-merge-rename-directories.sh | 12 +++++-----
 t/t6433-merge-toplevel.sh           |  2 +-
 t/t6437-submodule-merge.sh          |  2 +-
 t/t6500-gc.sh                       |  2 +-
 t/t7400-submodule-basic.sh          | 16 +++++++-------
 t/t7414-submodule-mistakes.sh       |  6 ++---
 t/t7415-submodule-names.sh          |  2 +-
 t/t7416-submodule-dash-url.sh       |  2 +-
 t/t7502-commit-porcelain.sh         | 10 ++++-----
 t/t7508-status.sh                   |  8 +++----
 t/t7518-ident-corner-cases.sh       |  2 +-
 t/t7519-status-fsmonitor.sh         |  4 ++--
 t/t7520-ignored-hook-warning.sh     |  6 ++---
 t/t7601-merge-pull-config.sh        | 34 ++++++++++++++---------------
 t/t7810-grep.sh                     |  2 +-
 t/t7816-grep-binary-pattern.sh      |  2 +-
 t/t9800-git-p4-basic.sh             |  2 +-
 t/t9807-git-p4-submit.sh            |  2 +-
 42 files changed, 98 insertions(+), 98 deletions(-)

diff --git a/t/t0041-usage.sh b/t/t0041-usage.sh
index 5b927b76fe..7d84671941 100755
--- a/t/t0041-usage.sh
+++ b/t/t0041-usage.sh
@@ -18,7 +18,7 @@ test_expect_success 'tag --contains <inexistent_tag>' '
 	test_must_fail git tag --contains "notag" >actual 2>actual.err &&
 	test_line_count = 0 actual &&
 	test_i18ngrep "error" actual.err &&
-	test_i18ngrep ! "usage" actual.err
+	! grep "usage" actual.err
 '
 
 test_expect_success 'tag --no-contains <existent_tag>' '
@@ -31,7 +31,7 @@ test_expect_success 'tag --no-contains <inexistent_tag>' '
 	test_must_fail git tag --no-contains "notag" >actual 2>actual.err &&
 	test_line_count = 0 actual &&
 	test_i18ngrep "error" actual.err &&
-	test_i18ngrep ! "usage" actual.err
+	! grep "usage" actual.err
 '
 
 test_expect_success 'tag usage error' '
@@ -50,7 +50,7 @@ test_expect_success 'branch --contains <inexistent_commit>' '
 	test_must_fail git branch --no-contains "nocommit" >actual 2>actual.err &&
 	test_line_count = 0 actual &&
 	test_i18ngrep "error" actual.err &&
-	test_i18ngrep ! "usage" actual.err
+	! grep "usage" actual.err
 '
 
 test_expect_success 'branch --no-contains <existent_commit>' '
@@ -63,7 +63,7 @@ test_expect_success 'branch --no-contains <inexistent_commit>' '
 	test_must_fail git branch --no-contains "nocommit" >actual 2>actual.err &&
 	test_line_count = 0 actual &&
 	test_i18ngrep "error" actual.err &&
-	test_i18ngrep ! "usage" actual.err
+	! grep "usage" actual.err
 '
 
 test_expect_success 'branch usage error' '
@@ -82,7 +82,7 @@ test_expect_success 'for-each-ref --contains <inexistent_object>' '
 	test_must_fail git for-each-ref --no-contains "noobject" >actual 2>actual.err &&
 	test_line_count = 0 actual &&
 	test_i18ngrep "error" actual.err &&
-	test_i18ngrep ! "usage" actual.err
+	! grep "usage" actual.err
 '
 
 test_expect_success 'for-each-ref --no-contains <existent_object>' '
@@ -95,7 +95,7 @@ test_expect_success 'for-each-ref --no-contains <inexistent_object>' '
 	test_must_fail git for-each-ref --no-contains "noobject" >actual 2>actual.err &&
 	test_line_count = 0 actual &&
 	test_i18ngrep "error" actual.err &&
-	test_i18ngrep ! "usage" actual.err
+	! grep "usage" actual.err
 '
 
 test_expect_success 'for-each-ref usage error' '
diff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh
index bc89371f53..18dd448c7a 100755
--- a/t/t1060-object-corruption.sh
+++ b/t/t1060-object-corruption.sh
@@ -123,7 +123,7 @@ test_expect_success 'fetch into corrupted repo with index-pack' '
 		cd bit-error-cp &&
 		test_must_fail git -c transfer.unpackLimit=1 \
 			fetch ../no-bit-error 2>stderr &&
-		test_i18ngrep ! -i collision stderr
+		! grep -i collision stderr
 	)
 '
 
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index 84acfc48b6..e0b3c7e5e4 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -180,7 +180,7 @@ test_expect_success 'cone mode: match patterns' '
 	git -C repo config --worktree core.sparseCheckoutCone true &&
 	rm -rf repo/a repo/folder1 repo/folder2 &&
 	git -C repo read-tree -mu HEAD 2>err &&
-	test_i18ngrep ! "disabling cone patterns" err &&
+	! grep "disabling cone patterns" err &&
 	git -C repo reset --hard &&
 	check_files repo a folder1 folder2
 '
@@ -323,8 +323,8 @@ test_expect_success 'revert to old sparse-checkout on empty update' '
 		git add file &&
 		git commit -m "test" &&
 		git sparse-checkout set nothing 2>err &&
-		test_i18ngrep ! "Sparse checkout leaves no entry on working directory" err &&
-		test_i18ngrep ! ".git/index.lock" err &&
+		! grep "Sparse checkout leaves no entry on working directory" err &&
+		! grep ".git/index.lock" err &&
 		git sparse-checkout set file
 	)
 '
@@ -340,7 +340,7 @@ test_expect_success '.gitignore should not warn about cone mode' '
 	git -C repo config --worktree core.sparseCheckoutCone true &&
 	echo "**/bin/*" >repo/.gitignore &&
 	git -C repo reset --hard 2>err &&
-	test_i18ngrep ! "disabling cone patterns" err
+	! grep "disabling cone patterns" err
 '
 
 test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' '
@@ -417,7 +417,7 @@ test_expect_success 'sparse-checkout reapply' '
 
 	git -C tweak checkout HEAD deep/deeper2/a &&
 	git -C tweak sparse-checkout reapply 2>err &&
-	test_i18ngrep ! "warning.*The following paths are not up to date" err &&
+	! grep "warning.*The following paths are not up to date" err &&
 	test_path_is_missing tweak/deep/deeper2/a &&
 	test_i18ngrep "warning.*The following paths are unmerged" err &&
 	test_path_is_file tweak/folder1/a &&
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index b17f5c21fb..884b33569c 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -301,7 +301,7 @@ test_expect_success 'unparseable tree object' '
 	test_must_fail git fsck 2>out &&
 	test_i18ngrep "error: empty filename in tree entry" out &&
 	test_i18ngrep "$tree_sha1" out &&
-	test_i18ngrep ! "fatal: empty filename in tree entry" out
+	! grep "fatal: empty filename in tree entry" out
 '
 
 test_expect_success 'tree entry with type mismatch' '
@@ -319,7 +319,7 @@ test_expect_success 'tree entry with type mismatch' '
 	git update-ref refs/heads/type_mismatch $commit &&
 	test_must_fail git fsck >out 2>&1 &&
 	test_i18ngrep "is a blob, not a tree" out &&
-	test_i18ngrep ! "dangling blob" out
+	! grep "dangling blob" out
 '
 
 test_expect_success 'tag pointing to nonexistent' '
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index e2ae15a2cf..80006b3707 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -167,7 +167,7 @@ test_expect_success 'relative path when cwd is outside worktree' '
 
 test_expect_success '<commit>:file correctly diagnosed after a pathname' '
 	test_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&
-	test_i18ngrep ! "exists on disk" error &&
+	! grep "exists on disk" error &&
 	test_i18ngrep "no such path in the working tree" error &&
 	cat >expect <<-\EOF &&
 	file.txt
diff --git a/t/t2019-checkout-ambiguous-ref.sh b/t/t2019-checkout-ambiguous-ref.sh
index b99d5192a9..2a46257c76 100755
--- a/t/t2019-checkout-ambiguous-ref.sh
+++ b/t/t2019-checkout-ambiguous-ref.sh
@@ -31,7 +31,7 @@ test_expect_success 'checkout chooses branch over tag' '
 
 test_expect_success 'checkout reports switch to branch' '
 	test_i18ngrep "Switched to branch" stderr &&
-	test_i18ngrep ! "^HEAD is now at" stderr
+	! grep "^HEAD is now at" stderr
 '
 
 test_expect_success 'checkout vague ref succeeds' '
@@ -53,7 +53,7 @@ test_expect_success VAGUENESS_SUCCESS 'checkout chooses branch over tag' '
 
 test_expect_success VAGUENESS_SUCCESS 'checkout reports switch to branch' '
 	test_i18ngrep "Switched to branch" stderr &&
-	test_i18ngrep ! "^HEAD is now at" stderr
+	! grep "^HEAD is now at" stderr
 '
 
 test_done
diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh
index b748db9946..552dd9f505 100755
--- a/t/t2020-checkout-detach.sh
+++ b/t/t2020-checkout-detach.sh
@@ -14,10 +14,10 @@ check_not_detached () {
 PREV_HEAD_DESC='Previous HEAD position was'
 check_orphan_warning() {
 	test_i18ngrep "you are leaving $2 behind" "$1" &&
-	test_i18ngrep ! "$PREV_HEAD_DESC" "$1"
+	! grep "$PREV_HEAD_DESC" "$1"
 }
 check_no_orphan_warning() {
-	test_i18ngrep ! "you are leaving .* commit.*behind" "$1" &&
+	! grep "you are leaving .* commit.*behind" "$1" &&
 	test_i18ngrep "$PREV_HEAD_DESC" "$1"
 }
 
diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh
index a4f8d3a67e..6e5042c606 100755
--- a/t/t2024-checkout-dwim.sh
+++ b/t/t2024-checkout-dwim.sh
@@ -118,7 +118,7 @@ test_expect_success PERL 'checkout -p with multiple remotes does not print advic
 	test_might_fail git branch -D foo &&
 
 	git checkout -p foo 2>stderr &&
-	test_i18ngrep ! "^hint: " stderr &&
+	! grep "^hint: " stderr &&
 	status_uno_is_clean
 '
 
diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh
index 7a2da972fd..958653aebf 100755
--- a/t/t3418-rebase-continue.sh
+++ b/t/t3418-rebase-continue.sh
@@ -178,7 +178,7 @@ test_expect_success '--skip after failed fixup cleans commit message' '
 
 	(test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
 	git show HEAD >out &&
-	test_i18ngrep ! "# This is a combination" out &&
+	! grep "# This is a combination" out &&
 
 	: Final squash failed, but there was still a squash &&
 	test_i18ngrep "# This is a combination of 2 commits" .git/copy.txt &&
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index a21adcf0e4..2cc7338b75 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -555,7 +555,7 @@ test_expect_success 'cherry-pick preserves sparse-checkout' '
 	echo /unrelated >.git/info/sparse-checkout &&
 	git read-tree --reset -u HEAD &&
 	test_must_fail git cherry-pick -Xours picked>actual &&
-	test_i18ngrep ! "Changes not staged for commit:" actual
+	! grep "Changes not staged for commit:" actual
 '
 
 test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index efec8d13b6..aa407095e9 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -264,7 +264,7 @@ test_expect_success 'Resolving by removal is not a warning-worthy event' '
 		echo "100644 $blob $stage	blob"
 	done | git update-index --index-info &&
 	git rm blob >msg 2>&1 &&
-	test_i18ngrep ! "needs merge" msg &&
+	! grep "needs merge" msg &&
 	test_must_fail git ls-files -s --error-unmatch blob
 '
 
diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh
index c16486a9d4..9fa37836c0 100755
--- a/t/t4001-diff-rename.sh
+++ b/t/t4001-diff-rename.sh
@@ -145,7 +145,7 @@ test_expect_success 'test diff.renames=true for git status' '
 
 test_expect_success 'test diff.renames=false for git status' '
 	git -c diff.renames=false status >out &&
-	test_i18ngrep ! "renamed: .*path1 -> subdir/path1" out &&
+	! grep "renamed: .*path1 -> subdir/path1" out &&
 	test_i18ngrep "new file: .*subdir/path1" out &&
 	test_i18ngrep "deleted: .*[^/]path1" out
 '
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index c5e5e0da3f..dce16a4741 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -2242,7 +2242,7 @@ test_expect_success 'interdiff: cover-letter' '
 	EOF
 	git format-patch --cover-letter --interdiff=boop~2 -1 boop &&
 	test_i18ngrep "^Interdiff:$" 0000-cover-letter.patch &&
-	test_i18ngrep ! "^Interdiff:$" 0001-fleep.patch &&
+	! grep "^Interdiff:$" 0001-fleep.patch &&
 	sed "1,/^@@ /d; /^-- $/q" 0000-cover-letter.patch >actual &&
 	test_cmp expect actual
 '
diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index 9675bc17db..b75b6358d1 100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
@@ -60,15 +60,15 @@ do
 		echo "*.java diff=$p" >.gitattributes &&
 		test_expect_code 1 git diff --no-index \
 			A.java B.java 2>msg &&
-		test_i18ngrep ! fatal msg &&
-		test_i18ngrep ! error msg
+		! grep fatal msg &&
+		! grep error msg
 	'
 	test_expect_success "builtin $p wordRegex pattern compiles" '
 		echo "*.java diff=$p" >.gitattributes &&
 		test_expect_code 1 git diff --no-index --word-diff \
 			A.java B.java 2>msg &&
-		test_i18ngrep ! fatal msg &&
-		test_i18ngrep ! error msg
+		! grep fatal msg &&
+		! grep error msg
 	'
 done
 
diff --git a/t/t4153-am-resume-override-opts.sh b/t/t4153-am-resume-override-opts.sh
index 8ea22d1bcb..74d4e07632 100755
--- a/t/t4153-am-resume-override-opts.sh
+++ b/t/t4153-am-resume-override-opts.sh
@@ -53,7 +53,7 @@ test_expect_success '--no-quiet overrides --quiet' '
 	# Applying side1 will be quiet.
 	test_must_fail git am --quiet side[123].eml >out &&
 	test_path_is_dir .git/rebase-apply &&
-	test_i18ngrep ! "^Applying: " out &&
+	! grep "^Applying: " out &&
 	echo side1 >file &&
 	git add file &&
 
diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh
index 4d3842b83b..5dc03be6e6 100755
--- a/t/t5324-split-commit-graph.sh
+++ b/t/t5324-split-commit-graph.sh
@@ -342,7 +342,7 @@ test_expect_success 'add octopus merge' '
 	git commit-graph write --reachable --split &&
 	git commit-graph verify --progress 2>err &&
 	test_line_count = 3 err &&
-	test_i18ngrep ! warning err &&
+	! grep warning err &&
 	test_line_count = 3 $graphdir/commit-graph-chain
 '
 
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index ecadf02d64..8db6c1feaf 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -1341,7 +1341,7 @@ test_expect_success 'unqualified <dst> refspec DWIM and advice' '
 			test_must_fail git -c advice.pushUnqualifiedRefName=false \
 				push origin $oid:dst 2>err &&
 			test_i18ngrep "error: The destination you" err &&
-			test_i18ngrep ! "hint: Did you mean" err ||
+			! grep "hint: Did you mean" err ||
 			exit_with=false
 		done &&
 		$exit_with
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 2013051a64..bfb282744e 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -993,7 +993,7 @@ test_expect_success '--no-show-forced-updates' '
 	(
 		cd no-forced-update-clone &&
 		git fetch --no-show-forced-updates origin 2>output &&
-		test_i18ngrep ! "(forced update)" output
+		! grep "(forced update)" output
 	)
 '
 
diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh
index af0385fb89..a9a4df21b2 100755
--- a/t/t5534-push-signed.sh
+++ b/t/t5534-push-signed.sh
@@ -284,7 +284,7 @@ test_expect_success GPG 'failed atomic push does not execute GPG' '
 			--signed --atomic --porcelain \
 			dst noop ff noff >out 2>err &&
 
-	test_i18ngrep ! "gpg failed to sign" err &&
+	! grep "gpg failed to sign" err &&
 	cat >expect <<-EOF &&
 	To dst
 	=	refs/heads/noop:refs/heads/noop	[up to date]
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 187454f5dd..6969744d93 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -321,7 +321,7 @@ test_expect_success TTY 'push --no-progress silences progress but not status' '
 	test_commit no-progress &&
 	test_terminal git push --no-progress >output 2>&1 &&
 	test_i18ngrep "^To http" output &&
-	test_i18ngrep ! "^Writing objects" output
+	! grep "^Writing objects" output
 '
 
 test_expect_success 'push --progress shows progress to non-tty' '
@@ -503,7 +503,7 @@ test_expect_success 'colorize errors/hints' '
 	test_i18ngrep "<RED>.*rejected.*<RESET>" decoded &&
 	test_i18ngrep "<RED>error: failed to push some refs" decoded &&
 	test_i18ngrep "<YELLOW>hint: " decoded &&
-	test_i18ngrep ! "^hint: " decoded
+	! grep "^hint: " decoded
 '
 
 test_done
diff --git a/t/t5580-unc-paths.sh b/t/t5580-unc-paths.sh
index cf768b3a27..c143989456 100755
--- a/t/t5580-unc-paths.sh
+++ b/t/t5580-unc-paths.sh
@@ -71,7 +71,7 @@ test_expect_success push '
 test_expect_success MINGW 'remote nick cannot contain backslashes' '
 	BACKSLASHED="$(winpwd | tr / \\\\)" &&
 	git ls-remote "$BACKSLASHED" 2>err &&
-	test_i18ngrep ! "unable to access" err
+	! grep "unable to access" err
 '
 
 test_expect_success 'unc alternates' '
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 7f082fb23b..2eb221adb3 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -89,7 +89,7 @@ test_expect_success 'redirected clone does not show progress' '
 
 	git clone "file://$(pwd)/parent" clone-redirected >out 2>err &&
 	! grep % err &&
-	test_i18ngrep ! "Checking connectivity" err
+	! grep "Checking connectivity" err
 
 '
 
diff --git a/t/t6001-rev-list-graft.sh b/t/t6001-rev-list-graft.sh
index 7504ba4751..5af149f58a 100755
--- a/t/t6001-rev-list-graft.sh
+++ b/t/t6001-rev-list-graft.sh
@@ -116,7 +116,7 @@ test_expect_success 'show advice that grafts are deprecated' '
 	test_i18ngrep "git replace" err &&
 	test_config advice.graftFileDeprecated false &&
 	git show HEAD 2>err &&
-	test_i18ngrep ! "git replace" err
+	! grep "git replace" err
 '
 
 test_done
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index c80dc10b8f..a6641e8874 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -489,7 +489,7 @@ test_expect_success '--convert-graft-file' '
 	git status 2>stderr &&
 	test_i18ngrep "hint:.*grafts is deprecated" stderr &&
 	git replace --convert-graft-file 2>stderr &&
-	test_i18ngrep ! "hint:.*grafts is deprecated" stderr &&
+	! grep "hint:.*grafts is deprecated" stderr &&
 	test_path_is_missing .git/info/grafts &&
 
 	: verify that the history is now "grafted" &&
diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh
index 4ab133f489..089f220160 100755
--- a/t/t6423-merge-rename-directories.sh
+++ b/t/t6423-merge-rename-directories.sh
@@ -591,7 +591,7 @@ test_expect_success '2b: Directory split into two on one side, with equal number
 		git rev-parse >expect \
 			 O:z/b  O:z/c  B:x/d &&
 		test_cmp expect actual &&
-		test_i18ngrep ! "CONFLICT.*directory rename split" out
+		! grep "CONFLICT.*directory rename split" out
 	)
 '
 
@@ -727,7 +727,7 @@ test_expect_success '3b: Avoid implicit rename if involved as source on current
 
 		test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
 		test_i18ngrep CONFLICT.*rename/rename.*z/d.*x/d.*w/d out &&
-		test_i18ngrep ! CONFLICT.*rename/rename.*y/d out &&
+		! grep CONFLICT.*rename/rename.*y/d out &&
 
 		git ls-files -s >out &&
 		test_line_count = 5 out &&
@@ -3606,7 +3606,7 @@ test_expect_merge_algorithm failure success '10e: Does git complain about untrac
 		echo random >z/c &&
 
 		git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
-		test_i18ngrep ! "following untracked working tree files would be overwritten by merge" err &&
+		! grep "following untracked working tree files would be overwritten by merge" err &&
 
 		git ls-files -s >out &&
 		test_line_count = 3 out &&
@@ -5356,9 +5356,9 @@ test_expect_success '13e: directory rename detection in recursive case' '
 
 		git -c merge.directoryRenames=conflict merge -s recursive C^0 >out 2>err &&
 
-		test_i18ngrep ! CONFLICT out &&
-		test_i18ngrep ! BUG: err &&
-		test_i18ngrep ! core.dumped err &&
+		! grep CONFLICT out &&
+		! grep BUG: err &&
+		! grep core.dumped err &&
 		test_must_be_empty err &&
 
 		git ls-files >paths &&
diff --git a/t/t6433-merge-toplevel.sh b/t/t6433-merge-toplevel.sh
index e29c284b9b..8418050d2d 100755
--- a/t/t6433-merge-toplevel.sh
+++ b/t/t6433-merge-toplevel.sh
@@ -148,7 +148,7 @@ test_expect_success 'refuse two-project merge by default, quit before --autostas
 	echo change >>one.t &&
 	git diff >expect &&
 	test_must_fail git merge --autostash five 2>err &&
-	test_i18ngrep ! "stash" err &&
+	! grep "stash" err &&
 	git diff >actual &&
 	test_cmp expect actual
 '
diff --git a/t/t6437-submodule-merge.sh b/t/t6437-submodule-merge.sh
index 3ead2b726f..e42a96cad4 100755
--- a/t/t6437-submodule-merge.sh
+++ b/t/t6437-submodule-merge.sh
@@ -446,7 +446,7 @@ test_expect_failure !FAIL_PREREQS 'directory/submodule conflict; should not trea
 		# We do not want files within the submodule to prevent the
 		# merge from starting; we should not be writing to such paths
 		# anyway.
-		test_i18ngrep ! "refusing to lose untracked file at" err
+		! grep "refusing to lose untracked file at" err
 	)
 '
 
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index 4a3b8f48ac..8670da6bf9 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -111,7 +111,7 @@ test_expect_success 'auto gc with too many loose objects does not attempt to cre
 	test_commit "$(test_oid obj4)" &&
 
 	git gc --auto 2>err &&
-	test_i18ngrep ! "^warning:" err &&
+	! grep "^warning:" err &&
 	ls .git/objects/pack/ | sort >post_packs &&
 	comm -1 -3 existing_packs post_packs >new &&
 	comm -2 -3 existing_packs post_packs >del &&
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index fec7e0299d..113b25892b 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -158,7 +158,7 @@ test_expect_success 'redirected submodule add does not show progress' '
 	git -C addtest submodule add "file://$submodurl/parent" submod-redirected \
 		2>err &&
 	! grep % err &&
-	test_i18ngrep ! "Checking connectivity" err
+	! grep "Checking connectivity" err
 '
 
 test_expect_success 'redirected submodule add --progress does show progress' '
@@ -1101,7 +1101,7 @@ test_expect_success 'submodule deinit deinits a submodule when its work tree is
 	git submodule deinit init example2 >actual &&
 	test -z "$(git config --get-regexp "submodule\.example\.")" &&
 	test -z "$(git config --get-regexp "submodule\.example2\.")" &&
-	test_i18ngrep ! "Cleared directory .init" actual &&
+	! grep "Cleared directory .init" actual &&
 	test_i18ngrep "Cleared directory .example2" actual &&
 	rmdir init
 '
@@ -1151,19 +1151,19 @@ test_expect_success 'submodule deinit is silent when used on an uninitialized su
 	test_i18ngrep "Submodule .example. (.*) unregistered for path .init" actual &&
 	test_i18ngrep "Cleared directory .init" actual &&
 	git submodule deinit init >actual &&
-	test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
+	! grep "Submodule .example. (.*) unregistered for path .init" actual &&
 	test_i18ngrep "Cleared directory .init" actual &&
 	git submodule deinit . >actual &&
-	test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
+	! grep "Submodule .example. (.*) unregistered for path .init" actual &&
 	test_i18ngrep "Submodule .example2. (.*) unregistered for path .example2" actual &&
 	test_i18ngrep "Cleared directory .init" actual &&
 	git submodule deinit . >actual &&
-	test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
-	test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
+	! grep "Submodule .example. (.*) unregistered for path .init" actual &&
+	! grep "Submodule .example2. (.*) unregistered for path .example2" actual &&
 	test_i18ngrep "Cleared directory .init" actual &&
 	git submodule deinit --all >actual &&
-	test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual &&
-	test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual &&
+	! grep "Submodule .example. (.*) unregistered for path .init" actual &&
+	! grep "Submodule .example2. (.*) unregistered for path .example2" actual &&
 	test_i18ngrep "Cleared directory .init" actual &&
 	rmdir init example2
 '
diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh
index f2e7df59cf..2bae75228e 100755
--- a/t/t7414-submodule-mistakes.sh
+++ b/t/t7414-submodule-mistakes.sh
@@ -17,7 +17,7 @@ test_expect_success 'git-add on embedded repository warns' '
 test_expect_success '--no-warn-embedded-repo suppresses warning' '
 	test_when_finished "git rm --cached -f embed" &&
 	git add --no-warn-embedded-repo embed 2>stderr &&
-	test_i18ngrep ! warning stderr
+	! grep warning stderr
 '
 
 test_expect_success 'no warning when updating entry' '
@@ -25,13 +25,13 @@ test_expect_success 'no warning when updating entry' '
 	git add embed &&
 	git -C embed commit --allow-empty -m two &&
 	git add embed 2>stderr &&
-	test_i18ngrep ! warning stderr
+	! grep warning stderr
 '
 
 test_expect_success 'submodule add does not warn' '
 	test_when_finished "git rm -rf submodule .gitmodules" &&
 	git submodule add ./embed submodule 2>stderr &&
-	test_i18ngrep ! warning stderr
+	! grep warning stderr
 '
 
 test_done
diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh
index f70368bc2e..5228c88b9f 100755
--- a/t/t7415-submodule-names.sh
+++ b/t/t7415-submodule-names.sh
@@ -187,7 +187,7 @@ test_expect_success 'fsck detects corrupt .gitmodules' '
 
 		git fsck 2>output &&
 		test_i18ngrep gitmodulesParse output &&
-		test_i18ngrep ! "bad config" output
+		! grep "bad config" output
 	)
 '
 
diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh
index eec96e0ba9..80b36914c4 100755
--- a/t/t7416-submodule-dash-url.sh
+++ b/t/t7416-submodule-dash-url.sh
@@ -57,7 +57,7 @@ test_expect_success 'trailing backslash is handled correctly' '
 	mv .new .gitmodules &&
 	git commit -am "Add testmodule" &&
 	test_must_fail git clone --verbose --recurse-submodules . dolly 2>err &&
-	test_i18ngrep ! "unknown option" err
+	! grep "unknown option" err
 '
 
 test_expect_success 'fsck rejects missing URL scheme' '
diff --git a/t/t7502-commit-porcelain.sh b/t/t7502-commit-porcelain.sh
index 14c92e4c25..6639a849c9 100755
--- a/t/t7502-commit-porcelain.sh
+++ b/t/t7502-commit-porcelain.sh
@@ -526,7 +526,7 @@ try_commit () {
 	GIT_EDITOR=.git/FAKE_EDITOR git commit -a $* $use_template &&
 	case "$use_template" in
 	'')
-		test_i18ngrep ! "^## Custom template" .git/COMMIT_EDITMSG ;;
+		! grep "^## Custom template" .git/COMMIT_EDITMSG ;;
 	*)
 		test_i18ngrep "^## Custom template" .git/COMMIT_EDITMSG ;;
 	esac
@@ -546,7 +546,7 @@ try_commit_status_combo () {
 
 	test_expect_success 'commit --no-status' '
 		try_commit --no-status &&
-		test_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG
+		! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
 	'
 
 	test_expect_success 'commit with commit.status = yes' '
@@ -558,7 +558,7 @@ try_commit_status_combo () {
 	test_expect_success 'commit with commit.status = no' '
 		test_config commit.status no &&
 		try_commit "" &&
-		test_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG
+		! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
 	'
 
 	test_expect_success 'commit --status with commit.status = yes' '
@@ -570,7 +570,7 @@ try_commit_status_combo () {
 	test_expect_success 'commit --no-status with commit.status = yes' '
 		test_config commit.status yes &&
 		try_commit --no-status &&
-		test_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG
+		! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
 	'
 
 	test_expect_success 'commit --status with commit.status = no' '
@@ -582,7 +582,7 @@ try_commit_status_combo () {
 	test_expect_success 'commit --no-status with commit.status = no' '
 		test_config commit.status no &&
 		try_commit --no-status &&
-		test_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG
+		! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
 	'
 
 }
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index 963fed6821..091c4dadea 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -1547,7 +1547,7 @@ test_expect_success 'git commit will commit a staged but ignored submodule' '
 	export GIT_EDITOR &&
 	git commit -uno &&
 	git status -s --ignore-submodules=dirty >output &&
-	test_i18ngrep ! "^M. sm" output
+	! grep "^M. sm" output
 '
 
 test_expect_success 'git commit --dry-run will show a staged but ignored submodule' '
@@ -1579,7 +1579,7 @@ EOF
 test_expect_success 'git commit -m will commit a staged but ignored submodule' '
 	git commit -uno -m message &&
 	git status -s --ignore-submodules=dirty >output &&
-	test_i18ngrep ! "^M. sm" output &&
+	! grep "^M. sm" output &&
 	git config --remove-section submodule.subname &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
@@ -1626,7 +1626,7 @@ test_expect_success '"No commits yet" should not be noted in status output' '
 	git checkout --orphan empty-branch-2 &&
 	test_commit test-commit-1 &&
 	git status >output &&
-	test_i18ngrep ! "No commits yet" output
+	! grep "No commits yet" output
 '
 
 test_expect_success '"Initial commit" should be noted in commit template' '
@@ -1643,7 +1643,7 @@ test_expect_success '"Initial commit" should not be noted in commit template' '
 	touch to_be_committed_2 &&
 	git add to_be_committed_2 &&
 	git commit --dry-run >output &&
-	test_i18ngrep ! "Initial commit" output
+	! grep "Initial commit" output
 '
 
 test_expect_success '--no-optional-locks prevents index update' '
diff --git a/t/t7518-ident-corner-cases.sh b/t/t7518-ident-corner-cases.sh
index 905957bd0a..1310b4381e 100755
--- a/t/t7518-ident-corner-cases.sh
+++ b/t/t7518-ident-corner-cases.sh
@@ -13,7 +13,7 @@ test_expect_success 'empty name and missing email' '
 		sane_unset GIT_AUTHOR_EMAIL &&
 		GIT_AUTHOR_NAME= &&
 		test_must_fail git commit --allow-empty -m foo 2>err &&
-		test_i18ngrep ! "(null)" err
+		! grep "(null)" err
 	)
 '
 
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index fbfdcca000..f2c1e0b741 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -290,10 +290,10 @@ do
 			rm -f marker &&
 			git status >actual &&
 			test_path_is_file marker &&
-			test_i18ngrep ! "Changes not staged for commit:" actual &&
+			! grep "Changes not staged for commit:" actual &&
 			if test $uc_val = true
 			then
-				test_i18ngrep ! "Untracked files:" actual
+				! grep "Untracked files:" actual
 			fi &&
 			if test $uc_val = false
 			then
diff --git a/t/t7520-ignored-hook-warning.sh b/t/t7520-ignored-hook-warning.sh
index 634fb7f23a..06682b20d0 100755
--- a/t/t7520-ignored-hook-warning.sh
+++ b/t/t7520-ignored-hook-warning.sh
@@ -15,7 +15,7 @@ test_expect_success setup '
 
 test_expect_success 'no warning if hook is not ignored' '
 	git commit --allow-empty -m "more" 2>message &&
-	test_i18ngrep ! -e "hook was ignored" message
+	! grep -e "hook was ignored" message
 '
 
 test_expect_success POSIXPERM 'warning if hook is ignored' '
@@ -28,14 +28,14 @@ test_expect_success POSIXPERM 'no warning if advice.ignoredHook set to false' '
 	test_config advice.ignoredHook false &&
 	chmod -x "$hook" &&
 	git commit --allow-empty -m "even more" 2>message &&
-	test_i18ngrep ! -e "hook was ignored" message
+	! grep -e "hook was ignored" message
 '
 
 test_expect_success 'no warning if unset advice.ignoredHook and hook removed' '
 	rm -f "$hook" &&
 	test_unconfig advice.ignoredHook &&
 	git commit --allow-empty -m "even more" 2>message &&
-	test_i18ngrep ! -e "hook was ignored" message
+	! grep -e "hook was ignored" message
 '
 
 test_done
diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
index 52e8ccc933..10b392028e 100755
--- a/t/t7601-merge-pull-config.sh
+++ b/t/t7601-merge-pull-config.sh
@@ -30,58 +30,58 @@ test_expect_success 'setup' '
 test_expect_success 'pull.rebase not set' '
 	git reset --hard c0 &&
 	git pull . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and pull.ff=true' '
 	git reset --hard c0 &&
 	test_config pull.ff true &&
 	git pull . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and pull.ff=false' '
 	git reset --hard c0 &&
 	test_config pull.ff false &&
 	git pull . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and pull.ff=only' '
 	git reset --hard c0 &&
 	test_config pull.ff only &&
 	git pull . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --rebase given' '
 	git reset --hard c0 &&
 	git pull --rebase . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --no-rebase given' '
 	git reset --hard c0 &&
 	git pull --no-rebase . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --ff given' '
 	git reset --hard c0 &&
 	git pull --ff . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --no-ff given' '
 	git reset --hard c0 &&
 	git pull --no-ff . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --ff-only given' '
 	git reset --hard c0 &&
 	git pull --ff-only . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set (not-fast-forward)' '
@@ -96,51 +96,51 @@ test_expect_success 'pull.rebase not set and pull.ff=true (not-fast-forward)' '
 	git reset --hard c2 &&
 	test_config pull.ff true &&
 	git pull . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and pull.ff=false (not-fast-forward)' '
 	git reset --hard c2 &&
 	test_config pull.ff false &&
 	git pull . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and pull.ff=only (not-fast-forward)' '
 	git reset --hard c2 &&
 	test_config pull.ff only &&
 	test_must_fail git pull . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --rebase given (not-fast-forward)' '
 	git reset --hard c2 &&
 	git pull --rebase . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --no-rebase given (not-fast-forward)' '
 	git reset --hard c2 &&
 	git pull --no-rebase . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --ff given (not-fast-forward)' '
 	git reset --hard c2 &&
 	git pull --ff . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --no-ff given (not-fast-forward)' '
 	git reset --hard c2 &&
 	git pull --no-ff . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'pull.rebase not set and --ff-only given (not-fast-forward)' '
 	git reset --hard c2 &&
 	test_must_fail git pull --ff-only . c1 2>err &&
-	test_i18ngrep ! "Pulling without specifying how to reconcile" err
+	! grep "Pulling without specifying how to reconcile" err
 '
 
 test_expect_success 'merge c1 with c2' '
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 991d5bd9c0..a7e17b1a5e 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -1268,7 +1268,7 @@ test_expect_success 'grep --no-index prefers paths to revs' '
 
 test_expect_success 'grep --no-index does not "diagnose" revs' '
 	test_must_fail git grep --no-index o :1:hello.c 2>err &&
-	test_i18ngrep ! -i "did you mean" err
+	! grep -i "did you mean" err
 '
 
 cat >expected <<EOF
diff --git a/t/t7816-grep-binary-pattern.sh b/t/t7816-grep-binary-pattern.sh
index 60bab291e4..25cbc16446 100755
--- a/t/t7816-grep-binary-pattern.sh
+++ b/t/t7816-grep-binary-pattern.sh
@@ -25,7 +25,7 @@ nul_match_internal () {
 			>stderr &&
 			printf '$pattern' | q_to_nul >f &&
 			test_must_fail env LC_ALL=\"$lc_all\" git grep $extra_flags -f f $flags a 2>stderr &&
-			test_i18ngrep ! 'This is only supported with -P under PCRE v2' stderr
+			! grep 'This is only supported with -P under PCRE v2' stderr
 		"
 	elif test "$matches" = P
 	then
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index c98c1dfc23..3f656bbbaa 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -202,7 +202,7 @@ test_expect_success 'exit when p4 fails to produce marshaled output' '
 		export PATH &&
 		test_expect_code 1 git p4 clone --dest="$git" //depot >errs 2>&1
 	) &&
-	test_i18ngrep ! Traceback errs
+	! grep Traceback errs
 '
 
 # Hide a file from p4d, make sure we catch its complaint.  This won't fail in
diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh
index eaaae414a1..22c8106b13 100755
--- a/t/t9807-git-p4-submit.sh
+++ b/t/t9807-git-p4-submit.sh
@@ -460,7 +460,7 @@ test_expect_success 'submit --prepare-p4-only' '
 		git p4 submit --prepare-p4-only >out &&
 		test_i18ngrep "prepared for submission" out &&
 		test_i18ngrep "must be deleted" out &&
-		test_i18ngrep ! "everything below this line is just the diff" out
+		! grep "everything below this line is just the diff" out
 	) &&
 	(
 		cd "$cli" &&
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 5/6] tests: (almost) remove C_LOCALE_OUTPUT prerequisites
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
                                             ` (7 preceding siblings ...)
  2021-01-11 14:47                           ` [PATCH 4/6] tests: (almost) remove use of "test_i18ngrep !" Ævar Arnfjörð Bjarmason
@ 2021-01-11 14:47                           ` Ævar Arnfjörð Bjarmason
  2021-01-11 14:47                           ` [PATCH 6/6] tests: remove uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
  2021-01-11 21:05                           ` Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false? Junio C Hamano
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 14:47 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

Almost entirely Remove the C_LOCALE_OUTPUT prerequisites and its uses
as a part of getting rid of the GIT_TEST_GETTEXT_POISON facility.

As with test_i18ngrep we're not removing the stub C_LOCALE_OUTPUT
prerequisite yet for the benefit of other in-flight code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0000-basic.sh                    |  2 +-
 t/t0020-crlf.sh                     |  6 ++----
 t/t0201-gettext-fallbacks.sh        |  2 +-
 t/t1430-bad-ref-name.sh             |  2 +-
 t/t1512-rev-parse-disambiguation.sh | 14 +++++++-------
 t/t3404-rebase-interactive.sh       | 14 +++++++-------
 t/t3415-rebase-autosquash.sh        | 10 +++++-----
 t/t3701-add-interactive.sh          |  2 +-
 t/t4012-diff-binary.sh              |  4 ++--
 t/t4205-log-pretty-formats.sh       |  2 +-
 t/t5300-pack-object.sh              |  4 ++--
 t/t5505-remote.sh                   |  6 +++---
 t/t5510-fetch.sh                    |  4 ++--
 t/t5601-clone.sh                    |  2 +-
 t/t6423-merge-rename-directories.sh |  2 +-
 t/t7300-clean.sh                    |  6 +++---
 t/t7810-grep.sh                     |  2 +-
 t/t9003-help-autocorrect.sh         |  7 ++-----
 18 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index f4ba2e8c85..45a88315ad 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -271,7 +271,7 @@ test_expect_success 'pretend we have a mix of all possible results' "
 	EOF
 "
 
-test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
+test_expect_success 'test --verbose' '
 	run_sub_test_lib_test_err \
 		t1234-verbose "test verbose" --verbose <<-\EOF &&
 	test_expect_success "passing test" true
diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh
index b63ba62e5d..7081485e21 100755
--- a/t/t0020-crlf.sh
+++ b/t/t0020-crlf.sh
@@ -84,10 +84,8 @@ test_expect_success 'safecrlf: print warning only once' '
 	git commit -m "nowarn" &&
 	for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn &&
 	git add doublewarn 2>err &&
-	if test_have_prereq C_LOCALE_OUTPUT
-	then
-		test $(grep "CRLF will be replaced by LF" err | wc -l) = 1
-	fi
+	grep "CRLF will be replaced by LF" err >err.lines &&
+	test_line_count = 1 err.lines
 '
 
 
diff --git a/t/t0201-gettext-fallbacks.sh b/t/t0201-gettext-fallbacks.sh
index 90da1c7ddc..a7b3e4a2c7 100755
--- a/t/t0201-gettext-fallbacks.sh
+++ b/t/t0201-gettext-fallbacks.sh
@@ -18,7 +18,7 @@ test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_TEST_FALLBACKS is set' '
     test -n "$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS"
 '
 
-test_expect_success C_LOCALE_OUTPUT 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is fallthrough' '
+test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is fallthrough' '
     echo fallthrough >expect &&
     echo $GIT_INTERNAL_GETTEXT_SH_SCHEME >actual &&
     test_cmp expect actual
diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh
index c7878a60ed..138fc9b1c3 100755
--- a/t/t1430-bad-ref-name.sh
+++ b/t/t1430-bad-ref-name.sh
@@ -122,7 +122,7 @@ test_expect_success 'push cannot create a badly named ref' '
 	! grep -e "broken\.\.\.ref" output
 '
 
-test_expect_failure C_LOCALE_OUTPUT 'push --mirror can delete badly named ref' '
+test_expect_failure 'push --mirror can delete badly named ref' '
 	top=$(pwd) &&
 	git init src &&
 	git init dest &&
diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh
index 18fa6cf40d..3a4b337ae0 100755
--- a/t/t1512-rev-parse-disambiguation.sh
+++ b/t/t1512-rev-parse-disambiguation.sh
@@ -311,39 +311,39 @@ test_expect_success 'ambiguous short sha1 ref' '
 	grep "refname.*${REF}.*ambiguous" err
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (raw)' '
+test_expect_success 'ambiguity errors are not repeated (raw)' '
 	test_must_fail git rev-parse 00000 2>stderr &&
 	grep "is ambiguous" stderr >errors &&
 	test_line_count = 1 errors
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (treeish)' '
+test_expect_success 'ambiguity errors are not repeated (treeish)' '
 	test_must_fail git rev-parse 00000:foo 2>stderr &&
 	grep "is ambiguous" stderr >errors &&
 	test_line_count = 1 errors
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (peel)' '
+test_expect_success 'ambiguity errors are not repeated (peel)' '
 	test_must_fail git rev-parse 00000^{commit} 2>stderr &&
 	grep "is ambiguous" stderr >errors &&
 	test_line_count = 1 errors
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity hints' '
+test_expect_success 'ambiguity hints' '
 	test_must_fail git rev-parse 000000000 2>stderr &&
 	grep ^hint: stderr >hints &&
 	# 16 candidates, plus one intro line
 	test_line_count = 17 hints
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity hints respect type' '
+test_expect_success 'ambiguity hints respect type' '
 	test_must_fail git rev-parse 000000000^{commit} 2>stderr &&
 	grep ^hint: stderr >hints &&
 	# 5 commits, 1 tag (which is a committish), plus intro line
 	test_line_count = 7 hints
 '
 
-test_expect_success C_LOCALE_OUTPUT 'failed type-selector still shows hint' '
+test_expect_success 'failed type-selector still shows hint' '
 	# these two blobs share the same prefix "ee3d", but neither
 	# will pass for a commit
 	echo 851 | git hash-object --stdin -w &&
@@ -367,7 +367,7 @@ test_expect_success 'core.disambiguate does not override context' '
 		git -c core.disambiguate=committish rev-parse $sha1^{tree}
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguous commits are printed by type first, then hash order' '
+test_expect_success 'ambiguous commits are printed by type first, then hash order' '
 	test_must_fail git rev-parse 0000 2>stderr &&
 	grep ^hint: stderr >hints &&
 	grep 0000 hints >objects &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index b06fc36159..c53ae6b5c7 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -447,7 +447,7 @@ test_expect_success 'verbose flag is heeded, even after --continue' '
 	grep "^ file1 | 2 +-$" output
 '
 
-test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '
+test_expect_success 'multi-squash only fires up editor once' '
 	base=$(git rev-parse HEAD~4) &&
 	(
 		set_fake_editor &&
@@ -460,7 +460,7 @@ test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '
 	test 1 = $(git show | grep ONCE | wc -l)
 '
 
-test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '
+test_expect_success 'multi-fixup does not fire up editor' '
 	git checkout -b multi-fixup E &&
 	base=$(git rev-parse HEAD~4) &&
 	(
@@ -511,7 +511,7 @@ test_expect_success 'commit message retained after conflict' '
 	git branch -D conflict-squash
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messages' '
+test_expect_success 'squash and fixup generate correct log messages' '
 	cat >expect-squash-fixup <<-\EOF &&
 	B
 
@@ -538,7 +538,7 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa
 	git branch -D squash-fixup
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
+test_expect_success 'squash ignores comments' '
 	git checkout -b skip-comments E &&
 	base=$(git rev-parse HEAD~4) &&
 	(
@@ -554,7 +554,7 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
 	git branch -D skip-comments
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '
+test_expect_success 'squash ignores blank lines' '
 	git checkout -b skip-blank-lines E &&
 	base=$(git rev-parse HEAD~4) &&
 	(
@@ -992,7 +992,7 @@ test_expect_success 'rebase -ix with several instances of --exec' '
 	test_cmp expected actual
 '
 
-test_expect_success C_LOCALE_OUTPUT 'rebase -ix with --autosquash' '
+test_expect_success 'rebase -ix with --autosquash' '
 	git reset --hard execute &&
 	git checkout -b autosquash &&
 	echo second >second.txt &&
@@ -1133,7 +1133,7 @@ test_expect_success 'rebase -i --root reword root when root has untracked file c
 	test "$(git rev-list --count HEAD)" = 2
 '
 
-test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' '
+test_expect_success 'rebase --edit-todo does not work on non-interactive rebase' '
 	git checkout reword-original-root-branch &&
 	git reset --hard &&
 	git checkout conflict-branch &&
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 7bab6000dc..e678f26c01 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -303,23 +303,23 @@ test_auto_fixup_fixup () {
 	fi
 }
 
-test_expect_success C_LOCALE_OUTPUT 'fixup! fixup!' '
+test_expect_success 'fixup! fixup!' '
 	test_auto_fixup_fixup fixup fixup
 '
 
-test_expect_success C_LOCALE_OUTPUT 'fixup! squash!' '
+test_expect_success 'fixup! squash!' '
 	test_auto_fixup_fixup fixup squash
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash! squash!' '
+test_expect_success 'squash! squash!' '
 	test_auto_fixup_fixup squash squash
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash! fixup!' '
+test_expect_success 'squash! fixup!' '
 	test_auto_fixup_fixup squash fixup
 '
 
-test_expect_success C_LOCALE_OUTPUT 'autosquash with custom inst format' '
+test_expect_success 'autosquash with custom inst format' '
 	git reset --hard base &&
 	git config --add rebase.instructionFormat "[%an @ %ar] %s"  &&
 	echo 2 >file1 &&
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index cc3f434a97..6cdde711e0 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -367,7 +367,7 @@ test_expect_success 'setup expected' '
 '
 
 # Test splitting the first patch, then adding both
-test_expect_success C_LOCALE_OUTPUT 'add first line works' '
+test_expect_success 'add first line works' '
 	git commit -am "clear local changes" &&
 	git apply patch &&
 	printf "%s\n" s y y | git add -p file 2>error |
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index 6579c81216..bd59328e4b 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -63,7 +63,7 @@ test_expect_success 'apply --numstat understands diff --binary format' '
 
 # apply needs to be able to skip the binary material correctly
 # in order to report the line number of a corrupt patch.
-test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
+test_expect_success 'apply detecting corrupt patch correctly' '
 	git diff >output &&
 	sed -e "s/-CIT/xCIT/" <output >broken &&
 	test_must_fail git apply --stat --summary broken 2>detected &&
@@ -73,7 +73,7 @@ test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
 	test "$detected" = xCIT
 '
 
-test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
+test_expect_success 'apply detecting corrupt patch correctly' '
 	git diff --binary | sed -e "s/-CIT/xCIT/" >broken &&
 	test_must_fail git apply --stat --summary broken 2>detected &&
 	detected=$(cat detected) &&
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 749bc1431a..5ec0f47b56 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -126,7 +126,7 @@ test_expect_success 'NUL separation with --stat' '
 	test_i18ncmp expected actual
 '
 
-test_expect_failure C_LOCALE_OUTPUT 'NUL termination with --stat' '
+test_expect_failure 'NUL termination with --stat' '
 	stat0_part=$(git diff --stat HEAD^ HEAD) &&
 	stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
 	printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n0" >expected &&
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index 392201cabd..d586fdc7a9 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -427,7 +427,7 @@ test_expect_success 'index-pack --strict <pack> works in non-repo' '
 	test_path_is_file foo.idx
 '
 
-test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'index-pack --threads=N or pack.threads=N warns when no pthreads' '
+test_expect_success !PTHREADS 'index-pack --threads=N or pack.threads=N warns when no pthreads' '
 	test_must_fail git index-pack --threads=2 2>err &&
 	grep ^warning: err >warnings &&
 	test_line_count = 1 warnings &&
@@ -445,7 +445,7 @@ test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'index-pack --threads=N or pack.th
 	grep -F "no threads support, ignoring pack.threads" err
 '
 
-test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'pack-objects --threads=N or pack.threads=N warns when no pthreads' '
+test_expect_success !PTHREADS 'pack-objects --threads=N or pack.threads=N warns when no pthreads' '
 	git pack-objects --threads=2 --stdout --all </dev/null >/dev/null 2>err &&
 	grep ^warning: err >warnings &&
 	test_line_count = 1 warnings &&
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 8db6c1feaf..3d5360d7cd 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -56,7 +56,7 @@ test_expect_success 'add remote whose URL agrees with url.<...>.insteadOf' '
 	git remote add myremote git@host.com:team/repo.git
 '
 
-test_expect_success C_LOCALE_OUTPUT 'remote information for the origin' '
+test_expect_success 'remote information for the origin' '
 	(
 		cd test &&
 		tokens_match origin "$(git remote)" &&
@@ -78,7 +78,7 @@ test_expect_success 'add another remote' '
 	)
 '
 
-test_expect_success C_LOCALE_OUTPUT 'check remote-tracking' '
+test_expect_success 'check remote-tracking' '
 	(
 		cd test &&
 		check_remote_track origin main side &&
@@ -104,7 +104,7 @@ test_expect_success 'remove remote' '
 	)
 '
 
-test_expect_success C_LOCALE_OUTPUT 'remove remote' '
+test_expect_success 'remove remote' '
 	(
 		cd test &&
 		tokens_match origin "$(git remote)" &&
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index bfb282744e..b7233fc8ce 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -944,7 +944,7 @@ test_expect_success 'fetching with auto-gc does not lock up' '
 	)
 '
 
-test_expect_success C_LOCALE_OUTPUT 'fetch aligned output' '
+test_expect_success 'fetch aligned output' '
 	git clone . full-output &&
 	test_commit looooooooooooong-tag &&
 	(
@@ -959,7 +959,7 @@ test_expect_success C_LOCALE_OUTPUT 'fetch aligned output' '
 	test_cmp expect actual
 '
 
-test_expect_success C_LOCALE_OUTPUT 'fetch compact output' '
+test_expect_success 'fetch compact output' '
 	git clone . compact &&
 	test_commit extraaa &&
 	(
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 7df3c5373a..d2b02fd25e 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -37,7 +37,7 @@ test_expect_success 'clone with excess parameters (2)' '
 
 '
 
-test_expect_success C_LOCALE_OUTPUT 'output from clone' '
+test_expect_success 'output from clone' '
 	rm -fr dst &&
 	git clone -n "file://$(pwd)/src" dst >output 2>&1 &&
 	test $(grep Clon output | wc -l) = 1
diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh
index 089f220160..2ca70f6274 100755
--- a/t/t6423-merge-rename-directories.sh
+++ b/t/t6423-merge-rename-directories.sh
@@ -2905,7 +2905,7 @@ test_setup_9e () {
 	)
 }
 
-test_expect_success C_LOCALE_OUTPUT '9e: N-to-1 whammo' '
+test_expect_success '9e: N-to-1 whammo' '
 	test_setup_9e &&
 	(
 		cd 9e &&
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index cb5e34d94c..a74816ca8b 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -110,7 +110,7 @@ test_expect_success 'git clean with prefix' '
 
 '
 
-test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' '
+test_expect_success 'git clean with relative prefix' '
 
 	mkdir -p build docs &&
 	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
@@ -123,7 +123,7 @@ test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' '
 	verbose test "$would_clean" = ../src/part3.c
 '
 
-test_expect_success C_LOCALE_OUTPUT 'git clean with absolute path' '
+test_expect_success 'git clean with absolute path' '
 
 	mkdir -p build docs &&
 	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
@@ -407,7 +407,7 @@ test_expect_success 'clean.requireForce and -f' '
 
 '
 
-test_expect_success C_LOCALE_OUTPUT 'core.excludesfile' '
+test_expect_success 'core.excludesfile' '
 
 	echo excludes >excludes &&
 	echo included >included &&
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index a7e17b1a5e..0c4a0e3865 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -978,7 +978,7 @@ do
 	"
 done
 
-test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'grep --threads=N or pack.threads=N warns when no pthreads' '
+test_expect_success !PTHREADS 'grep --threads=N or pack.threads=N warns when no pthreads' '
 	git grep --threads=2 Hello hello_world 2>err &&
 	grep ^warning: err >warnings &&
 	test_line_count = 1 warnings &&
diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh
index 03cd5c5423..f00deaf381 100755
--- a/t/t9003-help-autocorrect.sh
+++ b/t/t9003-help-autocorrect.sh
@@ -56,11 +56,8 @@ test_expect_success 'autocorrect can be declined altogether' '
 	git config help.autocorrect never &&
 
 	test_must_fail git lfg 2>actual &&
-	if test_have_prereq C_LOCALE_OUTPUT
-	then
-		grep "is not a git command" actual &&
-		test_line_count = 1 actual
-	fi
+	grep "is not a git command" actual &&
+	test_line_count = 1 actual
 '
 
 test_done
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH 6/6] tests: remove uses of GIT_TEST_GETTEXT_POISON=false
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
                                             ` (8 preceding siblings ...)
  2021-01-11 14:47                           ` [PATCH 5/6] tests: (almost) remove C_LOCALE_OUTPUT prerequisites Ævar Arnfjörð Bjarmason
@ 2021-01-11 14:47                           ` Ævar Arnfjörð Bjarmason
  2021-01-11 21:05                           ` Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false? Junio C Hamano
  10 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-11 14:47 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

As noted in previous commits we are removing the use of
GIT_TEST_GETTEXT_POISON=false. These tests all relied on the facility
being off, it always is off after an earlier change, but we hadn't
removed the redundant assignments to "false" in the tests.

I'm preserving the deletion of "error" lines in 38b9197a76a (t5411:
add basic test cases for proc-receive hook, 2020-08-27), it turns out
that's useful even without GIT_TEST_GETTEXT_POISON=true in
play. Update a comment added in that commit to note that.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1305-config-include.sh   | 4 +---
 t/t5411/common-functions.sh | 5 ++---
 t/t7201-co.sh               | 2 +-
 t/t9902-completion.sh       | 1 -
 4 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
index f1e1b289f9..f08cfcdfae 100755
--- a/t/t1305-config-include.sh
+++ b/t/t1305-config-include.sh
@@ -352,9 +352,7 @@ test_expect_success 'include cycles are detected' '
 	git init --bare cycle &&
 	git -C cycle config include.path cycle &&
 	git config -f cycle/cycle include.path config &&
-	test_must_fail \
-		env GIT_TEST_GETTEXT_POISON=false \
-		git -C cycle config --get-all test.value 2>stderr &&
+	test_must_fail git -C cycle config --get-all test.value 2>stderr &&
 	grep "exceeded maximum include depth" stderr
 '
 
diff --git a/t/t5411/common-functions.sh b/t/t5411/common-functions.sh
index 344d13f61a..13107fcdb6 100644
--- a/t/t5411/common-functions.sh
+++ b/t/t5411/common-functions.sh
@@ -36,9 +36,8 @@ create_commits_in () {
 # without having to worry about future changes of the commit ID and spaces
 # of the output.  Single quotes are replaced with double quotes, because
 # it is boring to prepare unquoted single quotes in expect text.  We also
-# remove some locale error messages, which break test if we turn on
-# `GIT_TEST_GETTEXT_POISON=true` in order to test unintentional translations
-# on plumbing commands.
+# remove some locale error messages. The emitted human-readable errors are
+# redundant to the more machine-readable output the tests already assert.
 make_user_friendly_and_stable_output () {
 	sed \
 		-e "s/  *\$//" \
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index b36a93056f..d10076efd7 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -245,7 +245,7 @@ test_expect_success 'checkout to detach HEAD' '
 	rev=$(git rev-parse --short renamer^) &&
 	git checkout -f renamer &&
 	git clean -f &&
-	GIT_TEST_GETTEXT_POISON=false git checkout renamer^ 2>messages &&
+	git checkout renamer^ 2>messages &&
 	grep "HEAD is now at $rev" messages &&
 	test_line_count -gt 1 messages &&
 	H=$(git rev-parse --verify HEAD) &&
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index a1c4f1f6d4..e5adee27d4 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2363,7 +2363,6 @@ test_expect_success 'sourcing the completion script clears cached commands' '
 '
 
 test_expect_success 'sourcing the completion script clears cached merge strategies' '
-	GIT_TEST_GETTEXT_POISON=false &&
 	__git_compute_merge_strategies &&
 	verbose test -n "$__git_merge_strategies" &&
 	. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false?
  2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
                                             ` (9 preceding siblings ...)
  2021-01-11 14:47                           ` [PATCH 6/6] tests: remove uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
@ 2021-01-11 21:05                           ` Junio C Hamano
  2021-01-12 11:22                             ` Jeff King
  10 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2021-01-11 21:05 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: SZEDER Gábor, git, Jeff King, brian m . carlson,
	Eric Sunshine, Johannes Schindelin

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> What do you think about just removing it? I.e. make setting it a noop?

I have been seeing occasional CI job failures from new tests that
forget to use test_i18ngrep.  I actually think marking such a grep
as "this is looking for a string that is meant for humans" a good
way to document the interface and expected end-user interaction,
so I am not sure about just removing it.

So after all, test_i18ngrep may make more sense than setting
GIT_TEST_GETTEXT_POISON to false.  I dunno.

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

* Re: [PATCH 0/2] Makefile & gettext.c: remove warning & long comment
  2021-01-11 13:14                           ` [PATCH 0/2] Makefile & gettext.c: remove warning & long comment Ævar Arnfjörð Bjarmason
@ 2021-01-11 21:06                             ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-01-11 21:06 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> We've got a huge comment in gettext.c that nobody cares about anymore,
> remove it, and an old warning in the Makefile while I'm at it.
>
> This doesn't conflict with any other patches I'm about to submit, I
> wanted to submit it separately because these are small isolated
> non-contentious changes.

Both look sensible.

Thanks, will queue.

> Ævar Arnfjörð Bjarmason (2):
>   Makefile: remove a warning about old GETTEXT_POISON flag
>   gettext.c: remove/reword a mostly-useless comment
>
>  Makefile  |  3 --
>  gettext.c | 94 +++++++++----------------------------------------------
>  2 files changed, 15 insertions(+), 82 deletions(-)

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

* Re: [PATCH 2/6] tests: remove support for GIT_TEST_GETTEXT_POISON
  2021-01-11 14:47                           ` [PATCH 2/6] tests: remove support for GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
@ 2021-01-11 21:54                             ` Junio C Hamano
  2021-03-24 23:36                             ` [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
  1 sibling, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-01-11 21:54 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> diff --git a/po/README b/po/README
> index 07595d369b..b9b6c9cb24 100644
> --- a/po/README
> +++ b/po/README
> @@ -284,23 +284,27 @@ Perl:
>  Testing marked strings
>  ----------------------
>  
> +Git's tests are run under LANG=C LC_ALL=C. So the tests do not need be
> +changed to account for translations as they're added.

After we told readers this ...

> +Testing whether marked strings are used by plumbing
> ...
> +It's still possible to do a one-off test of where a string might be
> +used in the tests by simply replacing the "some hardcoded string" with
> +something like "POISON ME" locally and running the tests, before
> +finally converting it to _("some hardcoded string").

... I do not see how this manual check can still be effective.

People rely on our tests running under C locale, and will add tests
to grep for error messages meant for humans in C locale.  What does
it help to notice that a particular string you are contemplating to
translate _is_ being looked for in an existing test?  The author of
such a test knew it was meant for humans, but trusted our promise to
run tests in the C locale and used grep for it, in which case it is
a fair game to be marked with _().

I think we should honestly admit that after this change it is no
longer possible for our tests to help catching strings that are
mistakenly marked for translation when they are meant for machine
consumption, and justify why it is still OK to apply this change.

> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> index 999982fe4a..c7b1d857c4 100644
> --- a/t/test-lib-functions.sh
> +++ b/t/test-lib-functions.sh

The changes to this file all look very attractive ;-)  Not having to
worry about poison test certainly makes it easier to write tests.

I just do not know if the price we are paying for the easier life is
too high.

Thanks.

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

* Re: [PATCH 1/6] ci: remove GETTEXT_POISON jobs
  2021-01-11 14:47                           ` [PATCH 1/6] ci: remove GETTEXT_POISON jobs Ævar Arnfjörð Bjarmason
@ 2021-01-12  8:50                             ` SZEDER Gábor
  2021-01-20 17:59                               ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: SZEDER Gábor @ 2021-01-12  8:50 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin

On Mon, Jan 11, 2021 at 03:47:35PM +0100, Ævar Arnfjörð Bjarmason wrote:
> A subsequent commit will remove GETTEXT_POISON entirely, let's start
> by removing the CI jobs that enable the option.
> 
> We cannot just remove the job because the CI is implicitly depending
> on the "poison" job being a sort of "default" job.

I don't understand what you mean here with a "default job" that the CI
is implicitly depending on.  There is certainly no such default job on
Travis CI, and I don't think there is one on the GitHub thing.

> Let's instead add a
> "default" job.
> 
> This means we can remove the initial "make test" from the "linux-gcc"
> job (it does another one after setting a bunch of GIT_TEST_*
> variables).
> 
> I'm not doing that because it would conflict with the in-flight
> 334afbc76fb (tests: mark tests relying on the current default for
> `init.defaultBranch`, 2020-11-18) (currently on the "seen" branch, so
> the SHA-1 will almost definitely change). It's going to use that "make
> test" again for different reasons, so let's preserve it for now.
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  .github/workflows/main.yml | 2 +-
>  .travis.yml                | 2 +-
>  ci/install-dependencies.sh | 2 +-
>  ci/lib.sh                  | 3 +--
>  4 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
> index aef6643648..8b52df200f 100644
> --- a/.github/workflows/main.yml
> +++ b/.github/workflows/main.yml
> @@ -286,7 +286,7 @@ jobs:
>            - jobname: osx-gcc
>              cc: gcc
>              pool: macos-latest
> -          - jobname: GETTEXT_POISON
> +          - jobname: linux-gcc-default
>              cc: gcc
>              pool: ubuntu-latest
>      env:
> diff --git a/.travis.yml b/.travis.yml
> index 05f3e3f8d7..908330a0a3 100644
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -16,7 +16,7 @@ compiler:
>  
>  matrix:
>    include:
> -    - env: jobname=GETTEXT_POISON
> +    - env: jobname=linux-gcc-default
>        os: linux
>        compiler:
>        addons:
> diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
> index 0229a77f7d..79c0633a18 100755
> --- a/ci/install-dependencies.sh
> +++ b/ci/install-dependencies.sh
> @@ -72,7 +72,7 @@ Documentation)
>  	test -n "$ALREADY_HAVE_ASCIIDOCTOR" ||
>  	sudo gem install --version 1.5.8 asciidoctor
>  	;;
> -linux-gcc-4.8|GETTEXT_POISON)
> +linux-gcc-default|linux-gcc-4.8)
>  	sudo apt-get -q update
>  	sudo apt-get -q -y install $UBUNTU_COMMON_PKGS
>  	;;
> diff --git a/ci/lib.sh b/ci/lib.sh
> index 38c0eac351..d848c036c5 100755
> --- a/ci/lib.sh
> +++ b/ci/lib.sh
> @@ -220,8 +220,7 @@ osx-clang|osx-gcc)
>  	# Travis CI OS X
>  	export GIT_SKIP_TESTS="t9810 t9816"
>  	;;
> -GETTEXT_POISON)
> -	export GIT_TEST_GETTEXT_POISON=true
> +linux-gcc-default)
>  	;;
>  Linux32)
>  	CC=gcc
> -- 
> 2.29.2.222.g5d2a92d10f8
> 

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

* Re: Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false?
  2021-01-11 21:05                           ` Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false? Junio C Hamano
@ 2021-01-12 11:22                             ` Jeff King
  0 siblings, 0 replies; 229+ messages in thread
From: Jeff King @ 2021-01-12 11:22 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Ævar Arnfjörð Bjarmason, SZEDER Gábor, git,
	brian m . carlson, Eric Sunshine, Johannes Schindelin

On Mon, Jan 11, 2021 at 01:05:37PM -0800, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> 
> > What do you think about just removing it? I.e. make setting it a noop?
> 
> I have been seeing occasional CI job failures from new tests that
> forget to use test_i18ngrep.  I actually think marking such a grep
> as "this is looking for a string that is meant for humans" a good
> way to document the interface and expected end-user interaction,
> so I am not sure about just removing it.
> 
> So after all, test_i18ngrep may make more sense than setting
> GIT_TEST_GETTEXT_POISON to false.  I dunno.

I agree that test_i18ngrep is preferable to setting
GIT_TEST_GETTEXT_POISON. Since it's tied to the comparison itself, I
think it's easier to see which messages we're expecting as
human-readable. It's also shorter and more readable IMHO (you'd already
be calling grep or test_cmp, so it is only a little longer).

I am on the fence on whether the presence of something like
test_i18ngrep in the test suite is really serving as a useful indication
of what was meant to be translated and what wasn't. It's such an
incomplete coverage of the total set of messages we generate that I
wouldn't trust it. I'd be more likely to look at the source to see if a
message is actually translated, or just assume we follow some basic
rules (in general, things to stderr are translatable; I think the
plumbing outputs from unpack_trees() were really the exception).

So I'm open to the idea that the whole poison mechanism has just
outlived its usefulness.

-Peff

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

* Re: Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false?
  2021-01-10 18:59                     ` Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false? Ævar Arnfjörð Bjarmason
  2021-01-10 20:12                       ` Junio C Hamano
@ 2021-01-20 15:21                       ` SZEDER Gábor
  1 sibling, 0 replies; 229+ messages in thread
From: SZEDER Gábor @ 2021-01-20 15:21 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Jeff King, brian m . carlson, Eric Sunshine,
	Johannes Schindelin

On Sun, Jan 10, 2021 at 07:59:50PM +0100, Ævar Arnfjörð Bjarmason wrote:
> 
> On Sun, Jan 10 2021, SZEDER Gábor wrote:
> 
> > On Tue, Jan 05, 2021 at 08:42:41PM +0100, Ævar Arnfjörð Bjarmason wrote:
> >> We need to provide GIT_TEST_GETTEXT_POISON=false here because the
> >> "invalid object type" error is emitted by
> >> parse_loose_header_extended(), which has that message already marked
> >> for translation. Another option would be to use test_i18ngrep, but I
> >> prefer always running the test, not skipping it under gettext poison
> >> testing.
> >
> > This is fairly unconvincing.  Why do you prefer it that way?  What is
> > so special in these tests of 'git mktags' that could possibly warrant
> > this special treatment WRT gettext poisoning, as opposed to the other
> > ~1500 invocations of test_i18n{grep,cmp}?
> 
> You prodded me about this and Johannes also did off-list. So given that
> this is already in "next" I think it's best to let usage in this mktag
> series land as-is.
> 
> I promise I'll follow-up with something to (at least start to) fix this
> generally one way or the other on "master" after that. It's a trivial
> part of this particular series.
> 
> I.e. either document & migrate away from test_i18ngrep (mostly, in some
> cases it's still convenient), or git rid of this and the few existing
> GIT_TEST_GETTEXT_POISON=false uses.
> 
> Anyway, as both the initial author of this poison facility & of its
> current runtime incarnation in git.git, some context on it:
> 
> The need for test_i18ngrep was always a wart. When I submitted the
> initial i18n patches a big selling point at the time to a (rightly so)
> skeptical audience on the Git ML was that it could almost entirely be
> turned off at compile-time, and that we had something in place to make
> sure we didn't introduce plumbing bugs by overtranslating.
> 
> For a while the mass-i18n patches were about as noisy on-list as the
> sha256 conversion patches were in more recenty memory.
> 
> So if you look through the history you'll see that first we skipped
> whole tests with the C_LOCALE_OUTPUT prereq, and then test_i18ngrep was
> a more granular way to do that:
> 
>     git some-command >output && 
>     test_i18ngrep "c locale string" output
> 
> But since 6cdccfce1e0 (i18n: make GETTEXT_POISON a runtime option,
> 2018-11-08) this hasn't been needed. But yes, we have a bit under 10
> years of test_i18ngrep usage in the test suite now.
> 
> But that stuff is the wart, and purely a historical artifact of this
> having once been compile-time only. We don't do this sort of thing with
> any other GIT_TEST_* option, e.g. we have tests like:
> 
>     t/t5512-ls-remote.sh:   GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
>     t/t5512-ls-remote.sh-   test_cmp expect actual &&
> 
> Not:
> 
>     t/t5512-ls-remote.sh:   git ls-remote --symref --heads . >actual &&
>     t/t5512-ls-remote.sh-   test_protocolv0cmp expect actual &&
> 
> Because that doesn't make sense. If we know we're testing protocol v0
> here why wouldn't we just pass that as a parameter in the test? Same for
> GIT_TEST_GETTEXT_POISON=false.

I think it's the comparison of GIT_TEST_GETTEXT_POISON and
GIT_TEST_PROTOCOL_VERSION that doesn't make sense in the first place.

For the sake of users who might be stuck on Git version not yet
understanding protocol v2 or have to connect to a v0-only remote, we
must make sure that both v0 and v2 protocols work, so a simple
'make test' must exercise both.  Since protocol v2 is the default
nowadays, we need a way to tell some tests to use v0 instead, and
setting GIT_TEST_PROTOCOL_VERSION=0 ended up our standard way to do
that.  Besides, the uses of GIT_TEST_PROTOCOL_VERSION is quite
contained, as it is set in only 34 times in 13 test scripts.

GETTEXT_POISON is purely a developer aid (of questionable usefulness
as you explained above), no end user would ever see it, and yet the
test_i18n* functions are used ~1500 times in 250+ test scripts.  I
sure dont't want to see 1500+ uses of 'GIT_TEST_GETTEXT_POISON=false
git cmd...'.  Besides, what would be the purpose of
'GIT_TEST_GETTEXT_POSION=true make test' if it would eventually be
overriden all over the place?

> I have also wondered if a better approach at this point isn't to just
> remove the thing entirely. We're just doing incremental i18n-ization at
> this point, so the odds that it's catching accidental plumbing
> translations is rather low compared to 2011-era git.git.

I wouldn't mind seeing it go...  well, I think I would welcome it,
actually :)  I can only recall cases where a failure of the
GETTEXT_POISON CI job was resolved by another replacement of 'grep'
with 'test_i18ngrep', but I don't seem to remember a case where we
decided that "Nah, this message should not have been translated in the
first place".

I would, however, really miss the error reporting of 'test_i18ngrep',
though, i.e. that it shows the contents of the file when it doesn't
find a match.


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

* Re: [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility
  2021-01-11 14:47                           ` [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility Ævar Arnfjörð Bjarmason
@ 2021-01-20 15:33                             ` SZEDER Gábor
  2021-01-20 18:13                               ` Ævar Arnfjörð Bjarmason
  2021-01-20 18:27                             ` [PATCH v2 0/3] " Ævar Arnfjörð Bjarmason
                                               ` (3 subsequent siblings)
  4 siblings, 1 reply; 229+ messages in thread
From: SZEDER Gábor @ 2021-01-20 15:33 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin

On Mon, Jan 11, 2021 at 03:47:34PM +0100, Ævar Arnfjörð Bjarmason wrote:
> As argued upthread and in 2/6 this test setup has outrun its
> usefulness.
> 
> This series begins to remove it in a way that's very careful about not
> stepping on the toes of any other in-flight patches. In particular
> "master" isn't anywhere in the diff context here to avoid conflicts
> with the series to do that mass-replacement in t/. 
> 
> This series merges and tests cleanly in combination with the current
> "seen" branch.
> 
> At the end we're left with a bunch of tests still using
> test_i18n{cmp,grep}, but I think that's preferable to having in-flight
> conflicts. It'll be trivial to search-replace those at some point in
> the future where we don't have another search-replacement series
> amending t/ in-flight.
> 
> Ævar Arnfjörð Bjarmason (6):
>   ci: remove GETTEXT_POISON jobs
>   tests: remove support for GIT_TEST_GETTEXT_POISON
>   tests: remove misc use of test_i18n{cmp,grep}
>   tests: (almost) remove use of "test_i18ngrep !"
>   tests: (almost) remove C_LOCALE_OUTPUT prerequisites
>   tests: remove uses of GIT_TEST_GETTEXT_POISON=false

At the end of this patch series there are still a couple of remnants
left:

  - t3406: has a comment about gettext poisoning.

  - Makefile still has a warning about for the GETTEXT_POISON build
    knob referring to GIT_TEST_GETTEXT_POISON and t/README.

I think both can be simply removed.

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

* Re: [PATCH 1/6] ci: remove GETTEXT_POISON jobs
  2021-01-12  8:50                             ` SZEDER Gábor
@ 2021-01-20 17:59                               ` Ævar Arnfjörð Bjarmason
  2021-01-20 19:14                                 ` SZEDER Gábor
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-20 17:59 UTC (permalink / raw)
  To: SZEDER Gábor
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin


On Tue, Jan 12 2021, SZEDER Gábor wrote:

> On Mon, Jan 11, 2021 at 03:47:35PM +0100, Ævar Arnfjörð Bjarmason wrote:
>> A subsequent commit will remove GETTEXT_POISON entirely, let's start
>> by removing the CI jobs that enable the option.
>> 
>> We cannot just remove the job because the CI is implicitly depending
>> on the "poison" job being a sort of "default" job.
>
> I don't understand what you mean here with a "default job" that the CI
> is implicitly depending on.  There is certainly no such default job on
> Travis CI, and I don't think there is one on the GitHub thing.

I'll reword this. I meant that the poison job was using the default
compiler etc., whereas the other ones were setting custom values.

I vaguely remember some list traffic about this in the past, i.e. the
reliance on the poison job not just for that, but also as "the default
OS image" setup.


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

* Re: [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility
  2021-01-20 15:33                             ` SZEDER Gábor
@ 2021-01-20 18:13                               ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-20 18:13 UTC (permalink / raw)
  To: SZEDER Gábor
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin


On Wed, Jan 20 2021, SZEDER Gábor wrote:

> On Mon, Jan 11, 2021 at 03:47:34PM +0100, Ævar Arnfjörð Bjarmason wrote:
>> As argued upthread and in 2/6 this test setup has outrun its
>> usefulness.
>> 
>> This series begins to remove it in a way that's very careful about not
>> stepping on the toes of any other in-flight patches. In particular
>> "master" isn't anywhere in the diff context here to avoid conflicts
>> with the series to do that mass-replacement in t/. 
>> 
>> This series merges and tests cleanly in combination with the current
>> "seen" branch.
>> 
>> At the end we're left with a bunch of tests still using
>> test_i18n{cmp,grep}, but I think that's preferable to having in-flight
>> conflicts. It'll be trivial to search-replace those at some point in
>> the future where we don't have another search-replacement series
>> amending t/ in-flight.
>> 
>> Ævar Arnfjörð Bjarmason (6):
>>   ci: remove GETTEXT_POISON jobs
>>   tests: remove support for GIT_TEST_GETTEXT_POISON
>>   tests: remove misc use of test_i18n{cmp,grep}
>>   tests: (almost) remove use of "test_i18ngrep !"
>>   tests: (almost) remove C_LOCALE_OUTPUT prerequisites
>>   tests: remove uses of GIT_TEST_GETTEXT_POISON=false
>
> At the end of this patch series there are still a couple of remnants
> left:
>
>   - t3406: has a comment about gettext poisoning.
>
>   - Makefile still has a warning about for the GETTEXT_POISON build
>     knob referring to GIT_TEST_GETTEXT_POISON and t/README.
>
> I think both can be simply removed.

The Makefile comment was in the 20210111131451.7084-1-avarab@gmail.com
sibling series, but I'll fix the other one in this one. Thanks!

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

* [PATCH v2 0/3] Remove GIT_TEST_GETTEXT_POISON facility
  2021-01-11 14:47                           ` [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility Ævar Arnfjörð Bjarmason
  2021-01-20 15:33                             ` SZEDER Gábor
@ 2021-01-20 18:27                             ` Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 0/4] More GETTEXT_POISON removal Ævar Arnfjörð Bjarmason
                                                 ` (4 more replies)
  2021-01-20 18:27                             ` [PATCH v2 1/3] ci: remove GETTEXT_POISON jobs Ævar Arnfjörð Bjarmason
                                               ` (2 subsequent siblings)
  4 siblings, 5 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-20 18:27 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

A slimmed-down and much easier to read version of v1 which addresses
the feedback on v1.

I'm not removing any test_i18ngrep etc. uses here in this series,
because SZEDER indicated in <20210120152132.GC8396@szeder.dev> that he
likes the test_i18ngrep error reporting. This leaves the door open to
him submitting some related series to add a
s/test_i18ngrep/test_grep/g helper or whatever.

As before I'll leave whether we *should* do this to list consensus. My
reading of it is that Junio/Jeff/SZEDER are leaning more towards this
approach, and Johannes more towards the rot13 alternate.

I certainly don't want to stomp on Johannes's toes with implementing
the rot13 alternative, and if this series were accepted that facilty
would need to start by mostly reverting this, so if the consensus is
leaning towards that approach this series should be dropped. Johannes
doesn't have time to work on that right now, but there's no rush here
either way.

But if it's leaning more towards "meh, let's just nuke it" we can
apply this.

Ævar Arnfjörð Bjarmason (3):
  ci: remove GETTEXT_POISON jobs
  tests: remove support for GIT_TEST_GETTEXT_POISON
  tests: remove uses of GIT_TEST_GETTEXT_POISON=false

 .github/workflows/main.yml            |  2 +-
 .travis.yml                           |  2 +-
 Documentation/MyFirstContribution.txt |  2 +-
 ci/install-dependencies.sh            |  2 +-
 ci/lib.sh                             |  3 +--
 config.c                              |  9 -------
 gettext.c                             | 10 -------
 gettext.h                             |  7 +----
 git-sh-i18n.sh                        | 22 +--------------
 po/README                             | 22 ++-------------
 t/README                              |  6 -----
 t/lib-gettext.sh                      |  2 +-
 t/lib-rebase.sh                       |  1 -
 t/t0017-env-helper.sh                 |  8 +++---
 t/t0205-gettext-poison.sh             | 39 ---------------------------
 t/t1305-config-include.sh             |  4 +--
 t/t3406-rebase-message.sh             |  7 -----
 t/t5411/common-functions.sh           |  5 ++--
 t/t7201-co.sh                         |  2 +-
 t/t9902-completion.sh                 |  1 -
 t/test-lib-functions.sh               | 23 +++++-----------
 t/test-lib.sh                         | 23 +++-------------
 22 files changed, 29 insertions(+), 173 deletions(-)
 delete mode 100755 t/t0205-gettext-poison.sh

Range-diff:
1:  00c5326694 ! 1:  164296c7d6 ci: remove GETTEXT_POISON jobs
    @@ Commit message
         by removing the CI jobs that enable the option.
     
         We cannot just remove the job because the CI is implicitly depending
    -    on the "poison" job being a sort of "default" job. Let's instead add a
    -    "default" job.
    +    on the "poison" job being a sort of "default" job in the sense that
    +    it's the job that was otherwise run with the default compiler, no
    +    other GIT_TEST_* options etc. So let's keep it under the name
    +    "linux-gcc-default".
     
         This means we can remove the initial "make test" from the "linux-gcc"
         job (it does another one after setting a bunch of GIT_TEST_*
2:  ac0f3a78d7 ! 2:  5c6299cde8 tests: remove support for GIT_TEST_GETTEXT_POISON
    @@ Commit message
         we still have a lot of test_i18n, C_LOCALE_OUTPUT
         etc. uses. Subsequent commits will remove those too.
     
    +    The change to t/lib-rebase.sh is a selective revert of the relevant
    +    part of f2d17068fd (i18n: rebase-interactive: mark comments of squash
    +    for translation, 2016-06-17), and the comment in
    +    t/t3406-rebase-message.sh is from c7108bf9ed (i18n: rebase: mark
    +    messages for translation, 2012-07-25).
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Documentation/MyFirstContribution.txt ##
    @@ po/README: Perl:
     -something in the test suite might still depend on the US English
     -version of the strings, e.g. to grep some error message or other
     -output.
    -+Git's tests are run under LANG=C LC_ALL=C. So the tests do not need be
    -+changed to account for translations as they're added.
    - 
    +-
     -To smoke out issues like these, Git tested with a translation mode that
     -emits gibberish on every call to gettext. To use it run the test suite
     -with it, e.g.:
    -+Testing whether marked strings are used by plumbing
    -+---------------------------------------------------
    - 
    +-
     -    cd t && GIT_TEST_GETTEXT_POISON=true prove -j 9 ./t[0-9]*.sh
    -+It may be useful to use the test suite to smoke out any strings that
    -+shouldn't be translated, because they are used by plumbing or
    -+otherwise part of machine-readable output.
    - 
    +-
     -If tests break with it you should inspect them manually and see if
     -what you're translating is sane, i.e. that you're not translating
    -+This is most useful in cases where e.g. library function might return
    -+a string like _("tree"), and the developer marking strings for
    -+translation wishes to check that they're not inadvertently translating
    - plumbing output.
    - 
    +-plumbing output.
    +-
     -If not you should replace calls to grep with test_i18ngrep, or
     -test_cmp calls with test_i18ncmp. If that's not enough you can skip
     -the whole test by making it depend on the C_LOCALE_OUTPUT
     -prerequisite. See existing test files with this prerequisite for
     -examples.
    -+There used to be a GIT_TEST_GETTEXT_POISON=true test mode to replace
    -+translated strings with gibberish to facilitate this. Maintaining it
    -+and annotating tests appropriately was considered too high of a burden
    -+for its usefulness.
    -+
    -+It's still possible to do a one-off test of where a string might be
    -+used in the tests by simply replacing the "some hardcoded string" with
    -+something like "POISON ME" locally and running the tests, before
    -+finally converting it to _("some hardcoded string").
    ++Git's tests are run under LANG=C LC_ALL=C. So the tests do not need be
    ++changed to account for translations as they're added.
     
      ## t/README ##
     @@ t/README: whether this mode is active, and e.g. skip some tests that are hard to
    @@ t/lib-gettext.sh: else
      	# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
      	is_IS_locale=$(locale -a 2>/dev/null |
     
    + ## t/lib-rebase.sh ##
    +@@ t/lib-rebase.sh: set_fake_editor () {
    + 	*/COMMIT_EDITMSG)
    + 		test -z "$EXPECT_HEADER_COUNT" ||
    + 			test "$EXPECT_HEADER_COUNT" = "$(sed -n '1s/^# This is a combination of \(.*\) commits\./\1/p' < "$1")" ||
    +-			test "# # GETTEXT POISON #" = "$(sed -n '1p' < "$1")" ||
    + 			exit
    + 		test -z "$FAKE_COMMIT_MESSAGE" || echo "$FAKE_COMMIT_MESSAGE" > "$1"
    + 		test -z "$FAKE_COMMIT_AMEND" || echo "$FAKE_COMMIT_AMEND" >> "$1"
    +
      ## t/t0017-env-helper.sh ##
     @@ t/t0017-env-helper.sh: test_expect_success 'env--helper reads config thanks to trace2' '
      	git config -f home/cycle include.path .gitconfig &&
    @@ t/t0205-gettext-poison.sh (deleted)
     -
     -test_done
     
    + ## t/t3406-rebase-message.sh ##
    +@@ t/t3406-rebase-message.sh: test_expect_success 'rebase -n overrides config rebase.stat config' '
    + 	! grep "^ fileX |  *1 +$" diffstat.txt
    + '
    + 
    +-# Output to stderr:
    +-#
    +-#     "Does not point to a valid commit: invalid-ref"
    +-#
    +-# NEEDSWORK: This "grep" is fine in real non-C locales, but
    +-# GIT_TEST_GETTEXT_POISON poisons the refname along with the enclosing
    +-# error message.
    + test_expect_success 'rebase --onto outputs the invalid ref' '
    + 	test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
    + 	test_i18ngrep "invalid-ref" err
    +
      ## t/test-lib-functions.sh ##
     @@ t/test-lib-functions.sh: test_cmp_bin () {
      	cmp "$@"
3:  8bdf8d9513 < -:  ---------- tests: remove misc use of test_i18n{cmp,grep}
4:  ead017acc8 < -:  ---------- tests: (almost) remove use of "test_i18ngrep !"
5:  b1113122d0 < -:  ---------- tests: (almost) remove C_LOCALE_OUTPUT prerequisites
6:  9226c3a2df = 3:  7f982be41d tests: remove uses of GIT_TEST_GETTEXT_POISON=false
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 1/3] ci: remove GETTEXT_POISON jobs
  2021-01-11 14:47                           ` [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility Ævar Arnfjörð Bjarmason
  2021-01-20 15:33                             ` SZEDER Gábor
  2021-01-20 18:27                             ` [PATCH v2 0/3] " Ævar Arnfjörð Bjarmason
@ 2021-01-20 18:27                             ` Ævar Arnfjörð Bjarmason
  2021-01-20 18:27                             ` [PATCH v2 2/3] tests: remove support for GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
  2021-01-20 18:27                             ` [PATCH v2 3/3] tests: remove uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
  4 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-20 18:27 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

A subsequent commit will remove GETTEXT_POISON entirely, let's start
by removing the CI jobs that enable the option.

We cannot just remove the job because the CI is implicitly depending
on the "poison" job being a sort of "default" job in the sense that
it's the job that was otherwise run with the default compiler, no
other GIT_TEST_* options etc. So let's keep it under the name
"linux-gcc-default".

This means we can remove the initial "make test" from the "linux-gcc"
job (it does another one after setting a bunch of GIT_TEST_*
variables).

I'm not doing that because it would conflict with the in-flight
334afbc76fb (tests: mark tests relying on the current default for
`init.defaultBranch`, 2020-11-18) (currently on the "seen" branch, so
the SHA-1 will almost definitely change). It's going to use that "make
test" again for different reasons, so let's preserve it for now.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 .github/workflows/main.yml | 2 +-
 .travis.yml                | 2 +-
 ci/install-dependencies.sh | 2 +-
 ci/lib.sh                  | 3 +--
 4 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index aef6643648..8b52df200f 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -286,7 +286,7 @@ jobs:
           - jobname: osx-gcc
             cc: gcc
             pool: macos-latest
-          - jobname: GETTEXT_POISON
+          - jobname: linux-gcc-default
             cc: gcc
             pool: ubuntu-latest
     env:
diff --git a/.travis.yml b/.travis.yml
index 05f3e3f8d7..908330a0a3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,7 @@ compiler:
 
 matrix:
   include:
-    - env: jobname=GETTEXT_POISON
+    - env: jobname=linux-gcc-default
       os: linux
       compiler:
       addons:
diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
index 0b1184e04a..67852d0d37 100755
--- a/ci/install-dependencies.sh
+++ b/ci/install-dependencies.sh
@@ -72,7 +72,7 @@ Documentation)
 	test -n "$ALREADY_HAVE_ASCIIDOCTOR" ||
 	sudo gem install --version 1.5.8 asciidoctor
 	;;
-linux-gcc-4.8|GETTEXT_POISON)
+linux-gcc-default|linux-gcc-4.8)
 	sudo apt-get -q update
 	sudo apt-get -q -y install $UBUNTU_COMMON_PKGS
 	;;
diff --git a/ci/lib.sh b/ci/lib.sh
index 38c0eac351..d848c036c5 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -220,8 +220,7 @@ osx-clang|osx-gcc)
 	# Travis CI OS X
 	export GIT_SKIP_TESTS="t9810 t9816"
 	;;
-GETTEXT_POISON)
-	export GIT_TEST_GETTEXT_POISON=true
+linux-gcc-default)
 	;;
 Linux32)
 	CC=gcc
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 2/3] tests: remove support for GIT_TEST_GETTEXT_POISON
  2021-01-11 14:47                           ` [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility Ævar Arnfjörð Bjarmason
                                               ` (2 preceding siblings ...)
  2021-01-20 18:27                             ` [PATCH v2 1/3] ci: remove GETTEXT_POISON jobs Ævar Arnfjörð Bjarmason
@ 2021-01-20 18:27                             ` Ævar Arnfjörð Bjarmason
  2021-01-20 18:27                             ` [PATCH v2 3/3] tests: remove uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
  4 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-20 18:27 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

This removes the ability to inject "poison" gettext() messages via the
GIT_TEST_GETTEXT_POISON special test setup.

I initially added this as a compile-time option in bb946bba761 (i18n:
add GETTEXT_POISON to simulate unfriendly translator, 2011-02-22), and
most recently modified to be toggleable at runtime in
6cdccfce1e0 (i18n: make GETTEXT_POISON a runtime option, 2018-11-08)..

The reason for its removal is that the trade-off of maintaining it
v.s. what it's getting us has long since flipped. When gettext was
integrated in 5e9637c6297 (i18n: add infrastructure for translating
Git with gettext, 2011-11-18) there was understandable concern on the
Git ML that in marking messages for translation en-masse we'd
inadvertently mark plumbing messages. The GETTEXT_POISON facility was
a way to smoke those out via our test suite.

Nowadays however we're done (or almost entirely done) with any marking
of messages for translation. New messages are usually marked by their
authors, who'll know whether it makes sense to translate them or
not. If not any errors in marking the messages are much more likely to
be spotted in review than in the the initial deluge of i18n patches in
the 2011-2012 era.

So let's just remove this. This leaves the test suite in a state where
we still have a lot of test_i18n, C_LOCALE_OUTPUT
etc. uses. Subsequent commits will remove those too.

The change to t/lib-rebase.sh is a selective revert of the relevant
part of f2d17068fd (i18n: rebase-interactive: mark comments of squash
for translation, 2016-06-17), and the comment in
t/t3406-rebase-message.sh is from c7108bf9ed (i18n: rebase: mark
messages for translation, 2012-07-25).

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/MyFirstContribution.txt |  2 +-
 config.c                              |  9 -------
 gettext.c                             | 10 -------
 gettext.h                             |  7 +----
 git-sh-i18n.sh                        | 22 +--------------
 po/README                             | 22 ++-------------
 t/README                              |  6 -----
 t/lib-gettext.sh                      |  2 +-
 t/lib-rebase.sh                       |  1 -
 t/t0017-env-helper.sh                 |  8 +++---
 t/t0205-gettext-poison.sh             | 39 ---------------------------
 t/t3406-rebase-message.sh             |  7 -----
 t/test-lib-functions.sh               | 23 +++++-----------
 t/test-lib.sh                         | 23 +++-------------
 14 files changed, 21 insertions(+), 160 deletions(-)
 delete mode 100755 t/t0205-gettext-poison.sh

diff --git a/Documentation/MyFirstContribution.txt b/Documentation/MyFirstContribution.txt
index 7c9a037cc2..af0a9da62e 100644
--- a/Documentation/MyFirstContribution.txt
+++ b/Documentation/MyFirstContribution.txt
@@ -664,7 +664,7 @@ mention the right animal somewhere:
 ----
 test_expect_success 'runs correctly with no args and good output' '
 	git psuh >actual &&
-	test_i18ngrep Pony actual
+	grep Pony actual
 '
 ----
 
diff --git a/config.c b/config.c
index 4c0cf3a1c1..3d34c0fd76 100644
--- a/config.c
+++ b/config.c
@@ -996,15 +996,6 @@ static void die_bad_number(const char *name, const char *value)
 	if (!value)
 		value = "";
 
-	if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
-		/*
-		 * We explicitly *don't* use _() here since it would
-		 * cause an infinite loop with _() needing to call
-		 * use_gettext_poison(). This is why marked up
-		 * translations with N_() above.
-		 */
-		die(bad_numeric, value, name, error_type);
-
 	if (!(cf && cf->name))
 		die(_(bad_numeric), value, name, _(error_type));
 
diff --git a/gettext.c b/gettext.c
index 1b564216d0..af2413b47e 100644
--- a/gettext.c
+++ b/gettext.c
@@ -65,14 +65,6 @@ const char *get_preferred_languages(void)
 	return NULL;
 }
 
-int use_gettext_poison(void)
-{
-	static int poison_requested = -1;
-	if (poison_requested == -1)
-		poison_requested = git_env_bool("GIT_TEST_GETTEXT_POISON", 0);
-	return poison_requested;
-}
-
 #ifndef NO_GETTEXT
 static int test_vsnprintf(const char *fmt, ...)
 {
@@ -117,8 +109,6 @@ void git_setup_gettext(void)
 	if (!podir)
 		podir = p = system_path(GIT_LOCALE_PATH);
 
-	use_gettext_poison(); /* getenv() reentrancy paranoia */
-
 	if (!is_directory(podir)) {
 		free(p);
 		return;
diff --git a/gettext.h b/gettext.h
index bee52eb113..c8b34fd612 100644
--- a/gettext.h
+++ b/gettext.h
@@ -28,15 +28,12 @@
 
 #define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))
 
-int use_gettext_poison(void);
-
 #ifndef NO_GETTEXT
 void git_setup_gettext(void);
 int gettext_width(const char *s);
 #else
 static inline void git_setup_gettext(void)
 {
-	use_gettext_poison(); /* getenv() reentrancy paranoia */
 }
 static inline int gettext_width(const char *s)
 {
@@ -48,14 +45,12 @@ static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
 {
 	if (!*msgid)
 		return "";
-	return use_gettext_poison() ? "# GETTEXT POISON #" : gettext(msgid);
+	return gettext(msgid);
 }
 
 static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2)
 const char *Q_(const char *msgid, const char *plu, unsigned long n)
 {
-	if (use_gettext_poison())
-		return "# GETTEXT POISON #";
 	return ngettext(msgid, plu, n);
 }
 
diff --git a/git-sh-i18n.sh b/git-sh-i18n.sh
index 8eef60b43f..e3d9f4836d 100644
--- a/git-sh-i18n.sh
+++ b/git-sh-i18n.sh
@@ -17,12 +17,7 @@ export TEXTDOMAINDIR
 
 # First decide what scheme to use...
 GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
-if test -n "$GIT_TEST_GETTEXT_POISON" &&
-	    git env--helper --type=bool --default=0 --exit-code \
-		GIT_TEST_GETTEXT_POISON
-then
-	GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
-elif test -n "@@USE_GETTEXT_SCHEME@@"
+if test -n "@@USE_GETTEXT_SCHEME@@"
 then
 	GIT_INTERNAL_GETTEXT_SH_SCHEME="@@USE_GETTEXT_SCHEME@@"
 elif test -n "$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS"
@@ -63,21 +58,6 @@ gettext_without_eval_gettext)
 		)
 	}
 	;;
-poison)
-	# Emit garbage so that tests that incorrectly rely on translatable
-	# strings will fail.
-	gettext () {
-		printf "%s" "# GETTEXT POISON #"
-	}
-
-	eval_gettext () {
-		printf "%s" "# GETTEXT POISON #"
-	}
-
-	eval_ngettext () {
-		printf "%s" "# GETTEXT POISON #"
-	}
-	;;
 *)
 	gettext () {
 		printf "%s" "$1"
diff --git a/po/README b/po/README
index 07595d369b..efd5baaf1d 100644
--- a/po/README
+++ b/po/README
@@ -284,23 +284,5 @@ Perl:
 Testing marked strings
 ----------------------
 
-Even if you've correctly marked porcelain strings for translation
-something in the test suite might still depend on the US English
-version of the strings, e.g. to grep some error message or other
-output.
-
-To smoke out issues like these, Git tested with a translation mode that
-emits gibberish on every call to gettext. To use it run the test suite
-with it, e.g.:
-
-    cd t && GIT_TEST_GETTEXT_POISON=true prove -j 9 ./t[0-9]*.sh
-
-If tests break with it you should inspect them manually and see if
-what you're translating is sane, i.e. that you're not translating
-plumbing output.
-
-If not you should replace calls to grep with test_i18ngrep, or
-test_cmp calls with test_i18ncmp. If that's not enough you can skip
-the whole test by making it depend on the C_LOCALE_OUTPUT
-prerequisite. See existing test files with this prerequisite for
-examples.
+Git's tests are run under LANG=C LC_ALL=C. So the tests do not need be
+changed to account for translations as they're added.
diff --git a/t/README b/t/README
index c730a70770..9a9dded033 100644
--- a/t/README
+++ b/t/README
@@ -358,12 +358,6 @@ whether this mode is active, and e.g. skip some tests that are hard to
 refactor to deal with it. The "SYMLINKS" prerequisite is currently
 excluded as so much relies on it, but this might change in the future.
 
-GIT_TEST_GETTEXT_POISON=<boolean> turns all strings marked for
-translation into gibberish if true. Used for spotting those tests that
-need to be marked with a C_LOCALE_OUTPUT prerequisite when adding more
-strings for translation. See "Testing marked strings" in po/README for
-details.
-
 GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
 test suite. Accept any boolean values that are accepted by git-config.
 
diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh
index 2139b427ca..cc6bb2cdea 100644
--- a/t/lib-gettext.sh
+++ b/t/lib-gettext.sh
@@ -17,7 +17,7 @@ else
 	. "$GIT_BUILD_DIR"/git-sh-i18n
 fi
 
-if test_have_prereq GETTEXT && test_have_prereq C_LOCALE_OUTPUT
+if test_have_prereq GETTEXT
 then
 	# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
 	is_IS_locale=$(locale -a 2>/dev/null |
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index b72c051f47..172d7459ff 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -29,7 +29,6 @@ set_fake_editor () {
 	*/COMMIT_EDITMSG)
 		test -z "$EXPECT_HEADER_COUNT" ||
 			test "$EXPECT_HEADER_COUNT" = "$(sed -n '1s/^# This is a combination of \(.*\) commits\./\1/p' < "$1")" ||
-			test "# # GETTEXT POISON #" = "$(sed -n '1p' < "$1")" ||
 			exit
 		test -z "$FAKE_COMMIT_MESSAGE" || echo "$FAKE_COMMIT_MESSAGE" > "$1"
 		test -z "$FAKE_COMMIT_AMEND" || echo "$FAKE_COMMIT_AMEND" >> "$1"
diff --git a/t/t0017-env-helper.sh b/t/t0017-env-helper.sh
index c1ecf6aeac..4a159f99e4 100755
--- a/t/t0017-env-helper.sh
+++ b/t/t0017-env-helper.sh
@@ -86,14 +86,14 @@ test_expect_success 'env--helper reads config thanks to trace2' '
 	git config -f home/cycle include.path .gitconfig &&
 
 	test_must_fail \
-		env HOME="$(pwd)/home" GIT_TEST_GETTEXT_POISON=false \
+		env HOME="$(pwd)/home" \
 		git config -l 2>err &&
 	grep "exceeded maximum include depth" err &&
 
 	test_must_fail \
-		env HOME="$(pwd)/home" GIT_TEST_GETTEXT_POISON=true \
-		git -C cycle env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON 2>err &&
-	grep "# GETTEXT POISON #" err
+		env HOME="$(pwd)/home" GIT_TEST_ENV_HELPER=true \
+		git -C cycle env--helper --type=bool --default=0 --exit-code GIT_TEST_ENV_HELPER 2>err &&
+	grep "exceeded maximum include depth" err
 '
 
 test_done
diff --git a/t/t0205-gettext-poison.sh b/t/t0205-gettext-poison.sh
deleted file mode 100755
index f9fa16ad83..0000000000
--- a/t/t0205-gettext-poison.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010 Ævar Arnfjörð Bjarmason
-#
-
-test_description='Gettext Shell poison'
-
-GIT_TEST_GETTEXT_POISON=true
-export GIT_TEST_GETTEXT_POISON
-. ./lib-gettext.sh
-
-test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
-    test "$GIT_INTERNAL_GETTEXT_SH_SCHEME" = "poison"
-'
-
-test_expect_success 'gettext: our gettext() fallback has poison semantics' '
-    printf "# GETTEXT POISON #" >expect &&
-    gettext "test" >actual &&
-    test_cmp expect actual &&
-    printf "# GETTEXT POISON #" >expect &&
-    gettext "test more words" >actual &&
-    test_cmp expect actual
-'
-
-test_expect_success 'eval_gettext: our eval_gettext() fallback has poison semantics' '
-    printf "# GETTEXT POISON #" >expect &&
-    eval_gettext "test" >actual &&
-    test_cmp expect actual &&
-    printf "# GETTEXT POISON #" >expect &&
-    eval_gettext "test more words" >actual &&
-    test_cmp expect actual
-'
-
-test_expect_success "gettext: invalid GIT_TEST_GETTEXT_POISON value doesn't infinitely loop" "
-	test_must_fail env GIT_TEST_GETTEXT_POISON=xyz git version 2>error &&
-	grep \"fatal: bad numeric config value 'xyz' for 'GIT_TEST_GETTEXT_POISON': invalid unit\" error
-"
-
-test_done
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 4afc528165..6340e9bc72 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -64,13 +64,6 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '
 	! grep "^ fileX |  *1 +$" diffstat.txt
 '
 
-# Output to stderr:
-#
-#     "Does not point to a valid commit: invalid-ref"
-#
-# NEEDSWORK: This "grep" is fine in real non-C locales, but
-# GIT_TEST_GETTEXT_POISON poisons the refname along with the enclosing
-# error message.
 test_expect_success 'rebase --onto outputs the invalid ref' '
 	test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
 	test_i18ngrep "invalid-ref" err
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 2f08ce7cba..5befa8bd03 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -993,19 +993,16 @@ test_cmp_bin () {
 	cmp "$@"
 }
 
-# Use this instead of test_cmp to compare files that contain expected and
-# actual output from git commands that can be translated.  When running
-# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
-# results.
+# Wrapper for test_cmp which used to be used for
+# GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other
+# in-flight changes. Should not be used and will be removed soon.
 test_i18ncmp () {
-	! test_have_prereq C_LOCALE_OUTPUT || test_cmp "$@"
+	test_cmp "$@"
 }
 
-# Use this instead of "grep expected-string actual" to see if the
-# output from a git command that can be translated either contains an
-# expected string, or does not contain an unwanted one.  When running
-# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
-# results.
+# Wrapper for grep which used to be used for
+# GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other
+# in-flight changes. Should not be used and will be removed soon.
 test_i18ngrep () {
 	eval "last_arg=\${$#}"
 
@@ -1018,12 +1015,6 @@ test_i18ngrep () {
 		BUG "too few parameters to test_i18ngrep"
 	fi
 
-	if test_have_prereq !C_LOCALE_OUTPUT
-	then
-		# pretend success
-		return 0
-	fi
-
 	if test "x!" = "x$1"
 	then
 		shift
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 03c1c0836f..a5d8c207dd 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -404,15 +404,6 @@ TZ=UTC
 export LANG LC_ALL PAGER TZ
 EDITOR=:
 
-# GIT_TEST_GETTEXT_POISON should not influence git commands executed
-# during initialization of test-lib and the test repo. Back it up,
-# unset and then restore after initialization is finished.
-if test -n "$GIT_TEST_GETTEXT_POISON"
-then
-	GIT_TEST_GETTEXT_POISON_ORIG=$GIT_TEST_GETTEXT_POISON
-	unset GIT_TEST_GETTEXT_POISON
-fi
-
 # A call to "unset" with no arguments causes at least Solaris 10
 # /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
 # deriving from the command substitution clustered with the other
@@ -1529,16 +1520,10 @@ test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1
 test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
 
-if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
-then
-	GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
-	export GIT_TEST_GETTEXT_POISON
-	unset GIT_TEST_GETTEXT_POISON_ORIG
-fi
-
-test_lazy_prereq C_LOCALE_OUTPUT '
-	! test_bool_env GIT_TEST_GETTEXT_POISON false
-'
+# Used to be used for GIT_TEST_GETTEXT_POISON=false. Only here as a
+# shim for other in-flight changes. Should not be used and will be
+# removed soon.
+test_set_prereq C_LOCALE_OUTPUT
 
 if test -z "$GIT_TEST_CHECK_CACHE_TREE"
 then
-- 
2.29.2.222.g5d2a92d10f8


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

* [PATCH v2 3/3] tests: remove uses of GIT_TEST_GETTEXT_POISON=false
  2021-01-11 14:47                           ` [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility Ævar Arnfjörð Bjarmason
                                               ` (3 preceding siblings ...)
  2021-01-20 18:27                             ` [PATCH v2 2/3] tests: remove support for GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
@ 2021-01-20 18:27                             ` Ævar Arnfjörð Bjarmason
  4 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-20 18:27 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, SZEDER Gábor, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin,
	Ævar Arnfjörð Bjarmason

As noted in previous commits we are removing the use of
GIT_TEST_GETTEXT_POISON=false. These tests all relied on the facility
being off, it always is off after an earlier change, but we hadn't
removed the redundant assignments to "false" in the tests.

I'm preserving the deletion of "error" lines in 38b9197a76a (t5411:
add basic test cases for proc-receive hook, 2020-08-27), it turns out
that's useful even without GIT_TEST_GETTEXT_POISON=true in
play. Update a comment added in that commit to note that.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t1305-config-include.sh   | 4 +---
 t/t5411/common-functions.sh | 5 ++---
 t/t7201-co.sh               | 2 +-
 t/t9902-completion.sh       | 1 -
 4 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
index f1e1b289f9..f08cfcdfae 100755
--- a/t/t1305-config-include.sh
+++ b/t/t1305-config-include.sh
@@ -352,9 +352,7 @@ test_expect_success 'include cycles are detected' '
 	git init --bare cycle &&
 	git -C cycle config include.path cycle &&
 	git config -f cycle/cycle include.path config &&
-	test_must_fail \
-		env GIT_TEST_GETTEXT_POISON=false \
-		git -C cycle config --get-all test.value 2>stderr &&
+	test_must_fail git -C cycle config --get-all test.value 2>stderr &&
 	grep "exceeded maximum include depth" stderr
 '
 
diff --git a/t/t5411/common-functions.sh b/t/t5411/common-functions.sh
index 344d13f61a..13107fcdb6 100644
--- a/t/t5411/common-functions.sh
+++ b/t/t5411/common-functions.sh
@@ -36,9 +36,8 @@ create_commits_in () {
 # without having to worry about future changes of the commit ID and spaces
 # of the output.  Single quotes are replaced with double quotes, because
 # it is boring to prepare unquoted single quotes in expect text.  We also
-# remove some locale error messages, which break test if we turn on
-# `GIT_TEST_GETTEXT_POISON=true` in order to test unintentional translations
-# on plumbing commands.
+# remove some locale error messages. The emitted human-readable errors are
+# redundant to the more machine-readable output the tests already assert.
 make_user_friendly_and_stable_output () {
 	sed \
 		-e "s/  *\$//" \
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index b36a93056f..d10076efd7 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -245,7 +245,7 @@ test_expect_success 'checkout to detach HEAD' '
 	rev=$(git rev-parse --short renamer^) &&
 	git checkout -f renamer &&
 	git clean -f &&
-	GIT_TEST_GETTEXT_POISON=false git checkout renamer^ 2>messages &&
+	git checkout renamer^ 2>messages &&
 	grep "HEAD is now at $rev" messages &&
 	test_line_count -gt 1 messages &&
 	H=$(git rev-parse --verify HEAD) &&
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index c4a7758409..ea669cfaf5 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2363,7 +2363,6 @@ test_expect_success 'sourcing the completion script clears cached commands' '
 '
 
 test_expect_success 'sourcing the completion script clears cached merge strategies' '
-	GIT_TEST_GETTEXT_POISON=false &&
 	__git_compute_merge_strategies &&
 	verbose test -n "$__git_merge_strategies" &&
 	. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
-- 
2.29.2.222.g5d2a92d10f8


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

* Re: [PATCH 1/6] ci: remove GETTEXT_POISON jobs
  2021-01-20 17:59                               ` Ævar Arnfjörð Bjarmason
@ 2021-01-20 19:14                                 ` SZEDER Gábor
  2021-01-27  0:47                                   ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: SZEDER Gábor @ 2021-01-20 19:14 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin

On Wed, Jan 20, 2021 at 06:59:14PM +0100, Ævar Arnfjörð Bjarmason wrote:
> 
> On Tue, Jan 12 2021, SZEDER Gábor wrote:
> 
> > On Mon, Jan 11, 2021 at 03:47:35PM +0100, Ævar Arnfjörð Bjarmason wrote:
> >> A subsequent commit will remove GETTEXT_POISON entirely, let's start
> >> by removing the CI jobs that enable the option.
> >> 
> >> We cannot just remove the job because the CI is implicitly depending
> >> on the "poison" job being a sort of "default" job.
> >
> > I don't understand what you mean here with a "default job" that the CI
> > is implicitly depending on.  There is certainly no such default job on
> > Travis CI, and I don't think there is one on the GitHub thing.
> 
> I'll reword this. I meant that the poison job was using the default
> compiler etc., whereas the other ones were setting custom values.
> 
> I vaguely remember some list traffic about this in the past, i.e. the
> reliance on the poison job not just for that, but also as "the default
> OS image" setup.

Oh, I didn't mean that the commit message should be clarified.  I
meant that the GETTEXT_POISON job can simply be deleted.  Sorry for
not being clear enough.


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

* Re: [PATCH 1/6] ci: remove GETTEXT_POISON jobs
  2021-01-20 19:14                                 ` SZEDER Gábor
@ 2021-01-27  0:47                                   ` Ævar Arnfjörð Bjarmason
  2021-02-01 22:04                                     ` SZEDER Gábor
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-01-27  0:47 UTC (permalink / raw)
  To: SZEDER Gábor
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin


On Wed, Jan 20 2021, SZEDER Gábor wrote:

> On Wed, Jan 20, 2021 at 06:59:14PM +0100, Ævar Arnfjörð Bjarmason wrote:
>> 
>> On Tue, Jan 12 2021, SZEDER Gábor wrote:
>> 
>> > On Mon, Jan 11, 2021 at 03:47:35PM +0100, Ævar Arnfjörð Bjarmason wrote:
>> >> A subsequent commit will remove GETTEXT_POISON entirely, let's start
>> >> by removing the CI jobs that enable the option.
>> >> 
>> >> We cannot just remove the job because the CI is implicitly depending
>> >> on the "poison" job being a sort of "default" job.
>> >
>> > I don't understand what you mean here with a "default job" that the CI
>> > is implicitly depending on.  There is certainly no such default job on
>> > Travis CI, and I don't think there is one on the GitHub thing.
>> 
>> I'll reword this. I meant that the poison job was using the default
>> compiler etc., whereas the other ones were setting custom values.
>> 
>> I vaguely remember some list traffic about this in the past, i.e. the
>> reliance on the poison job not just for that, but also as "the default
>> OS image" setup.
>
> Oh, I didn't mean that the commit message should be clarified.  I
> meant that the GETTEXT_POISON job can simply be deleted.  Sorry for
> not being clear enough.

I still don't get it, and my patch still seems fine as it is to me. But
I'm probably missing something.

I'm looking at these, both pointing at e6362826a04 (The fourth batch,
2021-01-25):

    # Currently says "Please be aware travis-ci.org will be shutting
    # down in several weeks"
    https://www.travis-ci.org/github/git/git/builds/756176098

    https://github.com/git/git/actions/runs/510676142

For the GitHub one, there's only two things that are linux && gcc. The
linux-gcc job, and GETTEXT_POISON (renamed to linux-gcc-default in this
series).

In ci/install-dependencies.sh we install GCC 8 for linux-gcc, but also
perforce, apache, git-lfs etc.

Then in ci/lib.sh we set CC=gcc-8 on linux-gcc, but retain the default
on GETTEXT_POISON. We also set GIT_TEST_HTTPD=true.

So hence "linux-gcc-default", we're running as close to a default set of
packages we can get and build/run git at all. I.e. just "apt install
$UBUNTU_COMMON_PKGS".

Then in ci/run-build-and-tests.sh the "linux-gcc" job is also our "let's
turn on every GIT_TEST_* option you've heard of" job. Whereas on the
GETTEXT_POISON job we just ran "make test", well, with
GIT_TEST_GETTEXT_POISON=true before this series, but that was the only
non-default, now we've got no non-defaults.

I can see why we'd want this on top:
    
    diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
    index 50e0b90073f..3071099eaca 100755
    --- a/ci/run-build-and-tests.sh
    +++ b/ci/run-build-and-tests.sh
    @@ -32,11 +32,6 @@ linux-clang)
            export GIT_TEST_DEFAULT_HASH=sha256
            make test
            ;;
    -linux-gcc-4.8)
    -       # Don't run the tests; we only care about whether Git can be
    -       # built with GCC 4.8, as it errors out on some undesired (C99)
    -       # constructs that newer compilers seem to quietly accept.
    -       ;;
     *)
            make test
            ;;

Because there we're skipping tests on linux-gcc-4.8, but on travis it's
the only Ubuntu Trusty image (default is Xenial), so yes we build with
gcc 4.8, but we're also missing out in seeing if our tests are working
on a slightly older Ubuntu.

Also on GitHub's page the GETTEXT_POISON job finishes in ~10m but all
the other ones in ~30m, I see some run "make test" twice, as an aside is
there some limit on jobs but not overall CPU? Otherwise those would
finish faster if that was split up.

But "make test" twice doesn't account for a ~3x increase, so it's got to
be the extra tests we're running, i.e. svn tests, httpd etc.

It seems to me to provide value in itself to run some shorter version of
the CI for people using it as a poor man's edit/push/ci/edit loop.

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

* Re: [PATCH 1/6] ci: remove GETTEXT_POISON jobs
  2021-01-27  0:47                                   ` Ævar Arnfjörð Bjarmason
@ 2021-02-01 22:04                                     ` SZEDER Gábor
  2021-02-03 12:13                                       ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: SZEDER Gábor @ 2021-02-01 22:04 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin

On Wed, Jan 27, 2021 at 01:47:27AM +0100, Ævar Arnfjörð Bjarmason wrote:
> 
> On Wed, Jan 20 2021, SZEDER Gábor wrote:
> 
> > On Wed, Jan 20, 2021 at 06:59:14PM +0100, Ævar Arnfjörð Bjarmason wrote:
> >> 
> >> On Tue, Jan 12 2021, SZEDER Gábor wrote:
> >> 
> >> > On Mon, Jan 11, 2021 at 03:47:35PM +0100, Ævar Arnfjörð Bjarmason wrote:
> >> >> A subsequent commit will remove GETTEXT_POISON entirely, let's start
> >> >> by removing the CI jobs that enable the option.
> >> >> 
> >> >> We cannot just remove the job because the CI is implicitly depending
> >> >> on the "poison" job being a sort of "default" job.
> >> >
> >> > I don't understand what you mean here with a "default job" that the CI
> >> > is implicitly depending on.  There is certainly no such default job on
> >> > Travis CI, and I don't think there is one on the GitHub thing.
> >> 
> >> I'll reword this. I meant that the poison job was using the default
> >> compiler etc., whereas the other ones were setting custom values.
> >> 
> >> I vaguely remember some list traffic about this in the past, i.e. the
> >> reliance on the poison job not just for that, but also as "the default
> >> OS image" setup.
> >
> > Oh, I didn't mean that the commit message should be clarified.  I
> > meant that the GETTEXT_POISON job can simply be deleted.  Sorry for
> > not being clear enough.
> 
> I still don't get it, and my patch still seems fine as it is to me. But
> I'm probably missing something.
> 
> I'm looking at these, both pointing at e6362826a04 (The fourth batch,
> 2021-01-25):
> 
>     # Currently says "Please be aware travis-ci.org will be shutting
>     # down in several weeks"

... and continues with:

  "with all accounts migrating to travis-ci.com.  Please stay tuned
   here for more information."

FWIW, I recently migrated manually, and apart from the different TLD
haven't noticed anything different (though somehow the jobs in my .org
builds sometimes took a while to start lately, but on .com they all
started real fast so far, as they should).

>     https://www.travis-ci.org/github/git/git/builds/756176098
> 
>     https://github.com/git/git/actions/runs/510676142
> 
> For the GitHub one, there's only two things that are linux && gcc. The
> linux-gcc job, and GETTEXT_POISON (renamed to linux-gcc-default in this
> series).
> 
> In ci/install-dependencies.sh we install GCC 8 for linux-gcc, but also
> perforce, apache, git-lfs etc.
> 
> Then in ci/lib.sh we set CC=gcc-8 on linux-gcc, but retain the default
> on GETTEXT_POISON. We also set GIT_TEST_HTTPD=true.
> 
> So hence "linux-gcc-default", we're running as close to a default set of
> packages we can get and build/run git at all. I.e. just "apt install
> $UBUNTU_COMMON_PKGS".

We started installing newer compilers, because we wanted to benefit
from their better error reporting and improved warnings.  The reason
we did that in existing CI jobs without adding a "default" job was
that we don't care enough about the default compiler and configuration
to justify its additional runtime, because we run the test suite
enough times already.

Considering that the number of CI jobs has grown since then, I would
rather see the build complete faster than a default job running the
test suite for the N+1th time.

> Then in ci/run-build-and-tests.sh the "linux-gcc" job is also our "let's
> turn on every GIT_TEST_* option you've heard of" job. Whereas on the
> GETTEXT_POISON job we just ran "make test", well, with
> GIT_TEST_GETTEXT_POISON=true before this series, but that was the only
> non-default, now we've got no non-defaults.
> 
> I can see why we'd want this on top:
>     
>     diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
>     index 50e0b90073f..3071099eaca 100755
>     --- a/ci/run-build-and-tests.sh
>     +++ b/ci/run-build-and-tests.sh
>     @@ -32,11 +32,6 @@ linux-clang)
>             export GIT_TEST_DEFAULT_HASH=sha256
>             make test
>             ;;
>     -linux-gcc-4.8)
>     -       # Don't run the tests; we only care about whether Git can be
>     -       # built with GCC 4.8, as it errors out on some undesired (C99)
>     -       # constructs that newer compilers seem to quietly accept.
>     -       ;;
>      *)
>             make test
>             ;;
> 
> Because there we're skipping tests on linux-gcc-4.8, but on travis it's
> the only Ubuntu Trusty image (default is Xenial), so yes we build with
> gcc 4.8, but we're also missing out in seeing if our tests are working
> on a slightly older Ubuntu.

The above comment you propose to remove explains why you should not
remove it...  And, again, running the test suite doesn't seem to worth
the extra runtime.


> Also on GitHub's page the GETTEXT_POISON job finishes in ~10m but all
> the other ones in ~30m, I see some run "make test" twice, as an aside is
> there some limit on jobs but not overall CPU? Otherwise those would
> finish faster if that was split up.
> 
> But "make test" twice doesn't account for a ~3x increase, so it's got to
> be the extra tests we're running, i.e. svn tests, httpd etc.
> 
> It seems to me to provide value in itself to run some shorter version of
> the CI for people using it as a poor man's edit/push/ci/edit loop.

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

* Re: [PATCH 1/6] ci: remove GETTEXT_POISON jobs
  2021-02-01 22:04                                     ` SZEDER Gábor
@ 2021-02-03 12:13                                       ` Ævar Arnfjörð Bjarmason
  2021-02-03 21:24                                         ` SZEDER Gábor
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-02-03 12:13 UTC (permalink / raw)
  To: SZEDER Gábor
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin


On Mon, Feb 01 2021, SZEDER Gábor wrote:

> On Wed, Jan 27, 2021 at 01:47:27AM +0100, Ævar Arnfjörð Bjarmason wrote:
>> 
>> On Wed, Jan 20 2021, SZEDER Gábor wrote:
>> 
>> > On Wed, Jan 20, 2021 at 06:59:14PM +0100, Ævar Arnfjörð Bjarmason wrote:
>> >> 
>> >> On Tue, Jan 12 2021, SZEDER Gábor wrote:
>> >> 
>> >> > On Mon, Jan 11, 2021 at 03:47:35PM +0100, Ævar Arnfjörð Bjarmason wrote:
>> >> >> A subsequent commit will remove GETTEXT_POISON entirely, let's start
>> >> >> by removing the CI jobs that enable the option.
>> >> >> 
>> >> >> We cannot just remove the job because the CI is implicitly depending
>> >> >> on the "poison" job being a sort of "default" job.
>> >> >
>> >> > I don't understand what you mean here with a "default job" that the CI
>> >> > is implicitly depending on.  There is certainly no such default job on
>> >> > Travis CI, and I don't think there is one on the GitHub thing.
>> >> 
>> >> I'll reword this. I meant that the poison job was using the default
>> >> compiler etc., whereas the other ones were setting custom values.
>> >> 
>> >> I vaguely remember some list traffic about this in the past, i.e. the
>> >> reliance on the poison job not just for that, but also as "the default
>> >> OS image" setup.
>> >
>> > Oh, I didn't mean that the commit message should be clarified.  I
>> > meant that the GETTEXT_POISON job can simply be deleted.  Sorry for
>> > not being clear enough.
>> 
>> I still don't get it, and my patch still seems fine as it is to me. But
>> I'm probably missing something.
>> 
>> I'm looking at these, both pointing at e6362826a04 (The fourth batch,
>> 2021-01-25):
>> 
>>     # Currently says "Please be aware travis-ci.org will be shutting
>>     # down in several weeks"
>
> ... and continues with:
>
>   "with all accounts migrating to travis-ci.com.  Please stay tuned
>    here for more information."
>
> FWIW, I recently migrated manually, and apart from the different TLD
> haven't noticed anything different (though somehow the jobs in my .org
> builds sometimes took a while to start lately, but on .com they all
> started real fast so far, as they should).
>
>>     https://www.travis-ci.org/github/git/git/builds/756176098
>> 
>>     https://github.com/git/git/actions/runs/510676142
>> 
>> For the GitHub one, there's only two things that are linux && gcc. The
>> linux-gcc job, and GETTEXT_POISON (renamed to linux-gcc-default in this
>> series).
>> 
>> In ci/install-dependencies.sh we install GCC 8 for linux-gcc, but also
>> perforce, apache, git-lfs etc.
>> 
>> Then in ci/lib.sh we set CC=gcc-8 on linux-gcc, but retain the default
>> on GETTEXT_POISON. We also set GIT_TEST_HTTPD=true.
>> 
>> So hence "linux-gcc-default", we're running as close to a default set of
>> packages we can get and build/run git at all. I.e. just "apt install
>> $UBUNTU_COMMON_PKGS".
>
> We started installing newer compilers, because we wanted to benefit
> from their better error reporting and improved warnings.  The reason
> we did that in existing CI jobs without adding a "default" job was
> that we don't care enough about the default compiler and configuration
> to justify its additional runtime, because we run the test suite
> enough times already.

So in summary, you'd like it removed because the combination of
GETTEXT_POISON + old compiler is no longer worth it, but while we were
running with GETTEXT_POISON anyway we might as well run it on the old
compiler?

> Considering that the number of CI jobs has grown since then, I would
> rather see the build complete faster than a default job running the
> test suite for the N+1th time.

[...]

>> Then in ci/run-build-and-tests.sh the "linux-gcc" job is also our "let's
>> turn on every GIT_TEST_* option you've heard of" job. Whereas on the
>> GETTEXT_POISON job we just ran "make test", well, with
>> GIT_TEST_GETTEXT_POISON=true before this series, but that was the only
>> non-default, now we've got no non-defaults.
>> 
>> I can see why we'd want this on top:
>>     
>>     diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
>>     index 50e0b90073f..3071099eaca 100755
>>     --- a/ci/run-build-and-tests.sh
>>     +++ b/ci/run-build-and-tests.sh
>>     @@ -32,11 +32,6 @@ linux-clang)
>>             export GIT_TEST_DEFAULT_HASH=sha256
>>             make test
>>             ;;
>>     -linux-gcc-4.8)
>>     -       # Don't run the tests; we only care about whether Git can be
>>     -       # built with GCC 4.8, as it errors out on some undesired (C99)
>>     -       # constructs that newer compilers seem to quietly accept.
>>     -       ;;
>>      *)
>>             make test
>>             ;;
>> 
>> Because there we're skipping tests on linux-gcc-4.8, but on travis it's
>> the only Ubuntu Trusty image (default is Xenial), so yes we build with
>> gcc 4.8, but we're also missing out in seeing if our tests are working
>> on a slightly older Ubuntu.
>
> The above comment you propose to remove explains why you should not
> remove it...  And, again, running the test suite doesn't seem to worth
> the extra runtime.

How is it extra runtime in any meaningful sense?

Yes, we spend more CPU time, but as far as I can tell (and I'm looking
at an ongoing run on GitHub now) these jobs are run concurrently. Some
of that was covered in the quoted paragraph below that you didn't reply
to.

I.e. if I push a commit I don't care if 10 minutes of CPU time are being
wasted by a machine sitting in some rack somewhere, the important part
is that I may be saving 20 minutes of my time, since the faster 10
minute test (running concurrently with the ~30m tests) might fail
earlier.

Or are there some job limits involved here that I'm missing?

As I was writing this the CI job for GETTEXT_POISON just finished in
10m16s showing OK=green, and the rest are still churning.

>> Also on GitHub's page the GETTEXT_POISON job finishes in ~10m but all
>> the other ones in ~30m, I see some run "make test" twice, as an aside is
>> there some limit on jobs but not overall CPU? Otherwise those would
>> finish faster if that was split up.
>> 
>> But "make test" twice doesn't account for a ~3x increase, so it's got to
>> be the extra tests we're running, i.e. svn tests, httpd etc.
>> 
>> It seems to me to provide value in itself to run some shorter version of
>> the CI for people using it as a poor man's edit/push/ci/edit loop.


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

* Re: [PATCH 1/6] ci: remove GETTEXT_POISON jobs
  2021-02-03 12:13                                       ` Ævar Arnfjörð Bjarmason
@ 2021-02-03 21:24                                         ` SZEDER Gábor
  0 siblings, 0 replies; 229+ messages in thread
From: SZEDER Gábor @ 2021-02-03 21:24 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Johannes Schindelin,
	Nguyễn Thái Ngọc Duy, Jiang Xin

On Wed, Feb 03, 2021 at 01:13:32PM +0100, Ævar Arnfjörð Bjarmason wrote:
> 
> On Mon, Feb 01 2021, SZEDER Gábor wrote:
> 
> > On Wed, Jan 27, 2021 at 01:47:27AM +0100, Ævar Arnfjörð Bjarmason wrote:
> >> 
> >> On Wed, Jan 20 2021, SZEDER Gábor wrote:
> >> 
> >> > On Wed, Jan 20, 2021 at 06:59:14PM +0100, Ævar Arnfjörð Bjarmason wrote:
> >> >> 
> >> >> On Tue, Jan 12 2021, SZEDER Gábor wrote:
> >> >> 
> >> >> > On Mon, Jan 11, 2021 at 03:47:35PM +0100, Ævar Arnfjörð Bjarmason wrote:
> >> >> >> A subsequent commit will remove GETTEXT_POISON entirely, let's start
> >> >> >> by removing the CI jobs that enable the option.
> >> >> >> 
> >> >> >> We cannot just remove the job because the CI is implicitly depending
> >> >> >> on the "poison" job being a sort of "default" job.
> >> >> >
> >> >> > I don't understand what you mean here with a "default job" that the CI
> >> >> > is implicitly depending on.  There is certainly no such default job on
> >> >> > Travis CI, and I don't think there is one on the GitHub thing.
> >> >> 
> >> >> I'll reword this. I meant that the poison job was using the default
> >> >> compiler etc., whereas the other ones were setting custom values.
> >> >> 
> >> >> I vaguely remember some list traffic about this in the past, i.e. the
> >> >> reliance on the poison job not just for that, but also as "the default
> >> >> OS image" setup.
> >> >
> >> > Oh, I didn't mean that the commit message should be clarified.  I
> >> > meant that the GETTEXT_POISON job can simply be deleted.  Sorry for
> >> > not being clear enough.
> >> 
> >> I still don't get it, and my patch still seems fine as it is to me. But
> >> I'm probably missing something.
> >> 
> >> I'm looking at these, both pointing at e6362826a04 (The fourth batch,
> >> 2021-01-25):
> >> 
> >>     # Currently says "Please be aware travis-ci.org will be shutting
> >>     # down in several weeks"
> >
> > ... and continues with:
> >
> >   "with all accounts migrating to travis-ci.com.  Please stay tuned
> >    here for more information."
> >
> > FWIW, I recently migrated manually, and apart from the different TLD
> > haven't noticed anything different (though somehow the jobs in my .org
> > builds sometimes took a while to start lately, but on .com they all
> > started real fast so far, as they should).
> >
> >>     https://www.travis-ci.org/github/git/git/builds/756176098
> >> 
> >>     https://github.com/git/git/actions/runs/510676142
> >> 
> >> For the GitHub one, there's only two things that are linux && gcc. The
> >> linux-gcc job, and GETTEXT_POISON (renamed to linux-gcc-default in this
> >> series).
> >> 
> >> In ci/install-dependencies.sh we install GCC 8 for linux-gcc, but also
> >> perforce, apache, git-lfs etc.
> >> 
> >> Then in ci/lib.sh we set CC=gcc-8 on linux-gcc, but retain the default
> >> on GETTEXT_POISON. We also set GIT_TEST_HTTPD=true.
> >> 
> >> So hence "linux-gcc-default", we're running as close to a default set of
> >> packages we can get and build/run git at all. I.e. just "apt install
> >> $UBUNTU_COMMON_PKGS".
> >
> > We started installing newer compilers, because we wanted to benefit
> > from their better error reporting and improved warnings.  The reason
> > we did that in existing CI jobs without adding a "default" job was
> > that we don't care enough about the default compiler and configuration
> > to justify its additional runtime, because we run the test suite
> > enough times already.
> 
> So in summary, you'd like it removed because the combination of
> GETTEXT_POISON + old compiler is no longer worth it, but while we were
> running with GETTEXT_POISON anyway we might as well run it on the old
> compiler?

Yes, though I suspect that "no one gave a damn about the compiler used
in the GETTEXT_POISON job" might be closer to the truth.  Or even "no
one gave a damn about the GETTEXT_POISON job"...

And apart from the occasional translation-related failure (i.e. 'grep
"<translated message>" actual') and one flaky test that happened to
fail in the GETTEXT_POISON job I can't recall a single case where
building and testing with the default compiler discovered an issue
that the other jobs didn't.

> > Considering that the number of CI jobs has grown since then, I would
> > rather see the build complete faster than a default job running the
> > test suite for the N+1th time.
> 
> [...]
> 
> >> Then in ci/run-build-and-tests.sh the "linux-gcc" job is also our "let's
> >> turn on every GIT_TEST_* option you've heard of" job. Whereas on the
> >> GETTEXT_POISON job we just ran "make test", well, with
> >> GIT_TEST_GETTEXT_POISON=true before this series, but that was the only
> >> non-default, now we've got no non-defaults.
> >> 
> >> I can see why we'd want this on top:
> >>     
> >>     diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh
> >>     index 50e0b90073f..3071099eaca 100755
> >>     --- a/ci/run-build-and-tests.sh
> >>     +++ b/ci/run-build-and-tests.sh
> >>     @@ -32,11 +32,6 @@ linux-clang)
> >>             export GIT_TEST_DEFAULT_HASH=sha256
> >>             make test
> >>             ;;
> >>     -linux-gcc-4.8)
> >>     -       # Don't run the tests; we only care about whether Git can be
> >>     -       # built with GCC 4.8, as it errors out on some undesired (C99)
> >>     -       # constructs that newer compilers seem to quietly accept.
> >>     -       ;;
> >>      *)
> >>             make test
> >>             ;;
> >> 
> >> Because there we're skipping tests on linux-gcc-4.8, but on travis it's
> >> the only Ubuntu Trusty image (default is Xenial), so yes we build with
> >> gcc 4.8, but we're also missing out in seeing if our tests are working
> >> on a slightly older Ubuntu.
> >
> > The above comment you propose to remove explains why you should not
> > remove it...  And, again, running the test suite doesn't seem to worth
> > the extra runtime.
> 
> How is it extra runtime in any meaningful sense?
> 
> Yes, we spend more CPU time, but as far as I can tell (and I'm looking
> at an ongoing run on GitHub now)

(Well, I'm looking at eight ongoing builds now...)

> these jobs are run concurrently. Some
> of that was covered in the quoted paragraph below that you didn't reply
> to.
> 
> I.e. if I push a commit I don't care if 10 minutes of CPU time are being
> wasted by a machine sitting in some rack somewhere, the important part
> is that I may be saving 20 minutes of my time, since the faster 10
> minute test (running concurrently with the ~30m tests) might fail
> earlier.
> 
> Or are there some job limits involved here that I'm missing?

Travis CI usually runs 3 Linux and 2 OSX jobs in parallel, and I doubt
that GitHub would be foolish enough to run all my jobs parallel if I
were to use it.

> As I was writing this the CI job for GETTEXT_POISON just finished in
> 10m16s showing OK=green, and the rest are still churning.

Indeed, but you should also consider that:

  - At 10m16s that job is notably slower than even my tiny old laptop,
    even though it runs less tests.  If you really want to save time,
    then run 'make test' locally.

  - Without the GETTEXT_POISON job the whole build would be finished
    ~10 minutes earlier.  With six builds that's an hour.


> >> Also on GitHub's page the GETTEXT_POISON job finishes in ~10m but all
> >> the other ones in ~30m, I see some run "make test" twice, as an aside is
> >> there some limit on jobs but not overall CPU? Otherwise those would
> >> finish faster if that was split up.
> >> 
> >> But "make test" twice doesn't account for a ~3x increase, so it's got to
> >> be the extra tests we're running, i.e. svn tests, httpd etc.
> >> 
> >> It seems to me to provide value in itself to run some shorter version of
> >> the CI for people using it as a poor man's edit/push/ci/edit loop.
> 

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

* [PATCH 0/4] More GETTEXT_POISON removal
  2021-01-20 18:27                             ` [PATCH v2 0/3] " Ævar Arnfjörð Bjarmason
@ 2021-02-11  1:53                               ` Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 1/4] tests: remove last uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
                                                 ` (3 subsequent siblings)
  4 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-02-11  1:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Johannes Schindelin, SZEDER Gábor,
	Jiang Xin, Ævar Arnfjörð Bjarmason

Now that the removal of GETTEXT_POISON is in master follow-up [1] with
some more removal of now-dead code that assumed it still existed.

This leaves no uses of GIT_TEST_GETTEXT_POISON=false or
C_LOCALE_OUTPUT at the end, in 4/4 I'm removing most of test_i18ncmp,
but stopping short of conflicting with other in-flight topics, so once
those land we'll need another cleanup patch to clean up the
stragglers.

As with [1] I'm not touching test_i18ngrep since SZEDER expressed some
interest in retainng it as a generally useful grep with more verbose
debugging.

1. https://lore.kernel.org/git/20210120182759.31102-1-avarab@gmail.com/

Ævar Arnfjörð Bjarmason (4):
  tests: remove last uses of GIT_TEST_GETTEXT_POISON=false
  tests: remove most uses of C_LOCALE_OUTPUT
  tests: remove last uses of C_LOCALE_OUTPUT
  tests: remove most uses of test_i18ncmp

 t/lib-credential.sh                       |   2 +-
 t/lib-log-graph.sh                        |   4 +-
 t/t0000-basic.sh                          |   2 +-
 t/t0006-date.sh                           |   4 +-
 t/t0008-ignores.sh                        |   2 +-
 t/t0012-help.sh                           |   2 +-
 t/t0018-advice.sh                         |   4 +-
 t/t0020-crlf.sh                           |   6 +-
 t/t0027-auto-crlf.sh                      |   2 +-
 t/t0040-parse-options.sh                  |   8 +-
 t/t0201-gettext-fallbacks.sh              |  16 ++--
 t/t0300-credentials.sh                    |   8 +-
 t/t0500-progress-display.sh               |  22 ++---
 t/t1011-read-tree-sparse-checkout.sh      |   2 +-
 t/t1308-config-set.sh                     |   4 +-
 t/t1400-update-ref.sh                     |   6 +-
 t/t1404-update-ref-errors.sh              |   2 +-
 t/t1430-bad-ref-name.sh                   |   2 +-
 t/t1450-fsck.sh                           |   6 +-
 t/t1502-rev-parse-parseopt.sh             |  10 +-
 t/t1506-rev-parse-diagnosis.sh            |   2 +-
 t/t1507-rev-parse-upstream.sh             |  10 +-
 t/t1509-root-work-tree.sh                 |   4 +-
 t/t1512-rev-parse-disambiguation.sh       |  14 +--
 t/t1600-index.sh                          |   6 +-
 t/t2018-checkout-branch.sh                |   2 +-
 t/t2020-checkout-detach.sh                |  20 ++--
 t/t2200-add-update.sh                     |   2 +-
 t/t2401-worktree-prune.sh                 |   4 +-
 t/t2402-worktree-list.sh                  |   2 +-
 t/t3005-ls-files-relative.sh              |   4 +-
 t/t3200-branch.sh                         |  26 ++---
 t/t3201-branch-contains.sh                |   2 +-
 t/t3203-branch-output.sh                  |  28 +++---
 t/t3300-funny-names.sh                    |   2 +-
 t/t3400-rebase.sh                         |   2 +-
 t/t3404-rebase-interactive.sh             |  38 ++++----
 t/t3415-rebase-autosquash.sh              |  10 +-
 t/t3420-rebase-autostash.sh               |   4 +-
 t/t3504-cherry-pick-rerere.sh             |   4 +-
 t/t3507-cherry-pick-conflict.sh           |  12 +--
 t/t3508-cherry-pick-many-commits.sh       |   4 +-
 t/t3510-cherry-pick-sequence.sh           |   8 +-
 t/t3600-rm.sh                             |  16 ++--
 t/t3700-add.sh                            |   8 +-
 t/t3701-add-interactive.sh                |   4 +-
 t/t3800-mktag.sh                          |  12 +--
 t/t3903-stash.sh                          |   8 +-
 t/t3905-stash-include-untracked.sh        |   2 +-
 t/t4006-diff-mode.sh                      |   8 +-
 t/t4012-diff-binary.sh                    |  10 +-
 t/t4013-diff-various.sh                   |   2 +-
 t/t4014-format-patch.sh                   |   6 +-
 t/t4016-diff-quote.sh                     |   2 +-
 t/t4030-diff-textconv.sh                  |   2 +-
 t/t4045-diff-relative.sh                  |   2 +-
 t/t4049-diff-stat-count.sh                |   6 +-
 t/t4100-apply-stat.sh                     |   4 +-
 t/t4150-am.sh                             |   2 +-
 t/t4153-am-resume-override-opts.sh        |   2 +-
 t/t4205-log-pretty-formats.sh             |   4 +-
 t/t4254-am-corrupt.sh                     |   2 +-
 t/t5150-request-pull.sh                   |   4 +-
 t/t5300-pack-object.sh                    |   4 +-
 t/t5316-pack-delta-depth.sh               |   4 +-
 t/t5500-fetch-pack.sh                     |   6 +-
 t/t5505-remote.sh                         |  30 +++---
 t/t5510-fetch.sh                          |   6 +-
 t/t5512-ls-remote.sh                      |   2 +-
 t/t5526-fetch-submodules.sh               |  38 ++++----
 t/t5541-http-push-smart.sh                |   2 +-
 t/t5601-clone.sh                          |   2 +-
 t/t6020-bundle-misc.sh                    |  28 +++---
 t/t6030-bisect-porcelain.sh               |   4 +-
 t/t6040-tracking-info.sh                  |  22 ++---
 t/t6120-describe.sh                       |   2 +-
 t/t6134-pathspec-in-submodule.sh          |   2 +-
 t/t6301-for-each-ref-errors.sh            |  10 +-
 t/t6423-merge-rename-directories.sh       |   2 +-
 t/t6436-merge-overwrite.sh                |   4 +-
 t/t6439-merge-co-error-msgs.sh            |  12 +--
 t/t7001-mv.sh                             |   2 +-
 t/t7004-tag.sh                            |   8 +-
 t/t7012-skip-worktree-writing.sh          |   4 +-
 t/t7060-wtstatus.sh                       |  14 +--
 t/t7063-status-untracked-cache.sh         |   2 +-
 t/t7102-reset.sh                          |   6 +-
 t/t7300-clean.sh                          |   6 +-
 t/t7400-submodule-basic.sh                |   4 +-
 t/t7401-submodule-summary.sh              |  12 +--
 t/t7406-submodule-update.sh               |  16 ++--
 t/t7407-submodule-foreach.sh              |  10 +-
 t/t7500-commit-template-squash-signoff.sh |   4 +-
 t/t7502-commit-porcelain.sh               |   6 +-
 t/t7505-prepare-commit-msg-hook.sh        |   4 +-
 t/t7508-status.sh                         | 110 +++++++++++-----------
 t/t7512-status-help.sh                    |  74 +++++++--------
 t/t7519-status-fsmonitor.sh               |   4 +-
 t/t7521-ignored-mode.sh                   |  22 ++---
 t/t7600-merge.sh                          |   4 +-
 t/t7602-merge-octopus-many.sh             |   6 +-
 t/t7810-grep.sh                           |   2 +-
 t/t9003-help-autocorrect.sh               |   7 +-
 t/test-lib.sh                             |   5 -
 104 files changed, 464 insertions(+), 478 deletions(-)

-- 
2.30.0.284.gd98b1dd5eaa7


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

* [PATCH 1/4] tests: remove last uses of GIT_TEST_GETTEXT_POISON=false
  2021-01-20 18:27                             ` [PATCH v2 0/3] " Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 0/4] More GETTEXT_POISON removal Ævar Arnfjörð Bjarmason
@ 2021-02-11  1:53                               ` Ævar Arnfjörð Bjarmason
  2021-03-07 13:29                                 ` [PATCH] mktag tests: fix broken "&&" chain Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 2/4] tests: remove most uses of C_LOCALE_OUTPUT Ævar Arnfjörð Bjarmason
                                                 ` (2 subsequent siblings)
  4 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-02-11  1:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Johannes Schindelin, SZEDER Gábor,
	Jiang Xin, Ævar Arnfjörð Bjarmason

Follow-up my 73c01d25fe2 (tests: remove uses of
GIT_TEST_GETTEXT_POISON=false, 2021-01-20) by removing the last uses
of GIT_TEST_GETTEXT_POISON=*.

These assignments were part of branch that was in-flight at the time
of the gettext poison removal. See 466f94ec45e (Merge branch
'ab/detox-gettext-tests', 2021-02-10) and c7d6d419b0d (Merge branch
'ab/mktag', 2021-01-25) for the merging of the two branches.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 86bfeb271ec..60a666da595 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -13,13 +13,11 @@ test_description='git mktag: tag object verify test'
 
 check_verify_failure () {
 	test_expect_success "$1" "
-		test_must_fail env GIT_TEST_GETTEXT_POISON=false \
-			git mktag <tag.sig 2>message &&
+		test_must_fail git mktag <tag.sig 2>message &&
 		grep '$2' message &&
 		if test '$3' != '--no-strict'
 		then
-			test_must_fail env GIT_TEST_GETTEXT_POISON=false \
-				git mktag --no-strict <tag.sig 2>message.no-strict &&
+			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&xb
 			grep '$2' message.no-strict
 		fi
 	"
@@ -443,11 +441,9 @@ test_expect_success 'invalid header entry config & fsck' '
 	git -c fsck.extraHeaderEntry=ignore mktag --no-strict <tag.sig &&
 
 	git fsck &&
-	env GIT_TEST_GETTEXT_POISON=false \
-		git -c fsck.extraHeaderEntry=warn fsck 2>err &&
+	git -c fsck.extraHeaderEntry=warn fsck 2>err &&
 	grep "warning .*extraHeaderEntry:" err &&
-	test_must_fail env GIT_TEST_GETTEXT_POISON=false \
-		git -c fsck.extraHeaderEntry=error 2>err fsck &&
+	test_must_fail git -c fsck.extraHeaderEntry=error 2>err fsck &&
 	grep "error .* extraHeaderEntry:" err
 '
 
-- 
2.30.0.284.gd98b1dd5eaa7


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

* [PATCH 2/4] tests: remove most uses of C_LOCALE_OUTPUT
  2021-01-20 18:27                             ` [PATCH v2 0/3] " Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 0/4] More GETTEXT_POISON removal Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 1/4] tests: remove last uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
@ 2021-02-11  1:53                               ` Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 3/4] tests: remove last " Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 4/4] tests: remove most uses of test_i18ncmp Ævar Arnfjörð Bjarmason
  4 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-02-11  1:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Johannes Schindelin, SZEDER Gábor,
	Jiang Xin, Ævar Arnfjörð Bjarmason

As a follow-up to d162b25f956 (tests: remove support for
GIT_TEST_GETTEXT_POISON, 2021-01-20) remove those uses of the now
always true C_LOCALE_OUTPUT prerequisite from those tests which
declare it as an argument to test_expect_{success,failure}.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0000-basic.sh                    |  2 +-
 t/t0201-gettext-fallbacks.sh        |  2 +-
 t/t1430-bad-ref-name.sh             |  2 +-
 t/t1512-rev-parse-disambiguation.sh | 14 +++++++-------
 t/t3404-rebase-interactive.sh       | 14 +++++++-------
 t/t3415-rebase-autosquash.sh        | 10 +++++-----
 t/t3701-add-interactive.sh          |  2 +-
 t/t4012-diff-binary.sh              |  4 ++--
 t/t4205-log-pretty-formats.sh       |  2 +-
 t/t5300-pack-object.sh              |  4 ++--
 t/t5505-remote.sh                   |  6 +++---
 t/t5510-fetch.sh                    |  4 ++--
 t/t5601-clone.sh                    |  2 +-
 t/t6423-merge-rename-directories.sh |  2 +-
 t/t7300-clean.sh                    |  6 +++---
 t/t7505-prepare-commit-msg-hook.sh  |  4 ++--
 t/t7810-grep.sh                     |  2 +-
 17 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index a6e570d674a..705d62cc27a 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -271,7 +271,7 @@ test_expect_success 'pretend we have a mix of all possible results' '
 	EOF
 '
 
-test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
+test_expect_success 'test --verbose' '
 	run_sub_test_lib_test_err \
 		t1234-verbose "test verbose" --verbose <<-\EOF &&
 	test_expect_success "passing test" true
diff --git a/t/t0201-gettext-fallbacks.sh b/t/t0201-gettext-fallbacks.sh
index 90da1c7ddc4..a7b3e4a2c73 100755
--- a/t/t0201-gettext-fallbacks.sh
+++ b/t/t0201-gettext-fallbacks.sh
@@ -18,7 +18,7 @@ test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_TEST_FALLBACKS is set' '
     test -n "$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS"
 '
 
-test_expect_success C_LOCALE_OUTPUT 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is fallthrough' '
+test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is fallthrough' '
     echo fallthrough >expect &&
     echo $GIT_INTERNAL_GETTEXT_SH_SCHEME >actual &&
     test_cmp expect actual
diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh
index 354902e514f..b1839e08771 100755
--- a/t/t1430-bad-ref-name.sh
+++ b/t/t1430-bad-ref-name.sh
@@ -125,7 +125,7 @@ test_expect_success 'push cannot create a badly named ref' '
 	! grep -e "broken\.\.\.ref" output
 '
 
-test_expect_failure C_LOCALE_OUTPUT 'push --mirror can delete badly named ref' '
+test_expect_failure 'push --mirror can delete badly named ref' '
 	top=$(pwd) &&
 	git init src &&
 	git init dest &&
diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh
index 242abbfa0bc..7891a6becf3 100755
--- a/t/t1512-rev-parse-disambiguation.sh
+++ b/t/t1512-rev-parse-disambiguation.sh
@@ -314,39 +314,39 @@ test_expect_success 'ambiguous short sha1 ref' '
 	grep "refname.*${REF}.*ambiguous" err
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (raw)' '
+test_expect_success 'ambiguity errors are not repeated (raw)' '
 	test_must_fail git rev-parse 00000 2>stderr &&
 	grep "is ambiguous" stderr >errors &&
 	test_line_count = 1 errors
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (treeish)' '
+test_expect_success 'ambiguity errors are not repeated (treeish)' '
 	test_must_fail git rev-parse 00000:foo 2>stderr &&
 	grep "is ambiguous" stderr >errors &&
 	test_line_count = 1 errors
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (peel)' '
+test_expect_success 'ambiguity errors are not repeated (peel)' '
 	test_must_fail git rev-parse 00000^{commit} 2>stderr &&
 	grep "is ambiguous" stderr >errors &&
 	test_line_count = 1 errors
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity hints' '
+test_expect_success 'ambiguity hints' '
 	test_must_fail git rev-parse 000000000 2>stderr &&
 	grep ^hint: stderr >hints &&
 	# 16 candidates, plus one intro line
 	test_line_count = 17 hints
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguity hints respect type' '
+test_expect_success 'ambiguity hints respect type' '
 	test_must_fail git rev-parse 000000000^{commit} 2>stderr &&
 	grep ^hint: stderr >hints &&
 	# 5 commits, 1 tag (which is a committish), plus intro line
 	test_line_count = 7 hints
 '
 
-test_expect_success C_LOCALE_OUTPUT 'failed type-selector still shows hint' '
+test_expect_success 'failed type-selector still shows hint' '
 	# these two blobs share the same prefix "ee3d", but neither
 	# will pass for a commit
 	echo 851 | git hash-object --stdin -w &&
@@ -370,7 +370,7 @@ test_expect_success 'core.disambiguate does not override context' '
 		git -c core.disambiguate=committish rev-parse $sha1^{tree}
 '
 
-test_expect_success C_LOCALE_OUTPUT 'ambiguous commits are printed by type first, then hash order' '
+test_expect_success 'ambiguous commits are printed by type first, then hash order' '
 	test_must_fail git rev-parse 0000 2>stderr &&
 	grep ^hint: stderr >hints &&
 	grep 0000 hints >objects &&
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 1e738df81d5..dc45552b4d6 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -450,7 +450,7 @@ test_expect_success 'verbose flag is heeded, even after --continue' '
 	grep "^ file1 | 2 +-$" output
 '
 
-test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '
+test_expect_success 'multi-squash only fires up editor once' '
 	base=$(git rev-parse HEAD~4) &&
 	(
 		set_fake_editor &&
@@ -463,7 +463,7 @@ test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '
 	test 1 = $(git show | grep ONCE | wc -l)
 '
 
-test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '
+test_expect_success 'multi-fixup does not fire up editor' '
 	git checkout -b multi-fixup E &&
 	base=$(git rev-parse HEAD~4) &&
 	(
@@ -514,7 +514,7 @@ test_expect_success 'commit message retained after conflict' '
 	git branch -D conflict-squash
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messages' '
+test_expect_success 'squash and fixup generate correct log messages' '
 	cat >expect-squash-fixup <<-\EOF &&
 	B
 
@@ -541,7 +541,7 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa
 	git branch -D squash-fixup
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
+test_expect_success 'squash ignores comments' '
 	git checkout -b skip-comments E &&
 	base=$(git rev-parse HEAD~4) &&
 	(
@@ -557,7 +557,7 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
 	git branch -D skip-comments
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '
+test_expect_success 'squash ignores blank lines' '
 	git checkout -b skip-blank-lines E &&
 	base=$(git rev-parse HEAD~4) &&
 	(
@@ -995,7 +995,7 @@ test_expect_success 'rebase -ix with several instances of --exec' '
 	test_cmp expected actual
 '
 
-test_expect_success C_LOCALE_OUTPUT 'rebase -ix with --autosquash' '
+test_expect_success 'rebase -ix with --autosquash' '
 	git reset --hard execute &&
 	git checkout -b autosquash &&
 	echo second >second.txt &&
@@ -1136,7 +1136,7 @@ test_expect_success 'rebase -i --root reword root when root has untracked file c
 	test "$(git rev-list --count HEAD)" = 2
 '
 
-test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' '
+test_expect_success 'rebase --edit-todo does not work on non-interactive rebase' '
 	git checkout reword-original-root-branch &&
 	git reset --hard &&
 	git checkout conflict-branch &&
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 36f169d7f15..908016c2f88 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -306,23 +306,23 @@ test_auto_fixup_fixup () {
 	fi
 }
 
-test_expect_success C_LOCALE_OUTPUT 'fixup! fixup!' '
+test_expect_success 'fixup! fixup!' '
 	test_auto_fixup_fixup fixup fixup
 '
 
-test_expect_success C_LOCALE_OUTPUT 'fixup! squash!' '
+test_expect_success 'fixup! squash!' '
 	test_auto_fixup_fixup fixup squash
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash! squash!' '
+test_expect_success 'squash! squash!' '
 	test_auto_fixup_fixup squash squash
 '
 
-test_expect_success C_LOCALE_OUTPUT 'squash! fixup!' '
+test_expect_success 'squash! fixup!' '
 	test_auto_fixup_fixup squash fixup
 '
 
-test_expect_success C_LOCALE_OUTPUT 'autosquash with custom inst format' '
+test_expect_success 'autosquash with custom inst format' '
 	git reset --hard base &&
 	git config --add rebase.instructionFormat "[%an @ %ar] %s"  &&
 	echo 2 >file1 &&
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index b2f90997dbc..ed00c40370b 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -370,7 +370,7 @@ test_expect_success 'setup expected' '
 '
 
 # Test splitting the first patch, then adding both
-test_expect_success C_LOCALE_OUTPUT 'add first line works' '
+test_expect_success 'add first line works' '
 	git commit -am "clear local changes" &&
 	git apply patch &&
 	printf "%s\n" s y y | git add -p file 2>error |
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index 6579c81216a..bd59328e4b2 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -63,7 +63,7 @@ test_expect_success 'apply --numstat understands diff --binary format' '
 
 # apply needs to be able to skip the binary material correctly
 # in order to report the line number of a corrupt patch.
-test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
+test_expect_success 'apply detecting corrupt patch correctly' '
 	git diff >output &&
 	sed -e "s/-CIT/xCIT/" <output >broken &&
 	test_must_fail git apply --stat --summary broken 2>detected &&
@@ -73,7 +73,7 @@ test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
 	test "$detected" = xCIT
 '
 
-test_expect_success C_LOCALE_OUTPUT 'apply detecting corrupt patch correctly' '
+test_expect_success 'apply detecting corrupt patch correctly' '
 	git diff --binary | sed -e "s/-CIT/xCIT/" >broken &&
 	test_must_fail git apply --stat --summary broken 2>detected &&
 	detected=$(cat detected) &&
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 749bc1431ac..5ec0f47b567 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -126,7 +126,7 @@ test_expect_success 'NUL separation with --stat' '
 	test_i18ncmp expected actual
 '
 
-test_expect_failure C_LOCALE_OUTPUT 'NUL termination with --stat' '
+test_expect_failure 'NUL termination with --stat' '
 	stat0_part=$(git diff --stat HEAD^ HEAD) &&
 	stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
 	printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n0" >expected &&
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index 392201cabdf..d586fdc7a95 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -427,7 +427,7 @@ test_expect_success 'index-pack --strict <pack> works in non-repo' '
 	test_path_is_file foo.idx
 '
 
-test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'index-pack --threads=N or pack.threads=N warns when no pthreads' '
+test_expect_success !PTHREADS 'index-pack --threads=N or pack.threads=N warns when no pthreads' '
 	test_must_fail git index-pack --threads=2 2>err &&
 	grep ^warning: err >warnings &&
 	test_line_count = 1 warnings &&
@@ -445,7 +445,7 @@ test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'index-pack --threads=N or pack.th
 	grep -F "no threads support, ignoring pack.threads" err
 '
 
-test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'pack-objects --threads=N or pack.threads=N warns when no pthreads' '
+test_expect_success !PTHREADS 'pack-objects --threads=N or pack.threads=N warns when no pthreads' '
 	git pack-objects --threads=2 --stdout --all </dev/null >/dev/null 2>err &&
 	grep ^warning: err >warnings &&
 	test_line_count = 1 warnings &&
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 045398b94e6..d3a3bb0a42b 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -59,7 +59,7 @@ test_expect_success 'add remote whose URL agrees with url.<...>.insteadOf' '
 	git remote add myremote git@host.com:team/repo.git
 '
 
-test_expect_success C_LOCALE_OUTPUT 'remote information for the origin' '
+test_expect_success 'remote information for the origin' '
 	(
 		cd test &&
 		tokens_match origin "$(git remote)" &&
@@ -81,7 +81,7 @@ test_expect_success 'add another remote' '
 	)
 '
 
-test_expect_success C_LOCALE_OUTPUT 'check remote-tracking' '
+test_expect_success 'check remote-tracking' '
 	(
 		cd test &&
 		check_remote_track origin main side &&
@@ -107,7 +107,7 @@ test_expect_success 'remove remote' '
 	)
 '
 
-test_expect_success C_LOCALE_OUTPUT 'remove remote' '
+test_expect_success 'remove remote' '
 	(
 		cd test &&
 		tokens_match origin "$(git remote)" &&
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 42f55030047..a37df6d35a7 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -1097,7 +1097,7 @@ test_expect_success 'fetching with auto-gc does not lock up' '
 	)
 '
 
-test_expect_success C_LOCALE_OUTPUT 'fetch aligned output' '
+test_expect_success 'fetch aligned output' '
 	git clone . full-output &&
 	test_commit looooooooooooong-tag &&
 	(
@@ -1112,7 +1112,7 @@ test_expect_success C_LOCALE_OUTPUT 'fetch aligned output' '
 	test_cmp expect actual
 '
 
-test_expect_success C_LOCALE_OUTPUT 'fetch compact output' '
+test_expect_success 'fetch compact output' '
 	git clone . compact &&
 	test_commit extraaa &&
 	(
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 664c9138662..e7e6c089554 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -40,7 +40,7 @@ test_expect_success 'clone with excess parameters (2)' '
 
 '
 
-test_expect_success C_LOCALE_OUTPUT 'output from clone' '
+test_expect_success 'output from clone' '
 	rm -fr dst &&
 	git clone -n "file://$(pwd)/src" dst >output 2>&1 &&
 	test $(grep Clon output | wc -l) = 1
diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh
index 4ab133f489c..5d3b711fe68 100755
--- a/t/t6423-merge-rename-directories.sh
+++ b/t/t6423-merge-rename-directories.sh
@@ -2905,7 +2905,7 @@ test_setup_9e () {
 	)
 }
 
-test_expect_success C_LOCALE_OUTPUT '9e: N-to-1 whammo' '
+test_expect_success '9e: N-to-1 whammo' '
 	test_setup_9e &&
 	(
 		cd 9e &&
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index cb5e34d94c3..a74816ca8b4 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -110,7 +110,7 @@ test_expect_success 'git clean with prefix' '
 
 '
 
-test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' '
+test_expect_success 'git clean with relative prefix' '
 
 	mkdir -p build docs &&
 	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
@@ -123,7 +123,7 @@ test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' '
 	verbose test "$would_clean" = ../src/part3.c
 '
 
-test_expect_success C_LOCALE_OUTPUT 'git clean with absolute path' '
+test_expect_success 'git clean with absolute path' '
 
 	mkdir -p build docs &&
 	touch a.out src/part3.c docs/manual.txt obj.o build/lib.so &&
@@ -407,7 +407,7 @@ test_expect_success 'clean.requireForce and -f' '
 
 '
 
-test_expect_success C_LOCALE_OUTPUT 'core.excludesfile' '
+test_expect_success 'core.excludesfile' '
 
 	echo excludes >excludes &&
 	echo included >included &&
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index 321b4bc0fc6..7a8194ce720 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -218,7 +218,7 @@ test_expect_success 'with hook and editor (merge)' '
 test_rebase () {
 	expect=$1 &&
 	mode=$2 &&
-	test_expect_$expect C_LOCALE_OUTPUT "with hook (rebase ${mode:--i})" '
+	test_expect_$expect "with hook (rebase ${mode:--i})" '
 		test_when_finished "\
 			git rebase --abort
 			git checkout -f main
@@ -307,7 +307,7 @@ test_expect_success 'with failing hook (merge)' '
 
 '
 
-test_expect_success C_LOCALE_OUTPUT 'with failing hook (cherry-pick)' '
+test_expect_success 'with failing hook (cherry-pick)' '
 	test_when_finished "git checkout -f main" &&
 	git checkout -B other b &&
 	test_must_fail git cherry-pick rebase-1 2>actual &&
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 8f7591c9ccd..edfaa9a6d1c 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -969,7 +969,7 @@ do
 	"
 done
 
-test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'grep --threads=N or pack.threads=N warns when no pthreads' '
+test_expect_success !PTHREADS 'grep --threads=N or pack.threads=N warns when no pthreads' '
 	git grep --threads=2 Hello hello_world 2>err &&
 	grep ^warning: err >warnings &&
 	test_line_count = 1 warnings &&
-- 
2.30.0.284.gd98b1dd5eaa7


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

* [PATCH 3/4] tests: remove last uses of C_LOCALE_OUTPUT
  2021-01-20 18:27                             ` [PATCH v2 0/3] " Ævar Arnfjörð Bjarmason
                                                 ` (2 preceding siblings ...)
  2021-02-11  1:53                               ` [PATCH 2/4] tests: remove most uses of C_LOCALE_OUTPUT Ævar Arnfjörð Bjarmason
@ 2021-02-11  1:53                               ` Ævar Arnfjörð Bjarmason
  2021-02-11  1:53                               ` [PATCH 4/4] tests: remove most uses of test_i18ncmp Ævar Arnfjörð Bjarmason
  4 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-02-11  1:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Johannes Schindelin, SZEDER Gábor,
	Jiang Xin, Ævar Arnfjörð Bjarmason

Remove the last uses of the C_LOCALE_OUTPUT prerequisite as well as
the prerequisite itself. This is a follow-up to d162b25f956 (tests:
remove support for GIT_TEST_GETTEXT_POISON, 2021-01-20), as well as
the preceding commit where we removed the simpler uses of
C_LOCALE_OUTPUT.

Here I'm slightly refactoring a test added in 21e5ad50fc5 (safecrlf:
Add mechanism to warn about irreversible crlf conversions,
2008-02-06), as well as getting rid of another "test_have_prereq
C_LOCALE_OUTPUT" use.

I'm not leaving the prerequisite itself in place for in-flight changes
as there currently are none that introduce new tests that rely on it,
and because C_LOCALE_OUTPUT is currently a noop on the master branch
we likely won't have any new submissions that use it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t0020-crlf.sh             | 6 ++----
 t/t9003-help-autocorrect.sh | 7 ++-----
 t/test-lib.sh               | 5 -----
 3 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh
index 375cf943985..f25ae8b5e1f 100755
--- a/t/t0020-crlf.sh
+++ b/t/t0020-crlf.sh
@@ -87,10 +87,8 @@ test_expect_success 'safecrlf: print warning only once' '
 	git commit -m "nowarn" &&
 	for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >doublewarn &&
 	git add doublewarn 2>err &&
-	if test_have_prereq C_LOCALE_OUTPUT
-	then
-		test $(grep "CRLF will be replaced by LF" err | wc -l) = 1
-	fi
+	grep "CRLF will be replaced by LF" err >err.warnings &&
+	test_line_count = 1 err.warnings
 '
 
 
diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh
index 03cd5c54236..f00deaf3815 100755
--- a/t/t9003-help-autocorrect.sh
+++ b/t/t9003-help-autocorrect.sh
@@ -56,11 +56,8 @@ test_expect_success 'autocorrect can be declined altogether' '
 	git config help.autocorrect never &&
 
 	test_must_fail git lfg 2>actual &&
-	if test_have_prereq C_LOCALE_OUTPUT
-	then
-		grep "is not a git command" actual &&
-		test_line_count = 1 actual
-	fi
+	grep "is not a git command" actual &&
+	test_line_count = 1 actual
 '
 
 test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 431adba0fb3..6d188a8075d 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1519,11 +1519,6 @@ test -n "$USE_LIBPCRE2" && test_set_prereq PCRE
 test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
 
-# Used to be used for GIT_TEST_GETTEXT_POISON=false. Only here as a
-# shim for other in-flight changes. Should not be used and will be
-# removed soon.
-test_set_prereq C_LOCALE_OUTPUT
-
 if test -z "$GIT_TEST_CHECK_CACHE_TREE"
 then
 	GIT_TEST_CHECK_CACHE_TREE=true
-- 
2.30.0.284.gd98b1dd5eaa7


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

* [PATCH 4/4] tests: remove most uses of test_i18ncmp
  2021-01-20 18:27                             ` [PATCH v2 0/3] " Ævar Arnfjörð Bjarmason
                                                 ` (3 preceding siblings ...)
  2021-02-11  1:53                               ` [PATCH 3/4] tests: remove last " Ævar Arnfjörð Bjarmason
@ 2021-02-11  1:53                               ` Ævar Arnfjörð Bjarmason
  2021-02-11 17:32                                 ` Junio C Hamano
  2021-04-13 12:19                                 ` [PATCH] tests: remove all uses of test_i18cmp Ævar Arnfjörð Bjarmason
  4 siblings, 2 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-02-11  1:53 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, Johannes Schindelin, SZEDER Gábor,
	Jiang Xin, Ævar Arnfjörð Bjarmason

As a follow-up to d162b25f956 (tests: remove support for
GIT_TEST_GETTEXT_POISON, 2021-01-20) remove most uses of test_i18ncmp
via a simple s/test_i18ncmp/test_cmp/g search-replacement.

I'm leaving t6300-for-each-ref.sh out due to a conflict with in-flight
changes between "master" and "seen", as well as the prerequisite
itself due to other changes between "master" and "next/seen" which add
new test_i18ncmp uses.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/lib-credential.sh                       |   2 +-
 t/lib-log-graph.sh                        |   4 +-
 t/t0006-date.sh                           |   4 +-
 t/t0008-ignores.sh                        |   2 +-
 t/t0012-help.sh                           |   2 +-
 t/t0018-advice.sh                         |   4 +-
 t/t0027-auto-crlf.sh                      |   2 +-
 t/t0040-parse-options.sh                  |   8 +-
 t/t0201-gettext-fallbacks.sh              |  14 +--
 t/t0300-credentials.sh                    |   8 +-
 t/t0500-progress-display.sh               |  22 ++---
 t/t1011-read-tree-sparse-checkout.sh      |   2 +-
 t/t1308-config-set.sh                     |   4 +-
 t/t1400-update-ref.sh                     |   6 +-
 t/t1404-update-ref-errors.sh              |   2 +-
 t/t1450-fsck.sh                           |   6 +-
 t/t1502-rev-parse-parseopt.sh             |  10 +-
 t/t1506-rev-parse-diagnosis.sh            |   2 +-
 t/t1507-rev-parse-upstream.sh             |  10 +-
 t/t1509-root-work-tree.sh                 |   4 +-
 t/t1600-index.sh                          |   6 +-
 t/t2018-checkout-branch.sh                |   2 +-
 t/t2020-checkout-detach.sh                |  20 ++--
 t/t2200-add-update.sh                     |   2 +-
 t/t2401-worktree-prune.sh                 |   4 +-
 t/t2402-worktree-list.sh                  |   2 +-
 t/t3005-ls-files-relative.sh              |   4 +-
 t/t3200-branch.sh                         |  26 ++---
 t/t3201-branch-contains.sh                |   2 +-
 t/t3203-branch-output.sh                  |  28 +++---
 t/t3300-funny-names.sh                    |   2 +-
 t/t3400-rebase.sh                         |   2 +-
 t/t3404-rebase-interactive.sh             |  24 ++---
 t/t3420-rebase-autostash.sh               |   4 +-
 t/t3504-cherry-pick-rerere.sh             |   4 +-
 t/t3507-cherry-pick-conflict.sh           |  12 +--
 t/t3508-cherry-pick-many-commits.sh       |   4 +-
 t/t3510-cherry-pick-sequence.sh           |   8 +-
 t/t3600-rm.sh                             |  16 ++--
 t/t3700-add.sh                            |   8 +-
 t/t3701-add-interactive.sh                |   2 +-
 t/t3903-stash.sh                          |   8 +-
 t/t3905-stash-include-untracked.sh        |   2 +-
 t/t4006-diff-mode.sh                      |   8 +-
 t/t4012-diff-binary.sh                    |   6 +-
 t/t4013-diff-various.sh                   |   2 +-
 t/t4014-format-patch.sh                   |   6 +-
 t/t4016-diff-quote.sh                     |   2 +-
 t/t4030-diff-textconv.sh                  |   2 +-
 t/t4045-diff-relative.sh                  |   2 +-
 t/t4049-diff-stat-count.sh                |   6 +-
 t/t4100-apply-stat.sh                     |   4 +-
 t/t4150-am.sh                             |   2 +-
 t/t4153-am-resume-override-opts.sh        |   2 +-
 t/t4205-log-pretty-formats.sh             |   2 +-
 t/t4254-am-corrupt.sh                     |   2 +-
 t/t5150-request-pull.sh                   |   4 +-
 t/t5316-pack-delta-depth.sh               |   4 +-
 t/t5500-fetch-pack.sh                     |   6 +-
 t/t5505-remote.sh                         |  24 ++---
 t/t5510-fetch.sh                          |   2 +-
 t/t5512-ls-remote.sh                      |   2 +-
 t/t5526-fetch-submodules.sh               |  38 ++++----
 t/t5541-http-push-smart.sh                |   2 +-
 t/t6020-bundle-misc.sh                    |  28 +++---
 t/t6030-bisect-porcelain.sh               |   4 +-
 t/t6040-tracking-info.sh                  |  22 ++---
 t/t6120-describe.sh                       |   2 +-
 t/t6134-pathspec-in-submodule.sh          |   2 +-
 t/t6301-for-each-ref-errors.sh            |  10 +-
 t/t6436-merge-overwrite.sh                |   4 +-
 t/t6439-merge-co-error-msgs.sh            |  12 +--
 t/t7001-mv.sh                             |   2 +-
 t/t7004-tag.sh                            |   8 +-
 t/t7012-skip-worktree-writing.sh          |   4 +-
 t/t7060-wtstatus.sh                       |  14 +--
 t/t7063-status-untracked-cache.sh         |   2 +-
 t/t7102-reset.sh                          |   6 +-
 t/t7400-submodule-basic.sh                |   4 +-
 t/t7401-submodule-summary.sh              |  12 +--
 t/t7406-submodule-update.sh               |  16 ++--
 t/t7407-submodule-foreach.sh              |  10 +-
 t/t7500-commit-template-squash-signoff.sh |   4 +-
 t/t7502-commit-porcelain.sh               |   6 +-
 t/t7508-status.sh                         | 110 +++++++++++-----------
 t/t7512-status-help.sh                    |  74 +++++++--------
 t/t7519-status-fsmonitor.sh               |   4 +-
 t/t7521-ignored-mode.sh                   |  22 ++---
 t/t7600-merge.sh                          |   4 +-
 t/t7602-merge-octopus-many.sh             |   6 +-
 90 files changed, 415 insertions(+), 415 deletions(-)

diff --git a/t/lib-credential.sh b/t/lib-credential.sh
index dea2cbef517..5ea8bc9f1dc 100644
--- a/t/lib-credential.sh
+++ b/t/lib-credential.sh
@@ -20,7 +20,7 @@ check() {
 		false
 	fi &&
 	test_cmp expect-stdout stdout &&
-	test_i18ncmp expect-stderr stderr
+	test_cmp expect-stderr stderr
 }
 
 read_chunk() {
diff --git a/t/lib-log-graph.sh b/t/lib-log-graph.sh
index 1184cceef26..bf952ef9204 100644
--- a/t/lib-log-graph.sh
+++ b/t/lib-log-graph.sh
@@ -12,13 +12,13 @@ sanitize_log_output () {
 lib_test_cmp_graph () {
 	git log --graph "$@" >output &&
 	sed 's/ *$//' >output.sanitized <output &&
-	test_i18ncmp expect output.sanitized
+	test_cmp expect output.sanitized
 }
 
 lib_test_cmp_short_graph () {
 	git log --graph --pretty=short "$@" >output &&
 	sanitize_log_output >output.sanitized <output &&
-	test_i18ncmp expect output.sanitized
+	test_cmp expect output.sanitized
 }
 
 lib_test_cmp_colored_graph () {
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 75ee9a96b80..6b757d71692 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -11,7 +11,7 @@ check_relative() {
 	echo "$t -> $2" >expect
 	test_expect_${3:-success} "relative date ($2)" "
 	test-tool date relative $t >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 	"
 }
 
@@ -139,7 +139,7 @@ check_date_format_human() {
 	echo "$t -> $2" >expect
 	test_expect_success "human date $t" '
 		test-tool date human $t >actual &&
-		test_i18ncmp expect actual
+		test_cmp expect actual
 '
 }
 
diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh
index 370a389e5c5..f7abde62f63 100755
--- a/t/t0008-ignores.sh
+++ b/t/t0008-ignores.sh
@@ -34,7 +34,7 @@ expect_from_stdin () {
 test_stderr () {
 	expected="$1"
 	expect_in stderr "$1" &&
-	test_i18ncmp "$HOME/expected-stderr" "$HOME/stderr"
+	test_cmp "$HOME/expected-stderr" "$HOME/stderr"
 }
 
 broken_c_unquote () {
diff --git a/t/t0012-help.sh b/t/t0012-help.sh
index e8ef7300ecb..5679e29c624 100755
--- a/t/t0012-help.sh
+++ b/t/t0012-help.sh
@@ -55,7 +55,7 @@ test_expect_success "--help does not work for guides" "
 		git: 'revisions' is not a git command. See 'git --help'.
 	EOF
 	test_must_fail git revisions --help 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 "
 
 test_expect_success 'git help' '
diff --git a/t/t0018-advice.sh b/t/t0018-advice.sh
index e03554d2f34..39e5e4b34f8 100755
--- a/t/t0018-advice.sh
+++ b/t/t0018-advice.sh
@@ -10,7 +10,7 @@ test_expect_success 'advice should be printed when config variable is unset' '
 	hint: Disable this message with "git config advice.nestedTag false"
 	EOF
 	test-tool advise "This is a piece of advice" 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'advice should be printed when config variable is set to true' '
@@ -20,7 +20,7 @@ test_expect_success 'advice should be printed when config variable is set to tru
 	EOF
 	test_config advice.nestedTag true &&
 	test-tool advise "This is a piece of advice" 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'advice should not be printed when config variable is set to false' '
diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index 51f74a3ddf3..d24d5acfbc7 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -83,7 +83,7 @@ check_warning () {
 	*) echo >&2 "Illegal 1": "$1" ; return false ;;
 	esac
 	grep "will be replaced by" "$2" | sed -e "s/\(.*\) in [^ ]*$/\1/" | uniq  >"$2".actual
-	test_i18ncmp "$2".expect "$2".actual
+	test_cmp "$2".expect "$2".actual
 }
 
 commit_check_warn () {
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 14cafc138b7..ad4746d899a 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -61,7 +61,7 @@ EOF
 test_expect_success 'test help' '
 	test_must_fail test-tool parse-options -h >output 2>output.err &&
 	test_must_be_empty output.err &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 mv expect expect.err
@@ -84,7 +84,7 @@ check_unknown_i18n() {
 	cat expect.err >>expect &&
 	test_must_fail test-tool parse-options $* >output 2>output.err &&
 	test_must_be_empty output &&
-	test_i18ncmp expect output.err
+	test_cmp expect output.err
 }
 
 test_expect_success 'OPT_BOOL() #1' 'check boolean: 1 --yes'
@@ -250,7 +250,7 @@ EOF
 test_expect_success 'detect possible typos' '
 	test_must_fail test-tool parse-options -boolean >output 2>output.err &&
 	test_must_be_empty output &&
-	test_i18ncmp typo.err output.err
+	test_cmp typo.err output.err
 '
 
 cat >typo.err <<\EOF
@@ -260,7 +260,7 @@ EOF
 test_expect_success 'detect possible typos' '
 	test_must_fail test-tool parse-options -ambiguous >output 2>output.err &&
 	test_must_be_empty output &&
-	test_i18ncmp typo.err output.err
+	test_cmp typo.err output.err
 '
 
 test_expect_success 'keep some options as arguments' '
diff --git a/t/t0201-gettext-fallbacks.sh b/t/t0201-gettext-fallbacks.sh
index a7b3e4a2c73..6c74df0dc67 100755
--- a/t/t0201-gettext-fallbacks.sh
+++ b/t/t0201-gettext-fallbacks.sh
@@ -27,25 +27,25 @@ test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is fallthrough' '
 test_expect_success 'gettext: our gettext() fallback has pass-through semantics' '
     printf "test" >expect &&
     gettext "test" >actual &&
-    test_i18ncmp expect actual &&
+    test_cmp expect actual &&
     printf "test more words" >expect &&
     gettext "test more words" >actual &&
-    test_i18ncmp expect actual
+    test_cmp expect actual
 '
 
 test_expect_success 'eval_gettext: our eval_gettext() fallback has pass-through semantics' '
     printf "test" >expect &&
     eval_gettext "test" >actual &&
-    test_i18ncmp expect actual &&
+    test_cmp expect actual &&
     printf "test more words" >expect &&
     eval_gettext "test more words" >actual &&
-    test_i18ncmp expect actual
+    test_cmp expect actual
 '
 
 test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables' '
     printf "test YesPlease" >expect &&
     GIT_INTERNAL_GETTEXT_TEST_FALLBACKS=YesPlease eval_gettext "test \$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS" >actual &&
-    test_i18ncmp expect actual
+    test_cmp expect actual
 '
 
 test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables with spaces' '
@@ -53,7 +53,7 @@ test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate v
     export cmdline &&
     printf "When you have resolved this problem, run git am --resolved." >expect &&
     eval_gettext "When you have resolved this problem, run \$cmdline --resolved." >actual &&
-    test_i18ncmp expect actual
+    test_cmp expect actual
 '
 
 test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables with spaces and quotes' '
@@ -61,7 +61,7 @@ test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate v
     export cmdline &&
     printf "When you have resolved this problem, run \"git am --resolved\"." >expect &&
     eval_gettext "When you have resolved this problem, run \"\$cmdline --resolved\"." >actual &&
-    test_i18ncmp expect actual
+    test_cmp expect actual
 '
 
 test_done
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
index a18f8a473bf..3485c0534e6 100755
--- a/t/t0300-credentials.sh
+++ b/t/t0300-credentials.sh
@@ -578,7 +578,7 @@ test_expect_success 'helpers can abort the process' '
 	quit: host=example.com
 	fatal: credential helper '\''quit'\'' told us to quit
 	EOF
-	test_i18ncmp expect stderr
+	test_cmp expect stderr
 '
 
 test_expect_success 'empty helper spec resets helper list' '
@@ -606,7 +606,7 @@ test_expect_success 'url parser rejects embedded newlines' '
 	warning: url contains a newline in its path component: https://one.example.com?%0ahost=two.example.com/
 	fatal: credential url cannot be parsed: https://one.example.com?%0ahost=two.example.com/
 	EOF
-	test_i18ncmp expect stderr
+	test_cmp expect stderr
 '
 
 test_expect_success 'host-less URLs are parsed as empty host' '
@@ -633,7 +633,7 @@ test_expect_success 'credential system refuses to work with missing host' '
 	cat >expect <<-\EOF &&
 	fatal: refusing to work with credential missing host field
 	EOF
-	test_i18ncmp expect stderr
+	test_cmp expect stderr
 '
 
 test_expect_success 'credential system refuses to work with missing protocol' '
@@ -643,7 +643,7 @@ test_expect_success 'credential system refuses to work with missing protocol' '
 	cat >expect <<-\EOF &&
 	fatal: refusing to work with credential missing protocol field
 	EOF
-	test_i18ncmp expect stderr
+	test_cmp expect stderr
 '
 
 # usage: check_host_and_path <url> <expected-host> <expected-path>
diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh
index 84cce345e7d..22058b503ac 100755
--- a/t/t0500-progress-display.sh
+++ b/t/t0500-progress-display.sh
@@ -29,7 +29,7 @@ test_expect_success 'simple progress display' '
 	test-tool progress "Working hard" <in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'progress display with total' '
@@ -48,7 +48,7 @@ test_expect_success 'progress display with total' '
 	test-tool progress --total=3 "Working hard" <in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'progress display breaks long lines #1' '
@@ -72,7 +72,7 @@ EOF
 		<in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'progress display breaks long lines #2' '
@@ -100,7 +100,7 @@ EOF
 		<in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'progress display breaks long lines #3 - even the first is too long' '
@@ -126,7 +126,7 @@ EOF
 		<in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'progress display breaks long lines #4 - title line matches terminal width' '
@@ -150,7 +150,7 @@ EOF
 		<in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 # Progress counter goes backwards, this should not happen in practice.
@@ -172,7 +172,7 @@ test_expect_success 'progress shortens - crazy caller' '
 	test-tool progress --total=1000 "Working hard" <in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'progress display with throughput' '
@@ -201,7 +201,7 @@ test_expect_success 'progress display with throughput' '
 	test-tool progress "Working hard" <in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'progress display with throughput and total' '
@@ -226,7 +226,7 @@ test_expect_success 'progress display with throughput and total' '
 	test-tool progress --total=40 "Working hard" <in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'cover up after throughput shortens' '
@@ -255,7 +255,7 @@ test_expect_success 'cover up after throughput shortens' '
 	test-tool progress "Working hard" <in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'cover up after throughput shortens a lot' '
@@ -280,7 +280,7 @@ test_expect_success 'cover up after throughput shortens a lot' '
 	test-tool progress "Working hard" <in 2>stderr &&
 
 	show_cr <stderr >out &&
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'progress generates traces' '
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index dfe9794a740..24092c09a95 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -253,7 +253,7 @@ warning: The following paths were already present and thus not updated despite s
 
 After fixing the above paths, you may want to run `git sparse-checkout reapply`.
 EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'checkout without --ignore-skip-worktree-bits' '
diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index 3a527e3a843..88b119a0a35 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -208,14 +208,14 @@ test_expect_success 'proper error on error in default config files' '
 	echo "[" >>.git/config &&
 	echo "fatal: bad config line 34 in file .git/config" >expect &&
 	test_expect_code 128 test-tool config get_value foo.bar 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'proper error on error in custom config files' '
 	echo "[" >>syntax-error &&
 	echo "fatal: bad config line 1 in file syntax-error" >expect &&
 	test_expect_code 128 test-tool config configset_get_value foo.bar syntax-error 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'check line errors for malformed values' '
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 359d8731c8f..e31f65f381c 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -374,7 +374,7 @@ test_expect_success 'Query "main@{May 25 2005}" (before history)' '
 	echo "$C" >expect &&
 	test_cmp expect o &&
 	echo "warning: log for '\''main'\'' only goes back to $ed" >expect &&
-	test_i18ncmp expect e
+	test_cmp expect e
 '
 test_expect_success 'Query main@{2005-05-25} (before history)' '
 	test_when_finished "rm -f o e" &&
@@ -382,7 +382,7 @@ test_expect_success 'Query main@{2005-05-25} (before history)' '
 	echo "$C" >expect &&
 	test_cmp expect o &&
 	echo "warning: log for '\''main'\'' only goes back to $ed" >expect &&
-	test_i18ncmp expect e
+	test_cmp expect e
 '
 test_expect_success 'Query "main@{May 26 2005 23:31:59}" (1 second before history)' '
 	test_when_finished "rm -f o e" &&
@@ -390,7 +390,7 @@ test_expect_success 'Query "main@{May 26 2005 23:31:59}" (1 second before histor
 	echo "$C" >expect &&
 	test_cmp expect o &&
 	echo "warning: log for '\''main'\'' only goes back to $ed" >expect &&
-	test_i18ncmp expect e
+	test_cmp expect e
 '
 test_expect_success 'Query "main@{May 26 2005 23:32:00}" (exactly history start)' '
 	test_when_finished "rm -f o e" &&
diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh
index 2d142e5535e..8b51c4efc13 100755
--- a/t/t1404-update-ref-errors.sh
+++ b/t/t1404-update-ref-errors.sh
@@ -101,7 +101,7 @@ df_test() {
 		printf "%s\n" "delete $delname" "create $addname $D"
 	fi >commands &&
 	test_must_fail git update-ref --stdin <commands 2>output.err &&
-	test_i18ncmp expected-err output.err &&
+	test_cmp expected-err output.err &&
 	printf "%s\n" "$C $delref" >expected-refs &&
 	git for-each-ref --format="%(objectname) %(refname)" $prefix/r >actual-refs &&
 	test_cmp expected-refs actual-refs
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index a30fc5f74a9..f3241e0e7e2 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -380,7 +380,7 @@ test_expect_success 'tag with incorrect tag name & missing tagger' '
 	warning in tag $tag: badTagName: invalid '\''tag'\'' name: wrong name format
 	warning in tag $tag: missingTaggerEntry: invalid format - expected '\''tagger'\'' line
 	EOF
-	test_i18ncmp expect out
+	test_cmp expect out
 '
 
 test_expect_success 'tag with bad tagger' '
@@ -806,7 +806,7 @@ test_expect_success 'fsck notices dangling objects' '
 		git fsck >actual &&
 		# the output order is non-deterministic, as it comes from a hash
 		sort <actual >actual.sorted &&
-		test_i18ncmp expect actual.sorted
+		test_cmp expect actual.sorted
 	)
 '
 
@@ -816,7 +816,7 @@ test_expect_success 'fsck --connectivity-only notices dangling objects' '
 		git fsck --connectivity-only >actual &&
 		# the output order is non-deterministic, as it comes from a hash
 		sort <actual >actual.sorted &&
-		test_i18ncmp expect actual.sorted
+		test_cmp expect actual.sorted
 	)
 '
 
diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh
index a859abedf58..b29563fc997 100755
--- a/t/t1502-rev-parse-parseopt.sh
+++ b/t/t1502-rev-parse-parseopt.sh
@@ -95,7 +95,7 @@ test_expect_success 'test --parseopt help output' '
 |EOF
 END_EXPECT
 	test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'test --parseopt help output no switches' '
@@ -108,7 +108,7 @@ test_expect_success 'test --parseopt help output no switches' '
 |EOF
 END_EXPECT
 	test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec_no_switches &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'test --parseopt help output hidden switches' '
@@ -121,7 +121,7 @@ test_expect_success 'test --parseopt help output hidden switches' '
 |EOF
 END_EXPECT
 	test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec_only_hidden_switches &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'test --parseopt help-all output hidden switches' '
@@ -136,7 +136,7 @@ test_expect_success 'test --parseopt help-all output hidden switches' '
 |EOF
 END_EXPECT
 	test_expect_code 129 git rev-parse --parseopt -- --help-all > output < optionspec_only_hidden_switches &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'test --parseopt invalid switch help output' '
@@ -176,7 +176,7 @@ test_expect_success 'test --parseopt invalid switch help output' '
 |
 END_EXPECT
 	test_expect_code 129 git rev-parse --parseopt -- --does-not-exist 1>/dev/null 2>output < optionspec &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'setup expect.1' "
diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh
index f6e6f23f7e6..65a154a8a20 100755
--- a/t/t1506-rev-parse-diagnosis.sh
+++ b/t/t1506-rev-parse-diagnosis.sh
@@ -15,7 +15,7 @@ test_did_you_mean ()
 	fatal: path '$2$3' $4, but not ${5:-$SQ$3$SQ}
 	hint: Did you mean '$1:$2$3'${2:+ aka $SQ$1:./$3$SQ}?
 	EOF
-	test_i18ncmp expected error
+	test_cmp expected error
 }
 
 HASH_file=
diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh
index 73b4f34c6ee..c34714ffe3f 100755
--- a/t/t1507-rev-parse-upstream.sh
+++ b/t/t1507-rev-parse-upstream.sh
@@ -172,7 +172,7 @@ test_expect_success 'branch@{u} error message when no upstream' '
 	fatal: no upstream configured for branch ${SQ}non-tracking${SQ}
 	EOF
 	error_message non-tracking@{u} &&
-	test_i18ncmp expect error
+	test_cmp expect error
 '
 
 test_expect_success '@{u} error message when no upstream' '
@@ -180,7 +180,7 @@ test_expect_success '@{u} error message when no upstream' '
 	fatal: no upstream configured for branch ${SQ}main${SQ}
 	EOF
 	test_must_fail git rev-parse --verify @{u} 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'branch@{u} error message with misspelt branch' '
@@ -188,7 +188,7 @@ test_expect_success 'branch@{u} error message with misspelt branch' '
 	fatal: no such branch: ${SQ}no-such-branch${SQ}
 	EOF
 	error_message no-such-branch@{u} &&
-	test_i18ncmp expect error
+	test_cmp expect error
 '
 
 test_expect_success '@{u} error message when not on a branch' '
@@ -197,7 +197,7 @@ test_expect_success '@{u} error message when not on a branch' '
 	EOF
 	git checkout HEAD^0 &&
 	test_must_fail git rev-parse --verify @{u} 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'branch@{u} error message if upstream branch not fetched' '
@@ -205,7 +205,7 @@ test_expect_success 'branch@{u} error message if upstream branch not fetched' '
 	fatal: upstream branch ${SQ}refs/heads/side${SQ} not stored as a remote-tracking branch
 	EOF
 	error_message bad-upstream@{u} &&
-	test_i18ncmp expect error
+	test_cmp expect error
 '
 
 test_expect_success 'pull works when tracking a local branch' '
diff --git a/t/t1509-root-work-tree.sh b/t/t1509-root-work-tree.sh
index fd2f7abf1c1..553a3f601ba 100755
--- a/t/t1509-root-work-tree.sh
+++ b/t/t1509-root-work-tree.sh
@@ -221,7 +221,7 @@ test_expect_success 'setup' '
 	rm -rf /.git &&
 	echo "Initialized empty Git repository in /.git/" > expected &&
 	git init > result &&
-	test_i18ncmp expected result
+	test_cmp expected result
 '
 
 test_vars 'auto gitdir, root' ".git" "/" ""
@@ -246,7 +246,7 @@ test_expect_success 'setup' '
 	cd / &&
 	echo "Initialized empty Git repository in /" > expected &&
 	git init --bare > result &&
-	test_i18ncmp expected result
+	test_cmp expected result
 '
 
 test_vars 'auto gitdir, root' "." "" ""
diff --git a/t/t1600-index.sh b/t/t1600-index.sh
index b7c31aa86a1..c9b9e718b89 100755
--- a/t/t1600-index.sh
+++ b/t/t1600-index.sh
@@ -18,7 +18,7 @@ test_expect_success 'bogus GIT_INDEX_VERSION issues warning' '
 			warning: GIT_INDEX_VERSION set, but the value is invalid.
 			Using version Z
 		EOF
-		test_i18ncmp expect.err actual.err
+		test_cmp expect.err actual.err
 	)
 '
 
@@ -32,7 +32,7 @@ test_expect_success 'out of bounds GIT_INDEX_VERSION issues warning' '
 			warning: GIT_INDEX_VERSION set, but the value is invalid.
 			Using version Z
 		EOF
-		test_i18ncmp expect.err actual.err
+		test_cmp expect.err actual.err
 	)
 '
 
@@ -55,7 +55,7 @@ test_expect_success 'out of bounds index.version issues warning' '
 			warning: index.version set, but the value is invalid.
 			Using version Z
 		EOF
-		test_i18ncmp expect.err actual.err
+		test_cmp expect.err actual.err
 	)
 '
 
diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh
index 5f761bc616e..93be1c0eae5 100755
--- a/t/t2018-checkout-branch.sh
+++ b/t/t2018-checkout-branch.sh
@@ -150,7 +150,7 @@ test_expect_success 'checkout -b to @{-1} fails with the right branch name' '
 	git checkout branch2 &&
 	echo  >expect "fatal: A branch named '\''branch1'\'' already exists." &&
 	test_must_fail git checkout -b @{-1} 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'checkout -B to an existing branch resets branch to HEAD' '
diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh
index b432b6427b6..bc46713a43e 100755
--- a/t/t2020-checkout-detach.sh
+++ b/t/t2020-checkout-detach.sh
@@ -163,7 +163,7 @@ test_expect_success 'tracking count is accurate after orphan check' '
 	git config branch.child.merge refs/heads/main &&
 	git checkout child^ &&
 	git checkout child >stdout &&
-	test_i18ncmp expect stdout
+	test_cmp expect stdout
 '
 
 test_expect_success 'no advice given for explicit detached head state' '
@@ -237,15 +237,15 @@ test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not as
 	sane_unset GIT_PRINT_SHA1_ELLIPSIS &&
 	git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 1st_detach actual &&
+	test_cmp 1st_detach actual &&
 
 	GIT_PRINT_SHA1_ELLIPSIS="no" git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 2nd_detach actual &&
+	test_cmp 2nd_detach actual &&
 
 	GIT_PRINT_SHA1_ELLIPSIS= git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 3rd_detach actual &&
+	test_cmp 3rd_detach actual &&
 
 	sane_unset GIT_PRINT_SHA1_ELLIPSIS &&
 
@@ -256,17 +256,17 @@ test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not as
 	# Make no mention of the env var at all
 	git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 1st_detach actual &&
+	test_cmp 1st_detach actual &&
 
 	GIT_PRINT_SHA1_ELLIPSIS='nope' &&
 	git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 2nd_detach actual &&
+	test_cmp 2nd_detach actual &&
 
 	GIT_PRINT_SHA1_ELLIPSIS=nein &&
 	git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 3rd_detach actual &&
+	test_cmp 3rd_detach actual &&
 
 	true
 "
@@ -319,15 +319,15 @@ test_expect_success 'describe_detached_head does print SHA-1 ellipsis when asked
 
 	GIT_PRINT_SHA1_ELLIPSIS=yes git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 1st_detach actual &&
+	test_cmp 1st_detach actual &&
 
 	GIT_PRINT_SHA1_ELLIPSIS=Yes git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 2nd_detach actual &&
+	test_cmp 2nd_detach actual &&
 
 	GIT_PRINT_SHA1_ELLIPSIS=YES git -c 'core.abbrev=12' checkout HEAD^ >actual 2>&1 &&
 	check_detached &&
-	test_i18ncmp 3rd_detach actual &&
+	test_cmp 3rd_detach actual &&
 
 	true
 "
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index 7cb7a703827..45ca35d60ac 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -135,7 +135,7 @@ test_expect_success 'add -n -u should not add but just report' '
 	after=$(git ls-files -s check top) &&
 
 	test "$before" = "$after" &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 
 '
 
diff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh
index aff877590df..a615d3b4838 100755
--- a/t/t2401-worktree-prune.sh
+++ b/t/t2401-worktree-prune.sh
@@ -23,7 +23,7 @@ test_expect_success 'prune files inside $GIT_DIR/worktrees' '
 	cat >expect <<EOF &&
 Removing worktrees/abc: not a valid directory
 EOF
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 	! test -f .git/worktrees/abc &&
 	! test -d .git/worktrees
 '
@@ -35,7 +35,7 @@ test_expect_success 'prune directories without gitdir' '
 Removing worktrees/def: gitdir file does not exist
 EOF
 	git worktree prune --verbose >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 	! test -d .git/worktrees/def &&
 	! test -d .git/worktrees
 '
diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh
index 42d35d9ae82..fedcefe8de3 100755
--- a/t/t2402-worktree-list.sh
+++ b/t/t2402-worktree-list.sh
@@ -167,7 +167,7 @@ test_expect_success '"list" all worktrees --verbose with prunable' '
 	rm -rf prunable &&
 	git worktree list --verbose >out &&
 	sed -n "s/  */ /g;/\/prunable  *[0-9a-f].*$/,/prunable: .*$/p" <out >actual &&
-	test_i18ncmp actual expect
+	test_cmp actual expect
 '
 
 test_expect_success 'bare repo setup' '
diff --git a/t/t3005-ls-files-relative.sh b/t/t3005-ls-files-relative.sh
index 2ec69a8a266..727e9ae1a44 100755
--- a/t/t3005-ls-files-relative.sh
+++ b/t/t3005-ls-files-relative.sh
@@ -46,7 +46,7 @@ test_expect_success 'ls-files -c' '
 		ls ../x* >expect.out &&
 		test_must_fail git ls-files -c --error-unmatch ../[xy]* >actual.out 2>actual.err &&
 		test_cmp expect.out actual.out &&
-		test_i18ncmp expect.err actual.err
+		test_cmp expect.err actual.err
 	)
 '
 
@@ -61,7 +61,7 @@ test_expect_success 'ls-files -o' '
 		ls ../y* >expect.out &&
 		test_must_fail git ls-files -o --error-unmatch ../[xy]* >actual.out 2>actual.err &&
 		test_cmp expect.out actual.out &&
-		test_i18ncmp expect.err actual.err
+		test_cmp expect.err actual.err
 	)
 '
 
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 00761e40801..cc4b10236e2 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -695,7 +695,7 @@ test_expect_success 'deleting a symref' '
 	git branch -d symref >actual &&
 	test_path_is_file .git/refs/heads/target &&
 	test_path_is_missing .git/refs/heads/symref &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'deleting a dangling symref' '
@@ -704,7 +704,7 @@ test_expect_success 'deleting a dangling symref' '
 	echo "Deleted branch dangling-symref (was nowhere)." >expect &&
 	git branch -d dangling-symref >actual &&
 	test_path_is_missing .git/refs/heads/dangling-symref &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'deleting a self-referential symref' '
@@ -713,7 +713,7 @@ test_expect_success 'deleting a self-referential symref' '
 	echo "Deleted branch self-reference (was refs/heads/self-reference)." >expect &&
 	git branch -d self-reference >actual &&
 	test_path_is_missing .git/refs/heads/self-reference &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'renaming a symref is not allowed' '
@@ -808,7 +808,7 @@ test_expect_success 'test deleting branch without config' '
 	sha1=$(git rev-parse my7 | cut -c 1-7) &&
 	echo "Deleted branch my7 (was $sha1)." >expect &&
 	git branch -d my7 >actual 2>&1 &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'deleting currently checked out branch fails' '
@@ -843,7 +843,7 @@ test_expect_success 'branch from tag w/--track causes failure' '
 test_expect_success '--set-upstream-to fails on multiple branches' '
 	echo "fatal: too many arguments to set new upstream" >expect &&
 	test_must_fail git branch --set-upstream-to main a b c 2>err &&
-	test_i18ncmp expect err
+	test_cmp expect err
 '
 
 test_expect_success '--set-upstream-to fails on detached HEAD' '
@@ -851,13 +851,13 @@ test_expect_success '--set-upstream-to fails on detached HEAD' '
 	test_when_finished git checkout - &&
 	echo "fatal: could not set upstream of HEAD to main when it does not point to any branch." >expect &&
 	test_must_fail git branch --set-upstream-to main 2>err &&
-	test_i18ncmp expect err
+	test_cmp expect err
 '
 
 test_expect_success '--set-upstream-to fails on a missing dst branch' '
 	echo "fatal: branch '"'"'does-not-exist'"'"' does not exist" >expect &&
 	test_must_fail git branch --set-upstream-to main does-not-exist 2>err &&
-	test_i18ncmp expect err
+	test_cmp expect err
 '
 
 test_expect_success '--set-upstream-to fails on a missing src branch' '
@@ -868,7 +868,7 @@ test_expect_success '--set-upstream-to fails on a missing src branch' '
 test_expect_success '--set-upstream-to fails on a non-ref' '
 	echo "fatal: Cannot setup tracking information; starting point '"'"'HEAD^{}'"'"' is not a branch." >expect &&
 	test_must_fail git branch --set-upstream-to HEAD^{} 2>err &&
-	test_i18ncmp expect err
+	test_cmp expect err
 '
 
 test_expect_success '--set-upstream-to fails on locked config' '
@@ -899,7 +899,7 @@ test_expect_success 'use --set-upstream-to modify a particular branch' '
 test_expect_success '--unset-upstream should fail if given a non-existent branch' '
 	echo "fatal: Branch '"'"'i-dont-exist'"'"' has no upstream information" >expect &&
 	test_must_fail git branch --unset-upstream i-dont-exist 2>err &&
-	test_i18ncmp expect err
+	test_cmp expect err
 '
 
 test_expect_success '--unset-upstream should fail if config is locked' '
@@ -921,13 +921,13 @@ test_expect_success 'test --unset-upstream on HEAD' '
 	# fail for a branch without upstream set
 	echo "fatal: Branch '"'"'main'"'"' has no upstream information" >expect &&
 	test_must_fail git branch --unset-upstream 2>err &&
-	test_i18ncmp expect err
+	test_cmp expect err
 '
 
 test_expect_success '--unset-upstream should fail on multiple branches' '
 	echo "fatal: too many arguments to unset upstream" >expect &&
 	test_must_fail git branch --unset-upstream a b c 2>err &&
-	test_i18ncmp expect err
+	test_cmp expect err
 '
 
 test_expect_success '--unset-upstream should fail on detached HEAD' '
@@ -935,7 +935,7 @@ test_expect_success '--unset-upstream should fail on detached HEAD' '
 	test_when_finished git checkout - &&
 	echo "fatal: could not unset upstream of HEAD when it does not point to any branch." >expect &&
 	test_must_fail git branch --unset-upstream 2>err &&
-	test_i18ncmp expect err
+	test_cmp expect err
 '
 
 test_expect_success 'test --unset-upstream on a particular branch' '
@@ -957,7 +957,7 @@ test_expect_success '--set-upstream-to notices an error to set branch as own ups
 	EOF
 	test_expect_code 1 git config branch.my13.remote &&
 	test_expect_code 1 git config branch.my13.merge &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 # Keep this test last, as it changes the current branch
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 578b5f48255..349a810cee1 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -264,7 +264,7 @@ test_expect_success 'branch --merged with --verbose' '
 	* topic $(git rev-parse --short topic ) [ahead 1] foo
 	  zzz   $(git rev-parse --short zzz   ) second on main
 	EOF
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
index b6fcd017afe..5325b9f67a0 100755
--- a/t/t3203-branch-output.sh
+++ b/t/t3203-branch-output.sh
@@ -160,7 +160,7 @@ test_expect_success 'git branch shows detached HEAD properly' '
 EOF
 	git checkout HEAD^0 &&
 	git branch >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git branch shows detached HEAD properly after checkout --detach' '
@@ -173,7 +173,7 @@ test_expect_success 'git branch shows detached HEAD properly after checkout --de
 EOF
 	git checkout --detach &&
 	git branch >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git branch shows detached HEAD properly after moving' '
@@ -185,7 +185,7 @@ test_expect_success 'git branch shows detached HEAD properly after moving' '
 EOF
 	git reset --hard HEAD^1 &&
 	git branch >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git branch shows detached HEAD properly from tag' '
@@ -198,7 +198,7 @@ EOF
 	git tag fromtag main &&
 	git checkout fromtag &&
 	git branch >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git branch shows detached HEAD properly after moving from tag' '
@@ -210,7 +210,7 @@ test_expect_success 'git branch shows detached HEAD properly after moving from t
 EOF
 	git reset --hard HEAD^1 &&
 	git branch >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git branch `--sort=[-]objectsize` option' '
@@ -221,7 +221,7 @@ test_expect_success 'git branch `--sort=[-]objectsize` option' '
 	  main
 	EOF
 	git branch --sort=objectsize >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	cat >expect <<-\EOF &&
 	* (HEAD detached from fromtag)
@@ -230,7 +230,7 @@ test_expect_success 'git branch `--sort=[-]objectsize` option' '
 	  branch-two
 	EOF
 	git branch --sort=-objectsize >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git branch `--sort=[-]type` option' '
@@ -241,7 +241,7 @@ test_expect_success 'git branch `--sort=[-]type` option' '
 	  main
 	EOF
 	git branch --sort=type >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	cat >expect <<-\EOF &&
 	* (HEAD detached from fromtag)
@@ -250,7 +250,7 @@ test_expect_success 'git branch `--sort=[-]type` option' '
 	  main
 	EOF
 	git branch --sort=-type >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git branch `--sort=[-]version:refname` option' '
@@ -261,7 +261,7 @@ test_expect_success 'git branch `--sort=[-]version:refname` option' '
 	  main
 	EOF
 	git branch --sort=version:refname >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	cat >expect <<-\EOF &&
 	* (HEAD detached from fromtag)
@@ -270,7 +270,7 @@ test_expect_success 'git branch `--sort=[-]version:refname` option' '
 	  branch-one
 	EOF
 	git branch --sort=-version:refname >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git branch --points-at option' '
@@ -337,7 +337,7 @@ test_expect_success 'git branch --format option' '
 	Refname is refs/heads/ref-to-remote
 	EOF
 	git branch --format="Refname is %(refname)" >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'worktree colors correct' '
@@ -355,7 +355,7 @@ test_expect_success 'worktree colors correct' '
 	rm -r worktree_dir &&
 	git worktree prune &&
 	test_decode_color <actual.raw >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success "set up color tests" '
@@ -398,7 +398,7 @@ test_expect_success 'verbose output lists worktree path' '
 	git branch -vv >actual &&
 	rm -r worktree_dir &&
 	git worktree prune &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh
index 04de03cad0a..f5bf16abcd8 100755
--- a/t/t3300-funny-names.sh
+++ b/t/t3300-funny-names.sh
@@ -181,7 +181,7 @@ test_expect_success 'diffstat for rename quotes funny filename' '
 	git diff-index -M -p $t0 >diff &&
 	git apply --stat <diff >diffstat &&
 	sed -e "s/|.*//" -e "s/ *\$//" <diffstat >current &&
-	test_i18ncmp expected current
+	test_cmp expected current
 '
 
 test_expect_success 'numstat for rename quotes funny filename' '
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 5e88a10f8d7..587b408063a 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -113,7 +113,7 @@ test_expect_success 'rebase off of the previous branch using "-"' '
 	test_cmp expect.forkpoint actual.forkpoint &&
 	# the next one is dubious---we may want to say "-",
 	# instead of @{-1}, in the message
-	test_i18ncmp expect.messages actual.messages
+	test_cmp expect.messages actual.messages
 '
 
 test_expect_success 'rebase a single mode change' '
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index dc45552b4d6..b0431782230 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -86,7 +86,7 @@ test_expect_success 'rebase -i with empty todo list' '
 			git rebase -i HEAD^ >output 2>&1
 	) &&
 	tail -n 1 output >actual &&  # Ignore output about changing todo list
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'rebase -i with the exec command' '
@@ -158,9 +158,9 @@ test_expect_success 'rebase -x with empty command fails' '
 	test_when_finished "git rebase --abort ||:" &&
 	test_must_fail env git rebase -x "" @ 2>actual &&
 	test_write_lines "error: empty exec command" >expected &&
-	test_i18ncmp expected actual &&
+	test_cmp expected actual &&
 	test_must_fail env git rebase -x " " @ 2>actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'rebase -x with newline in command fails' '
@@ -168,7 +168,7 @@ test_expect_success 'rebase -x with newline in command fails' '
 	test_must_fail env git rebase -x "a${LF}b" @ 2>actual &&
 	test_write_lines "error: exec commands cannot contain newlines" \
 			 >expected &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'rebase -i with exec of inexistent command' '
@@ -1465,7 +1465,7 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = warn' '
 		FAKE_LINES="1 2 3 4" git rebase -i --root 2>actual.2
 	) &&
 	head -n4 actual.2 >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 	test D = $(git cat-file commit HEAD | sed -ne \$p)
 '
 
@@ -1489,7 +1489,7 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' '
 		set_fake_editor &&
 		test_must_fail env FAKE_LINES="1 2 4" \
 			git rebase -i --root 2>actual &&
-		test_i18ncmp expect actual &&
+		test_cmp expect actual &&
 		cp .git/rebase-merge/git-rebase-todo.backup \
 			.git/rebase-merge/git-rebase-todo &&
 		FAKE_LINES="1 2 drop 3 4 drop 5" git rebase --edit-todo
@@ -1535,11 +1535,11 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = wa
 		cp .git/rebase-merge/git-rebase-todo.backup orig &&
 		FAKE_LINES="2 3 4" git rebase --edit-todo 2>actual.2 &&
 		head -n6 actual.2 >actual &&
-		test_i18ncmp expect actual &&
+		test_cmp expect actual &&
 		cp orig .git/rebase-merge/git-rebase-todo &&
 		FAKE_LINES="1 2 3 4" git rebase --edit-todo 2>actual.2 &&
 		head -n4 actual.2 >actual &&
-		test_i18ncmp expect.3 actual &&
+		test_cmp expect.3 actual &&
 		git rebase --continue 2>actual
 	) &&
 	test D = $(git cat-file commit HEAD | sed -ne \$p) &&
@@ -1575,16 +1575,16 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = er
 		cp .git/rebase-merge/git-rebase-todo.backup orig &&
 		test_must_fail env FAKE_LINES="2 3 4" \
 			git rebase --edit-todo 2>actual &&
-		test_i18ncmp expect actual &&
+		test_cmp expect actual &&
 		test_must_fail git rebase --continue 2>actual &&
-		test_i18ncmp expect.2 actual &&
+		test_cmp expect.2 actual &&
 		test_must_fail git rebase --edit-todo &&
 		cp orig .git/rebase-merge/git-rebase-todo &&
 		test_must_fail env FAKE_LINES="1 2 3 4" \
 			git rebase --edit-todo 2>actual &&
-		test_i18ncmp expect.3 actual &&
+		test_cmp expect.3 actual &&
 		test_must_fail git rebase --continue 2>actual &&
-		test_i18ncmp expect.3 actual &&
+		test_cmp expect.3 actual &&
 		cp orig .git/rebase-merge/git-rebase-todo &&
 		FAKE_LINES="1 2 3 4 drop 5" git rebase --edit-todo &&
 		git rebase --continue 2>actual
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index 4caa014c71c..43fcb68f27e 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -110,7 +110,7 @@ testrebase () {
 		fi &&
 		create_expected_success_$suffix &&
 		sed "$remove_progress_re" <actual >actual2 &&
-		test_i18ncmp expected actual2
+		test_cmp expected actual2
 	'
 
 	test_expect_success "rebase$type: dirty index, non-conflicting rebase" '
@@ -231,7 +231,7 @@ testrebase () {
 		fi &&
 		create_expected_failure_$suffix &&
 		sed "$remove_progress_re" <actual >actual2 &&
-		test_i18ncmp expected actual2
+		test_cmp expected actual2
 	'
 }
 
diff --git a/t/t3504-cherry-pick-rerere.sh b/t/t3504-cherry-pick-rerere.sh
index 9198535874c..4581ae98b87 100755
--- a/t/t3504-cherry-pick-rerere.sh
+++ b/t/t3504-cherry-pick-rerere.sh
@@ -74,10 +74,10 @@ test_expect_success 'cherry-pick --continue rejects --rerere-autoupdate' '
 	git diff-files --quiet &&
 	test_must_fail git cherry-pick --continue --rerere-autoupdate >actual 2>&1 &&
 	echo "fatal: cherry-pick: --rerere-autoupdate cannot be used with --continue" >expect &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 	test_must_fail git cherry-pick --continue --no-rerere-autoupdate >actual 2>&1 &&
 	echo "fatal: cherry-pick: --no-rerere-autoupdate cannot be used with --continue" >expect &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 	git cherry-pick --abort
 '
 
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 5f4564c8306..014001b8f32 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -59,7 +59,7 @@ test_expect_success 'advice from failed cherry-pick' "
 	EOF
 	test_must_fail git cherry-pick picked 2>actual &&
 
-	test_i18ncmp expected actual
+	test_cmp expected actual
 "
 
 test_expect_success 'advice from failed cherry-pick --no-commit' "
@@ -73,7 +73,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' "
 	EOF
 	test_must_fail git cherry-pick --no-commit picked 2>actual &&
 
-	test_i18ncmp expected actual
+	test_cmp expected actual
 "
 
 test_expect_success 'failed cherry-pick sets CHERRY_PICK_HEAD' '
@@ -256,7 +256,7 @@ test_expect_success \
 
 	test_must_fail git cherry-pick picked &&
 
-	test_i18ncmp expected .git/MERGE_MSG
+	test_cmp expected .git/MERGE_MSG
 '
 
 test_expect_success \
@@ -276,7 +276,7 @@ test_expect_success \
 
 	test_must_fail git cherry-pick --cleanup=scissors picked &&
 
-	test_i18ncmp expected .git/MERGE_MSG
+	test_cmp expected .git/MERGE_MSG
 '
 
 test_expect_success 'failed cherry-pick describes conflict in work tree' '
@@ -465,7 +465,7 @@ test_expect_success \
 	test_must_fail git revert picked &&
 
 	sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success \
@@ -488,7 +488,7 @@ test_expect_success \
 	test_must_fail git revert --cleanup=scissors picked &&
 
 	sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'failed cherry-pick does not forget -s' '
diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh
index ec7a2c9fcfa..e8375d1c970 100755
--- a/t/t3508-cherry-pick-many-commits.sh
+++ b/t/t3508-cherry-pick-many-commits.sh
@@ -86,7 +86,7 @@ test_expect_success 'output to keep user entertained during multi-pick' '
 	git cherry-pick first..fourth >actual &&
 	sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy &&
 	test_line_count -ge 3 actual.fuzzy &&
-	test_i18ncmp expected actual.fuzzy
+	test_cmp expected actual.fuzzy
 '
 
 test_expect_success 'cherry-pick --strategy resolve first..fourth works' '
@@ -123,7 +123,7 @@ test_expect_success 'output during multi-pick indicates merge strategy' '
 	test_tick &&
 	git cherry-pick --strategy resolve first..fourth >actual &&
 	sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy &&
-	test_i18ncmp expected actual.fuzzy
+	test_cmp expected actual.fuzzy
 '
 
 test_expect_success 'cherry-pick --ff first..fourth works' '
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index 5b94fdaa671..b76cb6de91d 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -170,7 +170,7 @@ test_expect_success 'check advice when we move HEAD by committing' '
 	git commit -a &&
 	test_path_is_missing .git/CHERRY_PICK_HEAD &&
 	test_must_fail git cherry-pick --skip 2>advice &&
-	test_i18ncmp expect advice
+	test_cmp expect advice
 '
 
 test_expect_success 'selectively advise --skip while launching another sequence' '
@@ -182,7 +182,7 @@ test_expect_success 'selectively advise --skip while launching another sequence'
 	EOF
 	test_must_fail git cherry-pick picked..yetanotherpick &&
 	test_must_fail git cherry-pick picked..yetanotherpick 2>advice &&
-	test_i18ncmp expect advice &&
+	test_cmp expect advice &&
 	cat >expect <<-EOF &&
 	error: cherry-pick is already in progress
 	hint: try "git cherry-pick (--continue | --abort | --quit)"
@@ -190,7 +190,7 @@ test_expect_success 'selectively advise --skip while launching another sequence'
 	EOF
 	git reset --merge &&
 	test_must_fail git cherry-pick picked..yetanotherpick 2>advice &&
-	test_i18ncmp expect advice
+	test_cmp expect advice
 '
 
 test_expect_success 'allow skipping commit but not abort for a new history' '
@@ -204,7 +204,7 @@ test_expect_success 'allow skipping commit but not abort for a new history' '
 	test_must_fail git cherry-pick anotherpick &&
 	test_must_fail git cherry-pick --abort 2>advice &&
 	git cherry-pick --skip &&
-	test_i18ncmp expect advice
+	test_cmp expect advice
 '
 
 test_expect_success 'allow skipping stopped cherry-pick because of untracked file modifications' '
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index dff12286699..857b145cc25 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -442,7 +442,7 @@ test_expect_success 'rm issues a warning when section is not found in .gitmodule
 	git add .gitmodules &&
 	echo "warning: Could not find section in .gitmodules where path=submod" >expect.err &&
 	git rm submod >actual 2>actual.err &&
-	test_i18ncmp expect.err actual.err &&
+	test_cmp expect.err actual.err &&
 	test_path_is_missing submod &&
 	test_path_is_missing submod/.git &&
 	git status -s -uno >actual &&
@@ -812,7 +812,7 @@ test_expect_success 'rm files with different staged content' '
 	echo content1 >foo.txt &&
 	echo content1 >bar.txt &&
 	test_must_fail git rm foo.txt bar.txt 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'rm files with different staged content without hints' '
@@ -825,7 +825,7 @@ test_expect_success 'rm files with different staged content without hints' '
 	echo content2 >foo.txt &&
 	echo content2 >bar.txt &&
 	test_must_fail git -c advice.rmhints=false rm foo.txt bar.txt 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'rm file with local modification' '
@@ -837,7 +837,7 @@ test_expect_success 'rm file with local modification' '
 	git commit -m "testing rm 3" &&
 	echo content3 >foo.txt &&
 	test_must_fail git rm foo.txt 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'rm file with local modification without hints' '
@@ -847,7 +847,7 @@ test_expect_success 'rm file with local modification without hints' '
 	EOF
 	echo content4 >bar.txt &&
 	test_must_fail git -c advice.rmhints=false rm bar.txt 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'rm file with changes in the index' '
@@ -860,7 +860,7 @@ test_expect_success 'rm file with changes in the index' '
 	echo content5 >foo.txt &&
 	git add foo.txt &&
 	test_must_fail git rm foo.txt 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'rm file with changes in the index without hints' '
@@ -869,7 +869,7 @@ test_expect_success 'rm file with changes in the index without hints' '
 	    foo.txt
 	EOF
 	test_must_fail git -c advice.rmhints=false rm foo.txt 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'rm files with two different errors' '
@@ -888,7 +888,7 @@ test_expect_success 'rm files with two different errors' '
 	echo content6 >bar1.txt &&
 	git add bar1.txt &&
 	test_must_fail git rm bar1.txt foo1.txt 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'rm empty string should fail' '
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index b7d4ba608cb..dda84004f96 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -304,7 +304,7 @@ test_expect_success 'error on a repository with no commits' '
 	error: '"'empty/'"' does not have a commit checked out
 	fatal: adding files failed
 	EOF
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'git add --dry-run of existing changed file' "
@@ -320,7 +320,7 @@ test_expect_success 'git add --dry-run of non-existing file' "
 
 test_expect_success 'git add --dry-run of an existing file output' "
 	echo \"fatal: pathspec 'ignored-file' did not match any files\" >expect &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 "
 
 cat >expect.err <<\EOF
@@ -339,8 +339,8 @@ test_expect_success 'git add --dry-run --ignore-missing of non-existing file' '
 '
 
 test_expect_success 'git add --dry-run --ignore-missing of non-existing file output' '
-	test_i18ncmp expect.out actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.out actual.out &&
+	test_cmp expect.err actual.err
 '
 
 test_expect_success 'git add empty string should fail' '
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index ed00c40370b..207714655f2 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -974,7 +974,7 @@ test_expect_success 'show help from add--helper' '
 	EOF
 	test_write_lines h | force_color git add -i >actual.colored &&
 	test_decode_color <actual.colored >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 84b039e5739..5f282ecf617 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -564,7 +564,7 @@ test_expect_success 'stash show format defaults to --stat' '
 	 1 file changed, 1 insertion(+)
 	EOF
 	git stash show ${STASH_ID} >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'stash show - stashes on stack, stash-like argument' '
@@ -792,7 +792,7 @@ test_expect_success 'apply: show same status as git status (relative to ./)' '
 		git stash apply
 	) |
 	sed -e 1d >actual && # drop "Saved..."
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<EOF
@@ -1114,7 +1114,7 @@ test_expect_success 'stash push -p with pathspec shows no changes only once' '
 	git stash push -p foo >actual &&
 	echo "No local changes to save" >expect &&
 	git reset --hard HEAD~ &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'push <pathspec>: show no changes when there are none' '
@@ -1124,7 +1124,7 @@ test_expect_success 'push <pathspec>: show no changes when there are none' '
 	git stash push foo >actual &&
 	echo "No local changes to save" >expect &&
 	git reset --hard HEAD~ &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'push: <pathspec> not in the repository errors out' '
diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh
index f075c7f1f31..3d8b6b491f0 100755
--- a/t/t3905-stash-include-untracked.sh
+++ b/t/t3905-stash-include-untracked.sh
@@ -280,7 +280,7 @@ test_expect_success 'stash -u -- <ignored> leaves ignored file alone' '
 test_expect_success 'stash -u -- <non-existent> shows no changes when there are none' '
 	git stash push -u -- non-existent >actual &&
 	echo "No local changes to save" >expect &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'stash -u with globs' '
diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh
index 03489aff14e..275ce5fa15b 100755
--- a/t/t4006-diff-mode.sh
+++ b/t/t4006-diff-mode.sh
@@ -39,13 +39,13 @@ test_expect_success '--stat output after text chmod' '
 	 1 file changed, 0 insertions(+), 0 deletions(-)
 	EOF
 	git diff HEAD --stat >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success '--shortstat output after text chmod' '
 	tail -n 1 <expect >expect.short &&
 	git diff HEAD --shortstat >actual &&
-	test_i18ncmp expect.short actual
+	test_cmp expect.short actual
 '
 
 test_expect_success '--stat output after binary chmod' '
@@ -56,13 +56,13 @@ test_expect_success '--stat output after binary chmod' '
 	 2 files changed, 0 insertions(+), 0 deletions(-)
 	EOF
 	git diff HEAD --stat >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success '--shortstat output after binary chmod' '
 	tail -n 1 <expect >expect.short &&
 	git diff HEAD --shortstat >actual &&
-	test_i18ncmp expect.short actual
+	test_cmp expect.short actual
 '
 
 test_done
diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh
index bd59328e4b2..33ff588ebca 100755
--- a/t/t4012-diff-binary.sh
+++ b/t/t4012-diff-binary.sh
@@ -34,19 +34,19 @@ EOF
 test_expect_success 'apply --stat output for binary file change' '
 	git diff >diff &&
 	git apply --stat --summary <diff >current &&
-	test_i18ncmp expected current
+	test_cmp expected current
 '
 
 test_expect_success 'diff --shortstat output for binary file change' '
 	tail -n 1 expected >expect &&
 	git diff --shortstat >current &&
-	test_i18ncmp expect current
+	test_cmp expect current
 '
 
 test_expect_success 'diff --shortstat output for binary file change only' '
 	echo " 1 file changed, 0 insertions(+), 0 deletions(-)" >expected &&
 	git diff --shortstat -- b >current &&
-	test_i18ncmp expected current
+	test_cmp expected current
 '
 
 test_expect_success 'apply --numstat notices binary file change' '
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index ce6aa3914fe..47d4df08f9e 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -222,7 +222,7 @@ do
 			process_diffs "$expect" >expect &&
 			case $cmd in
 			*format-patch* | *-stat*)
-				test_i18ncmp expect actual;;
+				test_cmp expect actual;;
 			*)
 				test_cmp expect actual;;
 			esac &&
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 66630c8413d..cdd3154e702 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -888,11 +888,11 @@ echo "fatal: --check does not make sense" >expect.check
 
 test_expect_success 'options no longer allowed for format-patch' '
 	test_must_fail git format-patch --name-only 2>output &&
-	test_i18ncmp expect.name-only output &&
+	test_cmp expect.name-only output &&
 	test_must_fail git format-patch --name-status 2>output &&
-	test_i18ncmp expect.name-status output &&
+	test_cmp expect.name-status output &&
 	test_must_fail git format-patch --check 2>output &&
-	test_i18ncmp expect.check output
+	test_cmp expect.check output
 '
 
 test_expect_success 'format-patch --numstat should produce a patch' '
diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh
index 9c48e5c2c99..876271d6826 100755
--- a/t/t4016-diff-quote.sh
+++ b/t/t4016-diff-quote.sh
@@ -82,7 +82,7 @@ test_expect_success 'git diff --stat -M HEAD' '
 	 7 files changed, 0 insertions(+), 0 deletions(-)
 	EOF
 	git diff --stat -M HEAD >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index 4cb9f0e523d..c906320b60d 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -139,7 +139,7 @@ EOF
 test_expect_success 'diffstat does not run textconv' '
 	echo file diff=fail >.gitattributes &&
 	git diff --stat HEAD^ HEAD >actual &&
-	test_i18ncmp expect.stat actual &&
+	test_cmp expect.stat actual &&
 
 	head -n1 <expect.stat >expect.line1 &&
 	head -n1 <actual >actual.line1 &&
diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh
index 7be1de736d8..61ba5f707fb 100755
--- a/t/t4045-diff-relative.sh
+++ b/t/t4045-diff-relative.sh
@@ -61,7 +61,7 @@ check_stat () {
 	EOF
 	test_expect_success "--stat $*" "
 		git -C '$dir' diff --stat $* HEAD^ >actual &&
-		test_i18ncmp expected actual
+		test_cmp expected actual
 	"
 }
 
diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh
index a34121740a4..53061b104ec 100755
--- a/t/t4049-diff-stat-count.sh
+++ b/t/t4049-diff-stat-count.sh
@@ -25,7 +25,7 @@ test_expect_success 'mode-only change show as a 0-line change' '
 	 4 files changed, 2 insertions(+)
 	EOF
 	git diff --stat --stat-count=2 HEAD >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'binary changes do not count in lines' '
@@ -40,7 +40,7 @@ test_expect_success 'binary changes do not count in lines' '
 	 3 files changed, 2 insertions(+)
 	EOF
 	git diff --stat --stat-count=2 >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'exclude unmerged entries from total file count' '
@@ -62,7 +62,7 @@ test_expect_success 'exclude unmerged entries from total file count' '
 	 3 files changed, 3 insertions(+)
 	EOF
 	git diff --stat --stat-count=2 >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh
index 744b8e51bea..9b433de8363 100755
--- a/t/t4100-apply-stat.sh
+++ b/t/t4100-apply-stat.sh
@@ -17,13 +17,13 @@ do
 	test_expect_success "$title" '
 		git apply --stat --summary \
 			<"$TEST_DIRECTORY/t4100/t-apply-$num.patch" >current &&
-		test_i18ncmp "$TEST_DIRECTORY"/t4100/t-apply-$num.expect current
+		test_cmp "$TEST_DIRECTORY"/t4100/t-apply-$num.expect current
 	'
 
 	test_expect_success "$title with recount" '
 		sed -e "$UNC" <"$TEST_DIRECTORY/t4100/t-apply-$num.patch" |
 		git apply --recount --stat --summary >current &&
-		test_i18ncmp "$TEST_DIRECTORY"/t4100/t-apply-$num.expect current
+		test_cmp "$TEST_DIRECTORY"/t4100/t-apply-$num.expect current
 	'
 done <<\EOF
 rename
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 99987515dc2..2aaaa0d7ded 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -906,7 +906,7 @@ test_expect_success 'am empty-file does not infloop' '
 	test_tick &&
 	test_must_fail git am empty-file 2>actual &&
 	echo Patch format detection failed. >expected &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'am --message-id really adds the message id' '
diff --git a/t/t4153-am-resume-override-opts.sh b/t/t4153-am-resume-override-opts.sh
index 8ea22d1bcbb..b7c3861407d 100755
--- a/t/t4153-am-resume-override-opts.sh
+++ b/t/t4153-am-resume-override-opts.sh
@@ -61,7 +61,7 @@ test_expect_success '--no-quiet overrides --quiet' '
 	# Applying side2 will be quiet.
 	git am --no-quiet --continue >out &&
 	echo "Applying: side1" >expected &&
-	test_i18ncmp expected out
+	test_cmp expected out
 '
 
 test_expect_success '--signoff overrides --no-signoff' '
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 5ec0f47b567..85432b80ff5 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -123,7 +123,7 @@ test_expect_success 'NUL separation with --stat' '
 	stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) &&
 	printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n" >expected &&
 	git log -z --stat --pretty="format:%s" >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_failure 'NUL termination with --stat' '
diff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh
index daf01c309d0..54be7da1611 100755
--- a/t/t4254-am-corrupt.sh
+++ b/t/t4254-am-corrupt.sh
@@ -60,7 +60,7 @@ test_expect_success 'try to apply corrupted patch' '
 	test_must_fail git -c advice.amWorkDir=false am bad-patch.diff 2>actual &&
 	echo "error: git diff header lacks filename information (line 4)" >expected &&
 	test_path_is_file f &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success "NUL in commit message's body" '
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index db4e15fd596..cb67bac1c47 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -223,14 +223,14 @@ test_expect_success 'pull request format' '
 		git request-pull initial "$downstream_url" tags/full >../request
 	) &&
 	<request sed -nf fuzz.sed >request.fuzzy &&
-	test_i18ncmp expect request.fuzzy &&
+	test_cmp expect request.fuzzy &&
 
 	(
 		cd local &&
 		git request-pull initial "$downstream_url" tags/full:refs/tags/full
 	) >request &&
 	sed -nf fuzz.sed <request >request.fuzzy &&
-	test_i18ncmp expect request.fuzzy &&
+	test_cmp expect request.fuzzy &&
 
 	(
 		cd local &&
diff --git a/t/t5316-pack-delta-depth.sh b/t/t5316-pack-delta-depth.sh
index 0f06c40eb13..a8c1bc0f66b 100755
--- a/t/t5316-pack-delta-depth.sh
+++ b/t/t5316-pack-delta-depth.sh
@@ -84,14 +84,14 @@ test_expect_success 'packing produces a long delta' '
 	pack=$(git pack-objects --all --window=0 </dev/null pack) &&
 	echo 9 >expect &&
 	max_chain pack-$pack.pack >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success '--depth limits depth' '
 	pack=$(git pack-objects --all --depth=5 </dev/null pack) &&
 	echo 5 >expect &&
 	max_chain pack-$pack.pack >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_done
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 1f4cc873a83..8a5d3492c71 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -547,7 +547,7 @@ test_expect_success 'test lonely missing ref' '
 		cd client &&
 		test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy 2>../error-m
 	) &&
-	test_i18ncmp expect-error error-m
+	test_cmp expect-error error-m
 '
 
 test_expect_success 'test missing ref after existing' '
@@ -555,7 +555,7 @@ test_expect_success 'test missing ref after existing' '
 		cd client &&
 		test_must_fail git fetch-pack --no-progress .. refs/heads/A refs/heads/xyzzy 2>../error-em
 	) &&
-	test_i18ncmp expect-error error-em
+	test_cmp expect-error error-em
 '
 
 test_expect_success 'test missing ref before existing' '
@@ -563,7 +563,7 @@ test_expect_success 'test missing ref before existing' '
 		cd client &&
 		test_must_fail git fetch-pack --no-progress .. refs/heads/xyzzy refs/heads/A 2>../error-me
 	) &&
-	test_i18ncmp expect-error error-me
+	test_cmp expect-error error-me
 '
 
 test_expect_success 'test --all, --depth, and explicit head' '
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index d3a3bb0a42b..8c462f20ae6 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -140,8 +140,8 @@ test_expect_success 'remove remote protects local branches' '
 		git remote rm oops 2>actual2 &&
 		git branch -d foobranch &&
 		git tag -d footag &&
-		test_i18ncmp expect1 actual1 &&
-		test_i18ncmp expect2 actual2
+		test_cmp expect1 actual1 &&
+		test_cmp expect2 actual2
 	)
 '
 
@@ -150,7 +150,7 @@ test_expect_success 'remove errors out early when deleting non-existent branch'
 		cd test &&
 		echo "error: No such remote: '\''foo'\''" >expect &&
 		test_expect_code 2 git remote rm foo 2>actual &&
-		test_i18ncmp expect actual
+		test_cmp expect actual
 	)
 '
 
@@ -178,7 +178,7 @@ test_expect_success 'rename errors out early when deleting non-existent branch'
 		cd test &&
 		echo "error: No such remote: '\''foo'\''" >expect &&
 		test_expect_code 2 git remote rename foo bar 2>actual &&
-		test_i18ncmp expect actual
+		test_cmp expect actual
 	)
 '
 
@@ -186,14 +186,14 @@ test_expect_success 'rename errors out early when when new name is invalid' '
 	test_config remote.foo.vcs bar &&
 	echo "fatal: '\''invalid...name'\'' is not a valid remote name" >expect &&
 	test_must_fail git remote rename foo invalid...name 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'add existing foreign_vcs remote' '
 	test_config remote.foo.vcs bar &&
 	echo "error: remote foo already exists." >expect &&
 	test_expect_code 3 git remote add foo bar 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'add existing foreign_vcs remote' '
@@ -201,13 +201,13 @@ test_expect_success 'add existing foreign_vcs remote' '
 	test_config remote.bar.vcs bar &&
 	echo "error: remote bar already exists." >expect &&
 	test_expect_code 3 git remote rename foo bar 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'add invalid foreign_vcs remote' '
 	echo "fatal: '\''invalid...name'\'' is not a valid remote name" >expect &&
 	test_must_fail git remote add invalid...name bar 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >test/expect <<EOF
@@ -267,7 +267,7 @@ test_expect_success 'show' '
 		git config --add remote.two.push refs/heads/main:refs/heads/another &&
 		git remote show origin two >output &&
 		git branch -d rebase octopus &&
-		test_i18ncmp expect output
+		test_cmp expect output
 	)
 '
 
@@ -294,7 +294,7 @@ test_expect_success 'show -n' '
 		cd test &&
 		git remote show -n origin >output &&
 		mv ../one.unreachable ../one &&
-		test_i18ncmp expect output
+		test_cmp expect output
 	)
 '
 
@@ -337,7 +337,7 @@ test_expect_success 'set-head --auto has no problem w/multiple HEADs' '
 		git fetch two "refs/heads/*:refs/remotes/two/*" &&
 		git remote set-head --auto two >output 2>&1 &&
 		echo "two/HEAD set to main" >expect &&
-		test_i18ncmp expect output
+		test_cmp expect output
 	)
 '
 
@@ -369,7 +369,7 @@ test_expect_success 'prune --dry-run' '
 		git remote prune --dry-run origin >output &&
 		git rev-parse refs/remotes/origin/side2 &&
 		test_must_fail git rev-parse refs/remotes/origin/side &&
-		test_i18ncmp expect output
+		test_cmp expect output
 	)
 '
 
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index a37df6d35a7..ad1d1d5fd6b 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -1051,7 +1051,7 @@ test_expect_success 'fetch --prune prints the remotes url' '
 		git fetch --prune origin 2>&1 | head -n1 >../actual
 	) &&
 	echo "From ${D}/." >expect &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'branchname D/F conflict resolved by --prune' '
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 4a568a2398e..f53f58895a1 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -150,7 +150,7 @@ test_expect_success 'confuses pattern as remote when no remote specified' '
 	# We could just as easily have used "main"; the "*" emphasizes its
 	# role as a pattern.
 	test_must_fail git ls-remote "$does_not_exist" >actual 2>&1 &&
-	test_i18ncmp exp actual
+	test_cmp exp actual
 '
 
 test_expect_success 'die with non-2 for wrong repository even with --exit-code' '
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 11513ec15e1..ed11569d8d7 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -74,7 +74,7 @@ test_expect_success "fetch --recurse-submodules recurses into submodules" '
 		git fetch --recurse-submodules >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "submodule.recurse option triggers recursive fetch" '
@@ -84,7 +84,7 @@ test_expect_success "submodule.recurse option triggers recursive fetch" '
 		git -c submodule.recurse fetch >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "fetch --recurse-submodules -j2 has the same output behaviour" '
@@ -94,7 +94,7 @@ test_expect_success "fetch --recurse-submodules -j2 has the same output behaviou
 		GIT_TRACE="$TRASH_DIRECTORY/trace.out" git fetch --recurse-submodules -j2 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err &&
+	test_cmp expect.err actual.err &&
 	grep "2 tasks" trace.out
 '
 
@@ -124,7 +124,7 @@ test_expect_success "using fetchRecurseSubmodules=true in .gitmodules recurses i
 		git fetch >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "--no-recurse-submodules overrides .gitmodules config" '
@@ -155,7 +155,7 @@ test_expect_success "--recurse-submodules overrides fetchRecurseSubmodules setti
 		git config --unset submodule.submodule.fetchRecurseSubmodules
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "--quiet propagates to submodules" '
@@ -183,7 +183,7 @@ test_expect_success "--dry-run propagates to submodules" '
 		git fetch --recurse-submodules --dry-run >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "Without --dry-run propagates to submodules" '
@@ -192,7 +192,7 @@ test_expect_success "Without --dry-run propagates to submodules" '
 		git fetch --recurse-submodules >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "recurseSubmodules=true propagates into submodules" '
@@ -203,7 +203,7 @@ test_expect_success "recurseSubmodules=true propagates into submodules" '
 		git fetch >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "--recurse-submodules overrides config in submodule" '
@@ -217,7 +217,7 @@ test_expect_success "--recurse-submodules overrides config in submodule" '
 		git fetch --recurse-submodules >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "--no-recurse-submodules overrides config setting" '
@@ -257,7 +257,7 @@ test_expect_success "Recursion stops when no new submodule commits are fetched"
 		cd downstream &&
 		git fetch >../actual.out 2>../actual.err
 	) &&
-	test_i18ncmp expect.err.sub actual.err &&
+	test_cmp expect.err.sub actual.err &&
 	test_must_be_empty actual.out
 '
 
@@ -275,7 +275,7 @@ test_expect_success "Recursion doesn't happen when new superproject commits don'
 		git fetch >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err.file actual.err
+	test_cmp expect.err.file actual.err
 '
 
 test_expect_success "Recursion picks up config in submodule" '
@@ -303,7 +303,7 @@ test_expect_success "Recursion picks up config in submodule" '
 			git config --unset fetch.recurseSubmodules
 		)
 	) &&
-	test_i18ncmp expect.err.sub actual.err &&
+	test_cmp expect.err.sub actual.err &&
 	test_must_be_empty actual.out
 '
 
@@ -336,7 +336,7 @@ test_expect_success "Recursion picks up all submodules when necessary" '
 		cd downstream &&
 		git fetch >../actual.out 2>../actual.err
 	) &&
-	test_i18ncmp expect.err.2 actual.err &&
+	test_cmp expect.err.2 actual.err &&
 	test_must_be_empty actual.out
 '
 
@@ -392,7 +392,7 @@ test_expect_success "'--recurse-submodules=on-demand' recurses as deep as necess
 		)
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err
+	test_cmp expect.err actual.err
 '
 
 test_expect_success "'--recurse-submodules=on-demand' stops when no new submodule commits are found in the superproject (and ignores config)" '
@@ -409,7 +409,7 @@ test_expect_success "'--recurse-submodules=on-demand' stops when no new submodul
 		git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err.file actual.err
+	test_cmp expect.err.file actual.err
 '
 
 test_expect_success "'fetch.recurseSubmodules=on-demand' overrides global config" '
@@ -437,7 +437,7 @@ test_expect_success "'fetch.recurseSubmodules=on-demand' overrides global config
 		git config --unset fetch.recurseSubmodules
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err.2 actual.err
+	test_cmp expect.err.2 actual.err
 '
 
 test_expect_success "'submodule.<sub>.fetchRecurseSubmodules=on-demand' overrides fetch.recurseSubmodules" '
@@ -465,7 +465,7 @@ test_expect_success "'submodule.<sub>.fetchRecurseSubmodules=on-demand' override
 		git config --unset submodule.submodule.fetchRecurseSubmodules
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err.2 actual.err
+	test_cmp expect.err.2 actual.err
 '
 
 test_expect_success "don't fetch submodule when newly recorded commits are already present" '
@@ -484,7 +484,7 @@ test_expect_success "don't fetch submodule when newly recorded commits are alrea
 		git fetch >../actual.out 2>../actual.err
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err actual.err &&
+	test_cmp expect.err actual.err &&
 	(
 		cd submodule &&
 		git checkout -q sub
@@ -520,7 +520,7 @@ test_expect_success "'fetch.recurseSubmodules=on-demand' works also without .git
 		git reset --hard
 	) &&
 	test_must_be_empty actual.out &&
-	test_i18ncmp expect.err.2 actual.err &&
+	test_cmp expect.err.2 actual.err &&
 	git checkout HEAD^ -- .gitmodules &&
 	git add .gitmodules &&
 	git commit -m "new submodule restored .gitmodules"
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index bc5ccf233f0..c024fa28183 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -118,7 +118,7 @@ test_expect_success 'rejected update prints status' '
 	git commit -m dev2 &&
 	test_must_fail git push origin dev2 2>act &&
 	sed -e "/^remote: /s/ *$//" <act >cmp &&
-	test_i18ncmp exp cmp
+	test_cmp exp cmp
 '
 rm -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"
 
diff --git a/t/t6020-bundle-misc.sh b/t/t6020-bundle-misc.sh
index 6249420a806..90b2be9b2ed 100755
--- a/t/t6020-bundle-misc.sh
+++ b/t/t6020-bundle-misc.sh
@@ -175,7 +175,7 @@ test_expect_success 'create bundle from special rev: main^!' '
 	cat >expect <<-\EOF &&
 	<COMMIT-P> refs/heads/main
 	EOF
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	git bundle verify special-rev.bdl |
 		make_user_friendly_and_stable_output >actual &&
@@ -185,7 +185,7 @@ test_expect_success 'create bundle from special rev: main^!' '
 	The bundle requires this ref:
 	<COMMIT-O>
 	EOF
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	test_bundle_object_count special-rev.bdl 3
 '
@@ -207,7 +207,7 @@ test_expect_success 'create bundle with --max-count option' '
 	The bundle requires this ref:
 	<COMMIT-O>
 	EOF
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	test_bundle_object_count max-count.bdl 4
 '
@@ -236,7 +236,7 @@ test_expect_success 'create bundle with --since option' '
 	<COMMIT-M>
 	<COMMIT-K>
 	EOF
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	test_bundle_object_count --thin since.bdl 13
 '
@@ -262,11 +262,11 @@ test_expect_success 'create bundle 1 - no prerequisites' '
 	# verify bundle, which has no prerequisites
 	git bundle verify 1.bdl |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	git bundle verify stdin-1.bdl |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	test_bundle_object_count       1.bdl 24 &&
 	test_bundle_object_count stdin-1.bdl 24
@@ -304,11 +304,11 @@ test_expect_success 'create bundle 2 - has prerequisites' '
 
 	git bundle verify 2.bdl |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	git bundle verify stdin-2.bdl |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	test_bundle_object_count       2.bdl 16 &&
 	test_bundle_object_count stdin-2.bdl 16
@@ -326,11 +326,11 @@ test_expect_success 'fail to verify bundle without prerequisites' '
 
 	test_must_fail git -C test1.git bundle verify ../2.bdl 2>&1 |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	test_must_fail git -C test1.git bundle verify ../stdin-2.bdl 2>&1 |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'create bundle 3 - two refs, same object' '
@@ -363,11 +363,11 @@ test_expect_success 'create bundle 3 - two refs, same object' '
 
 	git bundle verify 3.bdl |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	git bundle verify stdin-3.bdl |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	test_bundle_object_count       3.bdl 4 &&
 	test_bundle_object_count stdin-3.bdl 4
@@ -404,11 +404,11 @@ test_expect_success 'create bundle 4 - with tags' '
 
 	git bundle verify 4.bdl |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	git bundle verify stdin-4.bdl |
 		make_user_friendly_and_stable_output >actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 
 	test_bundle_object_count       4.bdl 3 &&
 	test_bundle_object_count stdin-4.bdl 3
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 7bcde054d73..ef7bdcedf23 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -829,7 +829,7 @@ test_expect_success 'bisect terms needs 0 or 1 argument' '
 	test_must_fail git bisect terms 1 2 &&
 	test_must_fail git bisect terms 2>actual &&
 	echo "error: no terms defined" >expected &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'bisect terms shows good/bad after start' '
@@ -903,7 +903,7 @@ test_expect_success 'bisect start --term-* does store terms' '
 	Your current terms are two for the old state
 	and one for the new state.
 	EOF
-	test_i18ncmp expected actual &&
+	test_cmp expected actual &&
 	git bisect terms --term-bad >actual &&
 	echo one >expected &&
 	test_cmp expected actual &&
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index a160b2bf99c..a313849406d 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -57,7 +57,7 @@ test_expect_success 'branch -v' '
 		git branch -v
 	) |
 	sed -n -e "$t6040_script" >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<\EOF
@@ -75,7 +75,7 @@ test_expect_success 'branch -vv' '
 		git branch -vv
 	) |
 	sed -n -e "$t6040_script" >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'checkout (diverged from upstream)' '
@@ -146,7 +146,7 @@ test_expect_success 'status -s -b (diverged from upstream)' '
 		git checkout b1 >/dev/null &&
 		git status -s -b | head -1
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<\EOF
@@ -159,7 +159,7 @@ test_expect_success 'status -s -b --no-ahead-behind (diverged from upstream)' '
 		git checkout b1 >/dev/null &&
 		git status -s -b --no-ahead-behind | head -1
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<\EOF
@@ -172,7 +172,7 @@ test_expect_success 'status.aheadbehind=false status -s -b (diverged from upstre
 		git checkout b1 >/dev/null &&
 		git -c status.aheadbehind=false status -s -b | head -1
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<\EOF
@@ -187,7 +187,7 @@ test_expect_success 'status --long --branch' '
 		git checkout b1 >/dev/null &&
 		git status --long -b | head -3
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'status --long --branch' '
@@ -196,7 +196,7 @@ test_expect_success 'status --long --branch' '
 		git checkout b1 >/dev/null &&
 		git -c status.aheadbehind=true status --long -b | head -3
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<\EOF
@@ -210,7 +210,7 @@ test_expect_success 'status --long --branch --no-ahead-behind' '
 		git checkout b1 >/dev/null &&
 		git status --long -b --no-ahead-behind | head -2
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'status.aheadbehind=false status --long --branch' '
@@ -219,7 +219,7 @@ test_expect_success 'status.aheadbehind=false status --long --branch' '
 		git checkout b1 >/dev/null &&
 		git -c status.aheadbehind=false status --long -b | head -2
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<\EOF
@@ -232,7 +232,7 @@ test_expect_success 'status -s -b (upstream is gone)' '
 		git checkout b5 >/dev/null &&
 		git status -s -b | head -1
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<\EOF
@@ -245,7 +245,7 @@ test_expect_success 'status -s -b (up-to-date with upstream)' '
 		git checkout b6 >/dev/null &&
 		git status -s -b | head -1
 	) >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'fail to track lightweight tags' '
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 546796f8473..e89b6747bee 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -136,7 +136,7 @@ warning: tag 'Q' is externally known as 'A'
 EOF
 check_describe A-* HEAD
 test_expect_success 'warning was displayed for Q' '
-	test_i18ncmp err.expect err.actual
+	test_cmp err.expect err.actual
 '
 test_expect_success 'misnamed annotated tag forces long output' '
 	description=$(git describe --no-long Q^0) &&
diff --git a/t/t6134-pathspec-in-submodule.sh b/t/t6134-pathspec-in-submodule.sh
index c6706684098..0f1cb49cedc 100755
--- a/t/t6134-pathspec-in-submodule.sh
+++ b/t/t6134-pathspec-in-submodule.sh
@@ -21,7 +21,7 @@ EOF
 test_expect_success 'error message for path inside submodule' '
 	echo a >sub/a &&
 	test_must_fail git add sub/a 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'error message for path inside submodule from within submodule' '
diff --git a/t/t6301-for-each-ref-errors.sh b/t/t6301-for-each-ref-errors.sh
index 809854fc0ce..40edf9dab53 100755
--- a/t/t6301-for-each-ref-errors.sh
+++ b/t/t6301-for-each-ref-errors.sh
@@ -20,8 +20,8 @@ test_expect_success 'Broken refs are reported correctly' '
 	test_when_finished "rm -f .git/$r" &&
 	echo "warning: ignoring broken ref $r" >broken-err &&
 	git for-each-ref >out 2>err &&
-	test_i18ncmp full-list out &&
-	test_i18ncmp broken-err err
+	test_cmp full-list out &&
+	test_cmp broken-err err
 '
 
 test_expect_success 'NULL_SHA1 refs are reported correctly' '
@@ -31,10 +31,10 @@ test_expect_success 'NULL_SHA1 refs are reported correctly' '
 	echo "warning: ignoring broken ref $r" >zeros-err &&
 	git for-each-ref >out 2>err &&
 	test_cmp full-list out &&
-	test_i18ncmp zeros-err err &&
+	test_cmp zeros-err err &&
 	git for-each-ref --format="%(objectname) %(refname)" >brief-out 2>brief-err &&
 	test_cmp brief-list brief-out &&
-	test_i18ncmp zeros-err brief-err
+	test_cmp zeros-err brief-err
 '
 
 test_expect_success 'Missing objects are reported correctly' '
@@ -43,7 +43,7 @@ test_expect_success 'Missing objects are reported correctly' '
 	test_when_finished "rm -f .git/$r" &&
 	echo "fatal: missing object $MISSING for $r" >missing-err &&
 	test_must_fail git for-each-ref 2>err &&
-	test_i18ncmp missing-err err &&
+	test_cmp missing-err err &&
 	(
 		cat brief-list &&
 		echo "$MISSING $r"
diff --git a/t/t6436-merge-overwrite.sh b/t/t6436-merge-overwrite.sh
index 362ae37a122..84b4aacf496 100755
--- a/t/t6436-merge-overwrite.sh
+++ b/t/t6436-merge-overwrite.sh
@@ -139,7 +139,7 @@ test_expect_success 'will not overwrite untracked file in leading path' '
 	cp important sub &&
 	cp important sub2 &&
 	test_must_fail git merge sub 2>out &&
-	test_i18ncmp out expect &&
+	test_cmp out expect &&
 	test_path_is_missing .git/MERGE_HEAD &&
 	test_cmp important sub &&
 	test_cmp important sub2 &&
@@ -174,7 +174,7 @@ test_expect_success 'will not overwrite untracked file on unborn branch' '
 	git checkout --orphan new &&
 	cp important c0.c &&
 	test_must_fail git merge c0 2>out &&
-	test_i18ncmp out expect
+	test_cmp out expect
 '
 
 test_expect_success 'will not overwrite untracked file on unborn branch .git/MERGE_HEAD sanity etc.' '
diff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh
index e176475ed5b..5bfb027099a 100755
--- a/t/t6439-merge-co-error-msgs.sh
+++ b/t/t6439-merge-co-error-msgs.sh
@@ -40,14 +40,14 @@ EOF
 
 test_expect_success 'untracked files overwritten by merge (fast and non-fast forward)' '
 	test_must_fail git merge branch 2>out &&
-	test_i18ncmp out expect &&
+	test_cmp out expect &&
 	git commit --allow-empty -m empty &&
 	(
 		GIT_MERGE_VERBOSITY=0 &&
 		export GIT_MERGE_VERBOSITY &&
 		test_must_fail git merge branch 2>out2
 	) &&
-	test_i18ncmp out2 expect &&
+	test_cmp out2 expect &&
 	git reset --hard HEAD^
 '
 
@@ -68,7 +68,7 @@ test_expect_success 'untracked files or local changes ovewritten by merge' '
 	git add three &&
 	git add four &&
 	test_must_fail git merge branch 2>out &&
-	test_i18ncmp out expect
+	test_cmp out expect
 '
 
 cat >expect <<\EOF
@@ -90,7 +90,7 @@ test_expect_success 'cannot switch branches because of local changes' '
 	echo uno >rep/one &&
 	echo dos >rep/two &&
 	test_must_fail git checkout branch 2>out &&
-	test_i18ncmp out expect
+	test_cmp out expect
 '
 
 cat >expect <<\EOF
@@ -104,7 +104,7 @@ EOF
 test_expect_success 'not uptodate file porcelain checkout error' '
 	git add rep/one rep/two &&
 	test_must_fail git checkout branch 2>out &&
-	test_i18ncmp out expect
+	test_cmp out expect
 '
 
 cat >expect <<\EOF
@@ -135,7 +135,7 @@ test_expect_success 'not_uptodate_dir porcelain checkout error' '
 	>rep/untracked-file &&
 	>rep2/untracked-file &&
 	test_must_fail git checkout branch 2>out &&
-	test_i18ncmp out ../expect
+	test_cmp out ../expect
 '
 
 test_done
diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh
index 63d5f41a124..080a6530831 100755
--- a/t/t7001-mv.sh
+++ b/t/t7001-mv.sh
@@ -446,7 +446,7 @@ test_expect_success 'mv issues a warning when section is not found in .gitmodule
 	echo "warning: Could not find section in .gitmodules where path=sub" >expect.err &&
 	mkdir mod &&
 	git mv sub mod/sub 2>actual.err &&
-	test_i18ncmp expect.err actual.err &&
+	test_cmp expect.err actual.err &&
 	! test -e sub &&
 	[ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] &&
 	(
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 943a7d5c1db..bbd2b7b6f35 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -91,7 +91,7 @@ test_expect_success 'creating a tag with --create-reflog should create reflog' '
 	git tag --create-reflog tag_with_reflog &&
 	git reflog exists refs/tags/tag_with_reflog &&
 	sed -e "s/^.*	//" .git/logs/refs/tags/tag_with_reflog >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'annotated tag with --create-reflog has correct message' '
@@ -102,7 +102,7 @@ test_expect_success 'annotated tag with --create-reflog has correct message' '
 	git tag -m "annotated tag" --create-reflog tag_with_reflog &&
 	git reflog exists refs/tags/tag_with_reflog &&
 	sed -e "s/^.*	//" .git/logs/refs/tags/tag_with_reflog >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success '--create-reflog does not create reflog on failure' '
@@ -1409,7 +1409,7 @@ test_expect_success 'message in editor has initial comment: first line' '
 	# check the first line --- should be empty
 	echo >first.expect &&
 	sed -e 1q <actual >first.actual &&
-	test_i18ncmp first.expect first.actual
+	test_cmp first.expect first.actual
 '
 
 test_expect_success \
@@ -1732,7 +1732,7 @@ test_expect_success 'recursive tagging should give advice' '
 	hint: Disable this message with "git config advice.nestedTag false"
 	EOF
 	git tag -m nested nested annotated-v4.0 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'multiple --points-at are OR-ed together' '
diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh
index e5c6a038fbf..f2a8e765114 100755
--- a/t/t7012-skip-worktree-writing.sh
+++ b/t/t7012-skip-worktree-writing.sh
@@ -125,13 +125,13 @@ EOF
 test_expect_success 'git-clean, absent case' '
 	setup_absent &&
 	git clean -n > result &&
-	test_i18ncmp expected result
+	test_cmp expected result
 '
 
 test_expect_success 'git-clean, dirty case' '
 	setup_dirty &&
 	git clean -n > result &&
-	test_i18ncmp expected result
+	test_cmp expected result
 '
 
 test_expect_success '--ignore-skip-worktree-entries leaves worktree alone' '
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
index 72fb418b890..0f4344c55e6 100755
--- a/t/t7060-wtstatus.sh
+++ b/t/t7060-wtstatus.sh
@@ -56,9 +56,9 @@ EOF
 		git commit -m delete &&
 		test_must_fail git merge main &&
 		test_must_fail git commit --dry-run >../actual &&
-		test_i18ncmp ../expect ../actual &&
+		test_cmp ../expect ../actual &&
 		git status >../actual &&
-		test_i18ncmp ../expect ../actual
+		test_cmp ../expect ../actual
 	)
 '
 
@@ -151,7 +151,7 @@ Unmerged paths:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -185,7 +185,7 @@ Unmerged paths:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -210,7 +210,7 @@ Unmerged paths:
 Untracked files not listed (use -u option to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual &&
+	test_cmp expected actual &&
 	git reset --hard &&
 	git checkout main
 '
@@ -227,7 +227,7 @@ test_expect_success 'status --branch with detached HEAD' '
 	?? expected
 	?? mdconflict/
 	EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 ## Duplicate the above test and verify --porcelain=v1 arg parsing.
@@ -243,7 +243,7 @@ test_expect_success 'status --porcelain=v1 --branch with detached HEAD' '
 	?? expected
 	?? mdconflict/
 	EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 ## Verify parser error on invalid --porcelain argument.
diff --git a/t/t7063-status-untracked-cache.sh b/t/t7063-status-untracked-cache.sh
index f01bf277279..accefde72fb 100755
--- a/t/t7063-status-untracked-cache.sh
+++ b/t/t7063-status-untracked-cache.sh
@@ -731,7 +731,7 @@ test_expect_success 'test ident field is working' '
 	cp -R done dthree dtwo four three ../other_worktree &&
 	GIT_WORK_TREE=../other_worktree git status 2>../err &&
 	echo "warning: untracked cache is disabled on this system or location" >../expect &&
-	test_i18ncmp ../expect ../err
+	test_cmp ../expect ../err
 '
 
 test_expect_success 'untracked cache survives a checkout' '
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index 7d8fb188ee5..601b2bf97f0 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -75,14 +75,14 @@ test_expect_success 'reset --hard message' '
 	hex=$(git log -1 --format="%h") &&
 	git reset --hard >.actual &&
 	echo HEAD is now at $hex $(commit_msg) >.expected &&
-	test_i18ncmp .expected .actual
+	test_cmp .expected .actual
 '
 
 test_expect_success 'reset --hard message (ISO8859-1 logoutputencoding)' '
 	hex=$(git log -1 --format="%h") &&
 	git -c "i18n.logOutputEncoding=$test_encoding" reset --hard >.actual &&
 	echo HEAD is now at $hex $(commit_msg $test_encoding) >.expected &&
-	test_i18ncmp .expected .actual
+	test_cmp .expected .actual
 '
 
 test_expect_success 'giving a non existing revision should fail' '
@@ -469,7 +469,7 @@ test_expect_success '--mixed refreshes the index' '
 	EOF
 	echo 123 >>file2 &&
 	git reset --mixed HEAD >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'resetting specific path that is unmerged' '
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index d44f6962933..a924fdb7a6c 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -55,7 +55,7 @@ test_expect_success 'add aborts on repository with no commits' '
 	EOF
 	git init repo-no-commits &&
 	test_must_fail git submodule add ../a ./repo-no-commits 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'status should ignore inner git repo when not added' '
@@ -185,7 +185,7 @@ test_expect_success 'submodule add to .gitignored path fails' '
 		git add --force .gitignore &&
 		git commit -m"Ignore everything" &&
 		! git submodule add "$submodurl" submod >actual 2>&1 &&
-		test_i18ncmp expect actual
+		test_cmp expect actual
 	)
 '
 
diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh
index 76088147089..9c3cc4cf404 100755
--- a/t/t7401-submodule-summary.sh
+++ b/t/t7401-submodule-summary.sh
@@ -190,7 +190,7 @@ test_expect_success 'typechanged submodule(submodule->blob), --cached' "
 	  < Add foo5
 
 	EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 "
 
 test_expect_success 'typechanged submodule(submodule->blob), --files' "
@@ -200,7 +200,7 @@ test_expect_success 'typechanged submodule(submodule->blob), --files' "
 	  > Add foo5
 
 	EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 "
 
 rm -rf sm1 &&
@@ -211,7 +211,7 @@ test_expect_success 'typechanged submodule(submodule->blob)' "
 	* sm1 $head4(submodule)->$head5(blob):
 
 	EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 "
 
 rm -f sm1 &&
@@ -224,7 +224,7 @@ test_expect_success 'nonexistent commit' "
 	  Warn: sm1 doesn't contain commit $head4_full
 
 	EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 "
 
 commit_file
@@ -235,7 +235,7 @@ test_expect_success 'typechanged submodule(blob->submodule)' "
 	  > Add foo7
 
 	EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 "
 
 commit_file sm1 &&
@@ -292,7 +292,7 @@ test_expect_success 'given commit' "
 
 test_expect_success '--for-status' "
 	git submodule summary --for-status HEAD^ >actual &&
-	test_i18ncmp - actual <<-EOF
+	test_cmp - actual <<-EOF
 	* sm1 $head6...0000000:
 
 	* sm2 0000000...$head7 (2):
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index b9c1624fba9..ff3ba5422e9 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -155,9 +155,9 @@ test_expect_success 'submodule update --init --recursive from subdirectory' '
 	 cd tmp &&
 	 git submodule update --init --recursive ../super >../../actual 2>../../actual2
 	) &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 	sort actual2 >actual2.sorted &&
-	test_i18ncmp expect2 actual2.sorted
+	test_cmp expect2 actual2.sorted
 '
 
 cat <<EOF >expect2
@@ -174,7 +174,7 @@ test_expect_success 'submodule update --init from and of subdirectory' '
 	  git submodule update --init sub 2>../../actual2
 	 )
 	) &&
-	test_i18ncmp expect2 actual2
+	test_cmp expect2 actual2
 '
 
 test_expect_success 'submodule update does not fetch already present commits' '
@@ -192,7 +192,7 @@ test_expect_success 'submodule update does not fetch already present commits' '
 	(cd super &&
 	  git submodule update > ../actual 2> ../actual.err
 	) &&
-	test_i18ncmp expected actual &&
+	test_cmp expected actual &&
 	test_must_be_empty actual.err
 '
 
@@ -461,7 +461,7 @@ test_expect_success 'submodule update - command in .git/config catches failure'
 	(cd super &&
 	 test_must_fail git submodule update submodule 2>../actual
 	) &&
-	test_i18ncmp actual expect
+	test_cmp actual expect
 '
 
 cat << EOF >expect
@@ -479,7 +479,7 @@ test_expect_success 'submodule update - command in .git/config catches failure -
 	 mkdir tmp && cd tmp &&
 	 test_must_fail git submodule update ../submodule 2>../../actual
 	) &&
-	test_i18ncmp actual expect
+	test_cmp actual expect
 '
 
 test_expect_success 'submodule update - command run for initial population of submodule' '
@@ -488,7 +488,7 @@ test_expect_success 'submodule update - command run for initial population of su
 	EOF
 	rm -rf super/submodule &&
 	test_must_fail git -C super submodule update 2>actual &&
-	test_i18ncmp expect actual &&
+	test_cmp expect actual &&
 	git -C super submodule update --checkout
 '
 
@@ -509,7 +509,7 @@ test_expect_success 'recursive submodule update - command in .git/config catches
 	 mkdir -p tmp && cd tmp &&
 	 test_must_fail git submodule update --recursive ../super 2>../../actual
 	) &&
-	test_i18ncmp actual expect
+	test_cmp actual expect
 '
 
 test_expect_success 'submodule init does not copy command into .git/config' '
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 79981b51eb8..e2f110b7863 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -80,7 +80,7 @@ test_expect_success 'test basic "submodule foreach" usage' '
 		git config foo.bar zar &&
 		git submodule foreach "git config --file \"\$toplevel/.git/config\" foo.bar"
 	) &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat >expect <<EOF
@@ -96,7 +96,7 @@ test_expect_success 'test "submodule foreach" from subdirectory' '
 		cd clone/sub &&
 		git submodule foreach "echo \$toplevel-\$name-\$sm_path-\$displaypath-\$sha1" >../../actual
 	) &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'setup nested submodules' '
@@ -177,7 +177,7 @@ test_expect_success 'test messages from "foreach --recursive"' '
 		cd clone2 &&
 		git submodule foreach --recursive "true" > ../actual
 	) &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat > expect <<EOF
@@ -197,7 +197,7 @@ test_expect_success 'test messages from "foreach --recursive" from subdirectory'
 		cd untracked &&
 		git submodule foreach --recursive >../../actual
 	) &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 sub1sha1=$(cd clone2/sub1 && git rev-parse HEAD)
 sub2sha1=$(cd clone2/sub2 && git rev-parse HEAD)
@@ -229,7 +229,7 @@ test_expect_success 'test "submodule foreach --recursive" from subdirectory' '
 		cd clone2/untracked &&
 		git submodule foreach --recursive "echo toplevel: \$toplevel name: \$name path: \$sm_path displaypath: \$displaypath hash: \$sha1" >../../actual
 	) &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 cat > expect <<EOF
diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh
index 6d19ece05dd..e41ac18e7e0 100755
--- a/t/t7500-commit-template-squash-signoff.sh
+++ b/t/t7500-commit-template-squash-signoff.sh
@@ -15,7 +15,7 @@ commit_msg_is () {
 
 	printf "%s" "$(git log --pretty=format:%s%b -1)" >"$actual" &&
 	printf "%s" "$1" >"$expect" &&
-	test_i18ncmp "$expect" "$actual"
+	test_cmp "$expect" "$actual"
 }
 
 # A sanity check to see if commit is working at all.
@@ -356,7 +356,7 @@ test_expect_success 'new line found before status message in commit template' '
 	touch commit-template-check &&
 	git add commit-template-check &&
 	GIT_EDITOR="cat >editor-input" git commit --untracked-files=no --allow-empty-message &&
-	test_i18ncmp expected-template editor-input
+	test_cmp expected-template editor-input
 '
 
 test_expect_success 'setup empty commit with unstaged rename and copy' '
diff --git a/t/t7502-commit-porcelain.sh b/t/t7502-commit-porcelain.sh
index e5332adc9a1..6396897cc81 100755
--- a/t/t7502-commit-porcelain.sh
+++ b/t/t7502-commit-porcelain.sh
@@ -13,7 +13,7 @@ commit_msg_is () {
 
 	printf "%s" "$(git log --pretty=format:%s%b -1)" >$actual &&
 	printf "%s" "$1" >$expect &&
-	test_i18ncmp $expect $actual
+	test_cmp $expect $actual
 }
 
 # Arguments: [<prefix] [<commit message>] [<commit options>]
@@ -35,7 +35,7 @@ check_summary_oneline() {
 	SUMMARY_POSTFIX="$(git log -1 --pretty='format:%h')"
 	echo "[$SUMMARY_PREFIX $SUMMARY_POSTFIX] $2" >exp &&
 
-	test_i18ncmp exp act
+	test_cmp exp act
 }
 
 test_expect_success 'output summary format' '
@@ -300,7 +300,7 @@ echo "sample
 # with '#' will be ignored, and an empty message aborts the commit." >expect
 
 test_expect_success 'cleanup commit messages (strip option,-F,-e): output' '
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'cleanup commit message (fail on invalid cleanup mode option)' '
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index d01aacb66b5..2b72451ba3e 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -109,13 +109,13 @@ test_expect_success 'status --column' '
 #
 EOF
 	COLUMNS=50 git -c status.displayCommentPrefix=true status --column="column dense" >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status --column status.displayCommentPrefix=false' '
 	strip_comments expect &&
 	COLUMNS=49 git -c status.displayCommentPrefix=false status --column="column dense" >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >expect <<\EOF
@@ -144,19 +144,19 @@ EOF
 
 test_expect_success 'status with status.displayCommentPrefix=true' '
 	git -c status.displayCommentPrefix=true status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status with status.displayCommentPrefix=false' '
 	strip_comments expect &&
 	git -c status.displayCommentPrefix=false status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status -v' '
 	(cat expect && git diff --cached) >expect-with-v &&
 	git status -v >output &&
-	test_i18ncmp expect-with-v output
+	test_cmp expect-with-v output
 '
 
 test_expect_success 'status -v -v' '
@@ -167,7 +167,7 @@ test_expect_success 'status -v -v' '
 	 echo "Changes not staged for commit:" &&
 	 git -c diff.mnemonicprefix=true diff) >expect-with-v &&
 	git status -v -v >output &&
-	test_i18ncmp expect-with-v output
+	test_cmp expect-with-v output
 '
 
 test_expect_success 'setup fake editor' '
@@ -214,7 +214,7 @@ EOF
 test_expect_success 'status (advice.statusHints false)' '
 	test_config advice.statusHints false &&
 	git status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 
 '
 
@@ -296,7 +296,7 @@ Ignored files:
 
 EOF
 	git status --ignored >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status with gitignore (nothing untracked)' '
@@ -358,7 +358,7 @@ Ignored files:
 
 EOF
 	git status --ignored >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >.gitignore <<\EOF
@@ -380,7 +380,7 @@ EOF
 test_expect_success 'status -s -b' '
 
 	git status -s -b >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 
 '
 
@@ -390,7 +390,7 @@ test_expect_success 'status -s -z -b' '
 	git status -s -z -b >output &&
 	nul_to_q <output >output.q &&
 	mv output.q output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'setup dir3' '
@@ -418,13 +418,13 @@ Changes not staged for commit:
 Untracked files not listed (use -u option to show untracked files)
 EOF
 	git status -uno >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status (status.showUntrackedFiles no)' '
 	test_config status.showuntrackedfiles no &&
 	git status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status -uno (advice.statusHints false)' '
@@ -443,7 +443,7 @@ Untracked files not listed
 EOF
 	test_config advice.statusHints false &&
 	git status -uno >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >expect << EOF
@@ -487,13 +487,13 @@ Untracked files:
 
 EOF
 	git status -unormal >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status (status.showUntrackedFiles normal)' '
 	test_config status.showuntrackedfiles normal &&
 	git status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >expect <<EOF
@@ -543,13 +543,13 @@ Untracked files:
 
 EOF
 	git status -uall >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status (status.showUntrackedFiles all)' '
 	test_config status.showuntrackedfiles all &&
 	git status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'teardown dir3' '
@@ -601,7 +601,7 @@ Untracked files:
 
 EOF
 	(cd dir1 && git status) >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >expect <<\EOF
@@ -670,13 +670,13 @@ Untracked files:
 EOF
 	test_config color.ui auto &&
 	test_terminal git status | test_decode_color >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success TTY 'status with color.status' '
 	test_config color.status auto &&
 	test_terminal git status | test_decode_color >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >expect <<\EOF
@@ -718,7 +718,7 @@ EOF
 test_expect_success TTY 'status -s -b with color.status' '
 
 	test_terminal git status -s -b | test_decode_color >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 
 '
 
@@ -793,7 +793,7 @@ Untracked files:
 EOF
 	test_config status.relativePaths false &&
 	(cd dir1 && git status) >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 
 '
 
@@ -860,7 +860,7 @@ Untracked files:
 
 EOF
 	git commit --dry-run dir1/modified >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >expect <<EOF
@@ -921,13 +921,13 @@ Untracked files:
 
 EOF
 	git status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 # we expect the same as the previous test
 test_expect_success 'status --untracked-files=all does not show submodule' '
 	git status --untracked-files=all >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >expect <<EOF
@@ -984,13 +984,13 @@ Untracked files:
 EOF
 	git config status.submodulesummary 10 &&
 	git status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'status submodule summary with status.displayCommentPrefix=false' '
 	strip_comments expect &&
 	git -c status.displayCommentPrefix=false status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'commit with submodule summary ignores status.displayCommentPrefix' '
@@ -1035,9 +1035,9 @@ EOF
 	git commit -m "commit submodule" &&
 	git config status.submodulesummary 10 &&
 	test_must_fail git commit --dry-run >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 cat >expect <<EOF
@@ -1091,7 +1091,7 @@ Untracked files:
 EOF
 	git config status.submodulesummary 10 &&
 	git commit --dry-run --amend >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success POSIXPERM,SANITY 'status succeeds in a read-only repository' '
@@ -1143,17 +1143,17 @@ Untracked files:
 EOF
 	echo modified  sm/untracked &&
 	git status --ignore-submodules=untracked >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success '.gitmodules ignore=untracked suppresses submodules with untracked content' '
 	test_config diff.ignoreSubmodules dirty &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config --add -f .gitmodules submodule.subname.ignore untracked &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
@@ -1163,14 +1163,14 @@ test_expect_success '.git/config ignore=untracked suppresses submodules with unt
 	git config --add submodule.subname.ignore untracked &&
 	git config --add submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config --remove-section submodule.subname &&
 	git config --remove-section -f .gitmodules submodule.subname
 '
 
 test_expect_success '--ignore-submodules=dirty suppresses submodules with untracked content' '
 	git status --ignore-submodules=dirty >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success '.gitmodules ignore=dirty suppresses submodules with untracked content' '
@@ -1180,7 +1180,7 @@ test_expect_success '.gitmodules ignore=dirty suppresses submodules with untrack
 	git config --add -f .gitmodules submodule.subname.ignore dirty &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
@@ -1190,7 +1190,7 @@ test_expect_success '.git/config ignore=dirty suppresses submodules with untrack
 	git config --add submodule.subname.ignore dirty &&
 	git config --add submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config --remove-section submodule.subname &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
@@ -1198,14 +1198,14 @@ test_expect_success '.git/config ignore=dirty suppresses submodules with untrack
 test_expect_success '--ignore-submodules=dirty suppresses submodules with modified content' '
 	echo modified >sm/foo &&
 	git status --ignore-submodules=dirty >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success '.gitmodules ignore=dirty suppresses submodules with modified content' '
 	git config --add -f .gitmodules submodule.subname.ignore dirty &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
@@ -1215,7 +1215,7 @@ test_expect_success '.git/config ignore=dirty suppresses submodules with modifie
 	git config --add submodule.subname.ignore dirty &&
 	git config --add submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config --remove-section submodule.subname &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
@@ -1253,14 +1253,14 @@ Untracked files:
 
 EOF
 	git status --ignore-submodules=untracked > output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success ".gitmodules ignore=untracked doesn't suppress submodules with modified content" '
 	git config --add -f .gitmodules submodule.subname.ignore untracked &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
@@ -1270,7 +1270,7 @@ test_expect_success ".git/config ignore=untracked doesn't suppress submodules wi
 	git config --add submodule.subname.ignore untracked &&
 	git config --add submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config --remove-section submodule.subname &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
@@ -1314,14 +1314,14 @@ Untracked files:
 
 EOF
 	git status --ignore-submodules=untracked > output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success ".gitmodules ignore=untracked doesn't suppress submodule summary" '
 	git config --add -f .gitmodules submodule.subname.ignore untracked &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
@@ -1331,20 +1331,20 @@ test_expect_success ".git/config ignore=untracked doesn't suppress submodule sum
 	git config --add submodule.subname.ignore untracked &&
 	git config --add submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config --remove-section submodule.subname &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
 test_expect_success "--ignore-submodules=dirty doesn't suppress submodule summary" '
 	git status --ignore-submodules=dirty > output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 test_expect_success ".gitmodules ignore=dirty doesn't suppress submodule summary" '
 	git config --add -f .gitmodules submodule.subname.ignore dirty &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
@@ -1354,7 +1354,7 @@ test_expect_success ".git/config ignore=dirty doesn't suppress submodule summary
 	git config --add submodule.subname.ignore dirty &&
 	git config --add submodule.subname.path sm &&
 	git status >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config --remove-section submodule.subname &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
@@ -1398,7 +1398,7 @@ EOF
 test_expect_success "status (core.commentchar with submodule summary)" '
 	test_config core.commentchar ";" &&
 	git -c status.displayCommentPrefix=true status >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success "status (core.commentchar with two chars with submodule summary)" '
@@ -1429,7 +1429,7 @@ Untracked files:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --ignore-submodules=all > output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success '.gitmodules ignore=all suppresses unstaged submodule summary' '
@@ -1460,7 +1460,7 @@ EOF
 	git config --add -f .gitmodules submodule.subname.ignore all &&
 	git config --add -f .gitmodules submodule.subname.path sm &&
 	git status > output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
 
@@ -1470,7 +1470,7 @@ test_expect_success '.git/config ignore=all suppresses unstaged submodule summar
 	git config --add submodule.subname.ignore all &&
 	git config --add submodule.subname.path sm &&
 	git status > output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git config --remove-section submodule.subname &&
 	git config -f .gitmodules  --remove-section submodule.subname
 '
@@ -1571,7 +1571,7 @@ Changes not staged for commit:
 Untracked files not listed (use -u option to show untracked files)
 EOF
 	git commit -uno --dry-run >output &&
-	test_i18ncmp expect output &&
+	test_cmp expect output &&
 	git status -s --ignore-submodules=dirty >output &&
 	test_i18ngrep "^M. sm" output
 '
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index 9f5e3ce7931..7f2956d77ad 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -41,7 +41,7 @@ Unmerged paths:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -61,7 +61,7 @@ Changes to be committed:
 Untracked files not listed (use -u option to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -93,7 +93,7 @@ Unmerged paths:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -116,7 +116,7 @@ Changes to be committed:
 Untracked files not listed (use -u option to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -154,7 +154,7 @@ Unmerged paths:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -180,7 +180,7 @@ Changes to be committed:
 Untracked files not listed (use -u option to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -210,7 +210,7 @@ You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' o
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -249,7 +249,7 @@ Changes not staged for commit:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -282,7 +282,7 @@ You are currently editing a commit while rebasing branch '\''amend_last'\'' on '
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -321,7 +321,7 @@ You are currently editing a commit while rebasing branch '\''several_edits'\'' o
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -356,7 +356,7 @@ Changes not staged for commit:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -387,7 +387,7 @@ You are currently editing a commit while rebasing branch '\''several_edits'\'' o
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -418,7 +418,7 @@ You are currently editing a commit while rebasing branch '\''several_edits'\'' o
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -454,7 +454,7 @@ Changes not staged for commit:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -486,7 +486,7 @@ You are currently editing a commit while rebasing branch '\''several_edits'\'' o
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -519,7 +519,7 @@ You are currently editing a commit while rebasing branch '\''several_edits'\'' o
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -557,7 +557,7 @@ Changes not staged for commit:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -591,7 +591,7 @@ You are currently editing a commit while rebasing branch '\''several_edits'\'' o
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -619,7 +619,7 @@ You are in the middle of an am session.
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -641,7 +641,7 @@ You are in the middle of an am session.
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -664,7 +664,7 @@ The current patch is empty.
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -687,7 +687,7 @@ You are currently bisecting, started from branch '\''bisect'\''.
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -712,7 +712,7 @@ Unmerged paths:
 no changes added to commit
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -746,7 +746,7 @@ Unmerged paths:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 
@@ -770,7 +770,7 @@ Changes to be committed:
 Untracked files not listed (use -u option to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status when cherry-picking after committing conflict resolution' '
@@ -789,7 +789,7 @@ Cherry-pick currently in progress.
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status shows cherry-pick with invalid oid' '
@@ -798,7 +798,7 @@ test_expect_success 'status shows cherry-pick with invalid oid' '
 	git status --untracked-files=no >actual 2>err &&
 	git cherry-pick --quit &&
 	test_must_be_empty err &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status does not show error if .git/sequencer is a file' '
@@ -816,7 +816,7 @@ HEAD detached at atag
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual &&
+	test_cmp expected actual &&
 
 	git reset --hard HEAD^ &&
 	cat >expected <<\EOF &&
@@ -824,7 +824,7 @@ HEAD detached from atag
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status while reverting commit (conflicts)' '
@@ -852,7 +852,7 @@ Unmerged paths:
 no changes added to commit (use "git add" and/or "git commit -a")
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status while reverting commit (conflicts resolved)' '
@@ -872,7 +872,7 @@ Changes to be committed:
 Untracked files not listed (use -u option to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status after reverting commit' '
@@ -882,7 +882,7 @@ On branch main
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status while reverting after committing conflict resolution' '
@@ -901,7 +901,7 @@ Revert currently in progress.
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'prepare for different number of commits rebased' '
@@ -931,7 +931,7 @@ You are currently editing a commit while rebasing branch '\''several_commits'\''
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status: two commands done with some white lines in done file' '
@@ -959,7 +959,7 @@ You are currently editing a commit while rebasing branch '\''several_commits'\''
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status: two remaining commands with some white lines in todo file' '
@@ -988,7 +988,7 @@ You are currently editing a commit while rebasing branch '\''several_commits'\''
 nothing to commit (use -u to show untracked files)
 EOF
 	git status --untracked-files=no >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_expect_success 'status: handle not-yet-started rebase -i gracefully' '
@@ -1007,7 +1007,7 @@ You are currently editing a commit while rebasing branch '\''several_commits'\''
 
 nothing to commit (use -u to show untracked files)
 EOF
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_done
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index fbfdcca0007..45d025f9601 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -236,7 +236,7 @@ test_expect_success 'refresh_index() invalidates fsmonitor cache' '
 	git reset HEAD~1 &&
 	git status >actual &&
 	git -c core.fsmonitor= status >expect &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 # test fsmonitor with and without preloadIndex
@@ -273,7 +273,7 @@ do
 			git add dir2/new &&
 			git status >actual &&
 			git -c core.fsmonitor= status >expect &&
-			test_i18ncmp expect actual
+			test_cmp expect actual
 		'
 
 		# Make sure it's actually skipping the check for modified and untracked
diff --git a/t/t7521-ignored-mode.sh b/t/t7521-ignored-mode.sh
index 91790943c3d..a88b02b06ed 100755
--- a/t/t7521-ignored-mode.sh
+++ b/t/t7521-ignored-mode.sh
@@ -30,7 +30,7 @@ test_expect_success 'Verify behavior of status on directories with ignored files
 		dir/ignored/ignored_1.ign dir/ignored/ignored_2.ign &&
 
 	git status --porcelain=v2 --ignored=matching --untracked-files=all >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify status behavior on directory with tracked & ignored files' '
@@ -55,7 +55,7 @@ test_expect_success 'Verify status behavior on directory with tracked & ignored
 	git commit -m "commit tracked files" &&
 
 	git status --porcelain=v2 --ignored=matching --untracked-files=all >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify status behavior on directory with untracked and ignored files' '
@@ -80,7 +80,7 @@ test_expect_success 'Verify status behavior on directory with untracked and igno
 		dir/untracked_ignored/ignored_1.ign dir/untracked_ignored/ignored_2.ign &&
 
 	git status --porcelain=v2 --ignored=matching --untracked-files=all >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify status matching ignored files on ignored directory' '
@@ -96,7 +96,7 @@ test_expect_success 'Verify status matching ignored files on ignored directory'
 		ignored_dir/ignored_1.ign ignored_dir/ignored_2.ign &&
 
 	git status --porcelain=v2 --ignored=matching --untracked-files=all >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify status behavior on ignored directory containing tracked file' '
@@ -117,7 +117,7 @@ test_expect_success 'Verify status behavior on ignored directory containing trac
 	git add -f ignored_dir/tracked &&
 	git commit -m "Force add file in ignored directory" &&
 	git status --porcelain=v2 --ignored=matching --untracked-files=all >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify matching ignored files with --untracked-files=normal' '
@@ -136,7 +136,7 @@ test_expect_success 'Verify matching ignored files with --untracked-files=normal
 		ignored_files/ignored_1.ign ignored_files/ignored_2.ign \
 		untracked_dir/untracked &&
 	git status --porcelain=v2 --ignored=matching --untracked-files=normal >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify matching ignored files with --untracked-files=normal' '
@@ -155,7 +155,7 @@ test_expect_success 'Verify matching ignored files with --untracked-files=normal
 		ignored_files/ignored_1.ign ignored_files/ignored_2.ign \
 		untracked_dir/untracked &&
 	git status --porcelain=v2 --ignored=matching --untracked-files=normal >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify status behavior on ignored directory containing tracked file' '
@@ -176,7 +176,7 @@ test_expect_success 'Verify status behavior on ignored directory containing trac
 	git add -f ignored_dir/tracked &&
 	git commit -m "Force add file in ignored directory" &&
 	git status --porcelain=v2 --ignored=matching --untracked-files=normal >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify behavior of status with --ignored=no' '
@@ -191,7 +191,7 @@ test_expect_success 'Verify behavior of status with --ignored=no' '
 		dir/ignored/ignored_1.ign dir/ignored/ignored_2.ign &&
 
 	git status --porcelain=v2 --ignored=no --untracked-files=all >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify behavior of status with --ignored=traditional and --untracked-files=all' '
@@ -210,7 +210,7 @@ test_expect_success 'Verify behavior of status with --ignored=traditional and --
 		dir/ignored/ignored_1.ign dir/ignored/ignored_2.ign &&
 
 	git status --porcelain=v2 --ignored=traditional --untracked-files=all >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_expect_success 'Verify behavior of status with --ignored=traditional and --untracked-files=normal' '
@@ -227,7 +227,7 @@ test_expect_success 'Verify behavior of status with --ignored=traditional and --
 		dir/ignored/ignored_1.ign dir/ignored/ignored_2.ign &&
 
 	git status --porcelain=v2 --ignored=traditional --untracked-files=normal >output &&
-	test_i18ncmp expect output
+	test_cmp expect output
 '
 
 test_done
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index b2c1d861dcb..1cbc9715a81 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -272,7 +272,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '
 	EOF
 	git cat-file commit HEAD >raw &&
 	sed -e "1,/^$/d" raw >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' '
@@ -296,7 +296,7 @@ test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' '
 	EOF
 	git cat-file commit HEAD >raw &&
 	sed -e "1,/^$/d" raw >actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_debug 'git log --graph --decorate --oneline --all'
diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh
index 13859ec8595..a9c816b47f2 100755
--- a/t/t7602-merge-octopus-many.sh
+++ b/t/t7602-merge-octopus-many.sh
@@ -66,7 +66,7 @@ EOF
 test_expect_success 'merge output uses pretty names' '
 	git reset --hard c1 &&
 	git merge c2 c3 c4 >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 cat >expected <<\EOF
@@ -84,7 +84,7 @@ test_expect_success 'merge reduces irrelevant remote heads' '
 		rm expected.tmp
 	fi &&
 	GIT_MERGE_VERBOSITY=0 git merge c4 c5 >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 cat >expected <<\EOF
@@ -101,7 +101,7 @@ EOF
 test_expect_success 'merge fast-forward output uses pretty names' '
 	git reset --hard c0 &&
 	git merge c1 c2 >actual &&
-	test_i18ncmp expected actual
+	test_cmp expected actual
 '
 
 test_done
-- 
2.30.0.284.gd98b1dd5eaa7


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

* Re: [PATCH 4/4] tests: remove most uses of test_i18ncmp
  2021-02-11  1:53                               ` [PATCH 4/4] tests: remove most uses of test_i18ncmp Ævar Arnfjörð Bjarmason
@ 2021-02-11 17:32                                 ` Junio C Hamano
  2021-02-13 14:31                                   ` Ævar Arnfjörð Bjarmason
  2021-02-19 21:25                                   ` Jonathan Nieder
  2021-04-13 12:19                                 ` [PATCH] tests: remove all uses of test_i18cmp Ævar Arnfjörð Bjarmason
  1 sibling, 2 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-02-11 17:32 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Johannes Schindelin, SZEDER Gábor, Jiang Xin

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> As a follow-up to d162b25f956 (tests: remove support for
> GIT_TEST_GETTEXT_POISON, 2021-01-20) remove most uses of test_i18ncmp
> via a simple s/test_i18ncmp/test_cmp/g search-replacement.

I am a bit hesitant to take this step, primarily because the
distinction between test_cmp and test_i18ncmp is serving as a sign
for tests to identify if they are dealing with translatable messages
or plumbing/machine-readable messages.

If a totally different approach to test i18n messging part
(e.g. Dscho's rot13) appears any time soon, it would be helpful to
leave these distinction in, rather than ripping them out, with two
caveats.

 - If such a change does happen soon enough, then the codebase this
   huge patch touches would not be all that different by the time
   when it happens, so reverting this patch should not be too
   involved, which means my hesitation is not all that warranted.

 - If such a change does not happen for some time, then it would
   become impractical to revert this patch when it does happen due
   to changes in the codebase, if we apply it with the intention of
   "we can easily revert if we need to".  But even if we drop this
   step, until such a change appears, we surely will gain more calls
   to test_cmp (and possibly test_i18ncmp) in the codebase, and at
   that point, we can trust the distinction between test_cmp and
   test_i18ncmp even less, which means it does not help all that
   much if we tried to keep test_i18ncmp.

So, perhaps we should bite the bullet and just take this step.



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

* Re: [PATCH 4/4] tests: remove most uses of test_i18ncmp
  2021-02-11 17:32                                 ` Junio C Hamano
@ 2021-02-13 14:31                                   ` Ævar Arnfjörð Bjarmason
  2021-02-19 21:25                                   ` Jonathan Nieder
  1 sibling, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-02-13 14:31 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Schindelin, SZEDER Gábor, Jiang Xin, Jeff King


On Thu, Feb 11 2021, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
>
>> As a follow-up to d162b25f956 (tests: remove support for
>> GIT_TEST_GETTEXT_POISON, 2021-01-20) remove most uses of test_i18ncmp
>> via a simple s/test_i18ncmp/test_cmp/g search-replacement.
>
> I am a bit hesitant to take this step, primarily because the
> distinction between test_cmp and test_i18ncmp is serving as a sign
> for tests to identify if they are dealing with translatable messages
> or plumbing/machine-readable messages.
>
> If a totally different approach to test i18n messging part
> (e.g. Dscho's rot13) appears any time soon, it would be helpful to
> leave these distinction in, rather than ripping them out, with two
> caveats.
>
>  - If such a change does happen soon enough, then the codebase this
>    huge patch touches would not be all that different by the time
>    when it happens, so reverting this patch should not be too
>    involved, which means my hesitation is not all that warranted.
>
>  - If such a change does not happen for some time, then it would
>    become impractical to revert this patch when it does happen due
>    to changes in the codebase, if we apply it with the intention of
>    "we can easily revert if we need to".  But even if we drop this
>    step, until such a change appears, we surely will gain more calls
>    to test_cmp (and possibly test_i18ncmp) in the codebase, and at
>    that point, we can trust the distinction between test_cmp and
>    test_i18ncmp even less, which means it does not help all that
>    much if we tried to keep test_i18ncmp.
>
> So, perhaps we should bite the bullet and just take this step.

I think it either makes sense to take this series as a whole, or not
take any of it and also revert the already merged 73c01d25fe (tests:
remove uses of GIT_TEST_GETTEXT_POISON=false, 2021-01-20).

I.e. if we're going to not remove test_i18ncmp uses then we should leave
C_LOCALE_OUTPUT & GIT_TEST_GETTEXT_POISON=false alone as well (or
convert them to the test_i18n* forms).

As noted before I'm not invested in the outcome here, I just submitted
this to not leave the obvious post-cleanup undone.

My reading of the list discussion/consensus[1] (such as it was) was that
even if we had this rot13 mode ready we wouldn't think it's worth the
time investment overall, hence the follow-up patches.

Also, if we have it down the line we're probably better off with these
patches. The parts that'll revert cleanly can likely be resurrected
as-is, but conflicts would be a good thing, as that code needs to be
looked at anyway (it will be re-arranged tests that never used
GETTEXT_POISON in their current form).

We also won't have cargo-culting in the meantime, with new code using
test_i18ncmp or whatever just because the test above them did.

1. https://lore.kernel.org/git/20210120182759.31102-1-avarab@gmail.com/

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

* Re: [PATCH 4/4] tests: remove most uses of test_i18ncmp
  2021-02-11 17:32                                 ` Junio C Hamano
  2021-02-13 14:31                                   ` Ævar Arnfjörð Bjarmason
@ 2021-02-19 21:25                                   ` Jonathan Nieder
  1 sibling, 0 replies; 229+ messages in thread
From: Jonathan Nieder @ 2021-02-19 21:25 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Ævar Arnfjörð Bjarmason, git, Johannes Schindelin,
	SZEDER Gábor, Jiang Xin

Junio C Hamano wrote:
> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

>> As a follow-up to d162b25f956 (tests: remove support for
>> GIT_TEST_GETTEXT_POISON, 2021-01-20) remove most uses of test_i18ncmp
>> via a simple s/test_i18ncmp/test_cmp/g search-replacement.
>
> I am a bit hesitant to take this step, primarily because the
> distinction between test_cmp and test_i18ncmp is serving as a sign
> for tests to identify if they are dealing with translatable messages
> or plumbing/machine-readable messages.

I agree: in particular, I would value the ability to run tests with,
say, LANG=fr_CH.UTF-8 and catch localization-specific issues that way.
Removing the test_i18ncmp helper removes that ability.

That said:

[...]
> So, perhaps we should bite the bullet and just take this step.

If we don't have a convenient way to keep "testing the testsuite"
(i.e., some kind of CI run that uses a locale other than C), then I
agree that explicitly removing the test_i18ncmp / test_cmp distinction
is better than letting it bitrot.

Thanks,
Jonathan

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

* [PATCH] mktag tests: fix broken "&&" chain
  2021-02-11  1:53                               ` [PATCH 1/4] tests: remove last uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
@ 2021-03-07 13:29                                 ` Ævar Arnfjörð Bjarmason
  2021-03-07 16:36                                   ` SZEDER Gábor
                                                     ` (2 more replies)
  0 siblings, 3 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-03-07 13:29 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Eric Sunshine, Ævar Arnfjörð Bjarmason

Remove a stray "xb" I inadvertently introduced in 780aa0a21e0 (tests:
remove last uses of GIT_TEST_GETTEXT_POISON=false, 2021-02-11). This
would have been a failed attempt to type "C-x C-b" that snuck into the
code.

The chainlint check did not catch this one, but I don't know where to
start patching the wall-of-sed that is chainlint.sed to fix that.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3800-mktag.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 60a666da595..6275c98523f 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -17,7 +17,7 @@ check_verify_failure () {
 		grep '$2' message &&
 		if test '$3' != '--no-strict'
 		then
-			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&xb
+			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&
 			grep '$2' message.no-strict
 		fi
 	"
-- 
2.31.0.rc0.126.g04f22c5b82


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

* Re: [PATCH] mktag tests: fix broken "&&" chain
  2021-03-07 13:29                                 ` [PATCH] mktag tests: fix broken "&&" chain Ævar Arnfjörð Bjarmason
@ 2021-03-07 16:36                                   ` SZEDER Gábor
  2021-03-07 20:43                                   ` Junio C Hamano
  2021-03-24  2:11                                   ` [PATCH v2] " Ævar Arnfjörð Bjarmason
  2 siblings, 0 replies; 229+ messages in thread
From: SZEDER Gábor @ 2021-03-07 16:36 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Junio C Hamano, Eric Sunshine

On Sun, Mar 07, 2021 at 02:29:05PM +0100, Ævar Arnfjörð Bjarmason wrote:
> Remove a stray "xb" I inadvertently introduced in 780aa0a21e0 (tests:
> remove last uses of GIT_TEST_GETTEXT_POISON=false, 2021-02-11). This
> would have been a failed attempt to type "C-x C-b" that snuck into the
> code.
> 
> The chainlint check did not catch this one, but I don't know where to
> start patching the wall-of-sed that is chainlint.sed to fix that.

Chain-lint only checks 'test_expect_{success,failure}' blocks, but
this && chain is in a helper function.

> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t3800-mktag.sh | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index 60a666da595..6275c98523f 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -17,7 +17,7 @@ check_verify_failure () {
>  		grep '$2' message &&
>  		if test '$3' != '--no-strict'
>  		then
> -			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&xb
> +			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&
>  			grep '$2' message.no-strict
>  		fi
>  	"
> -- 
> 2.31.0.rc0.126.g04f22c5b82
> 

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

* Re: [PATCH] mktag tests: fix broken "&&" chain
  2021-03-07 13:29                                 ` [PATCH] mktag tests: fix broken "&&" chain Ævar Arnfjörð Bjarmason
  2021-03-07 16:36                                   ` SZEDER Gábor
@ 2021-03-07 20:43                                   ` Junio C Hamano
  2021-03-07 20:52                                     ` Eric Sunshine
  2021-03-24  2:11                                   ` [PATCH v2] " Ævar Arnfjörð Bjarmason
  2 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2021-03-07 20:43 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Eric Sunshine

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Remove a stray "xb" I inadvertently introduced in 780aa0a21e0 (tests:
> remove last uses of GIT_TEST_GETTEXT_POISON=false, 2021-02-11). This
> would have been a failed attempt to type "C-x C-b" that snuck into the
> code.
>
> The chainlint check did not catch this one, but I don't know where to
> start patching the wall-of-sed that is chainlint.sed to fix that.

I do not think the chainlint check is designed to deal with helper
functions, but I wonder why nobody noticed a runtime failure.  Is
this an unused/dead codepath?


> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t3800-mktag.sh | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
> index 60a666da595..6275c98523f 100755
> --- a/t/t3800-mktag.sh
> +++ b/t/t3800-mktag.sh
> @@ -17,7 +17,7 @@ check_verify_failure () {
>  		grep '$2' message &&
>  		if test '$3' != '--no-strict'
>  		then
> -			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&xb
> +			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&
>  			grep '$2' message.no-strict
>  		fi
>  	"

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

* Re: [PATCH] mktag tests: fix broken "&&" chain
  2021-03-07 20:43                                   ` Junio C Hamano
@ 2021-03-07 20:52                                     ` Eric Sunshine
  0 siblings, 0 replies; 229+ messages in thread
From: Eric Sunshine @ 2021-03-07 20:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Ævar Arnfjörð Bjarmason, Git List

On Sun, Mar 7, 2021 at 3:43 PM Junio C Hamano <gitster@pobox.com> wrote:
> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:
> > -                     test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&xb
> > +                     test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&
> >                       grep '$2' message.no-strict
>
> I do not think the chainlint check is designed to deal with helper
> functions, but I wonder why nobody noticed a runtime failure.  Is
> this an unused/dead codepath?

The `git mktag` invocation would still have produced the expected
stderr output regardless of what happens later (by "later", I mean the
failing invocation of the non-existent `xb` command), which means that
the subsequent `grep` will find what it's looking for, making the
function succeed as expected.

Someone looking at the verbose output might have had a chance of
spotting the "xp: not found" error message, but there likely wasn't
any reason to scan the verbose output since the test succeeded.

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

* [PATCH v2] mktag tests: fix broken "&&" chain
  2021-03-07 13:29                                 ` [PATCH] mktag tests: fix broken "&&" chain Ævar Arnfjörð Bjarmason
  2021-03-07 16:36                                   ` SZEDER Gábor
  2021-03-07 20:43                                   ` Junio C Hamano
@ 2021-03-24  2:11                                   ` Ævar Arnfjörð Bjarmason
  2021-03-24 19:57                                     ` Junio C Hamano
  2 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-03-24  2:11 UTC (permalink / raw)
  To: git
  Cc: Junio C Hamano, ric Sunshine, SZEDER Gábor,
	Ævar Arnfjörð Bjarmason

Remove a stray "xb" I inadvertently introduced in 780aa0a21e0 (tests:
remove last uses of GIT_TEST_GETTEXT_POISON=false, 2021-02-11).

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---

A v2 of a stray patch of mine that wasn't picked up during the release window.

Range-diff:
1:  bd8235ead3c ! 1:  0b43e43b949 mktag tests: fix broken "&&" chain
    @@ Commit message
         mktag tests: fix broken "&&" chain
     
         Remove a stray "xb" I inadvertently introduced in 780aa0a21e0 (tests:
    -    remove last uses of GIT_TEST_GETTEXT_POISON=false, 2021-02-11). This
    -    would have been a failed attempt to type "C-x C-b" that snuck into the
    -    code.
    -
    -    The chainlint check did not catch this one, but I don't know where to
    -    start patching the wall-of-sed that is chainlint.sed to fix that.
    +    remove last uses of GIT_TEST_GETTEXT_POISON=false, 2021-02-11).
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     

 t/t3800-mktag.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 60a666da595..6275c98523f 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -17,7 +17,7 @@ check_verify_failure () {
 		grep '$2' message &&
 		if test '$3' != '--no-strict'
 		then
-			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&xb
+			test_must_fail git mktag --no-strict <tag.sig 2>message.no-strict &&
 			grep '$2' message.no-strict
 		fi
 	"
-- 
2.31.0.354.gc8cbd507b5a


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

* Re: [PATCH v2] mktag tests: fix broken "&&" chain
  2021-03-24  2:11                                   ` [PATCH v2] " Ævar Arnfjörð Bjarmason
@ 2021-03-24 19:57                                     ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-03-24 19:57 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, ric Sunshine, SZEDER Gábor

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Remove a stray "xb" I inadvertently introduced in 780aa0a21e0 (tests:
> remove last uses of GIT_TEST_GETTEXT_POISON=false, 2021-02-11).

Thanks.

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

* [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON
  2021-01-11 14:47                           ` [PATCH 2/6] tests: remove support for GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
  2021-01-11 21:54                             ` Junio C Hamano
@ 2021-03-24 23:36                             ` Ævar Arnfjörð Bjarmason
  2021-03-25  0:36                               ` Jeff King
  2021-04-08 13:25                               ` [PATCH v2] " Ævar Arnfjörð Bjarmason
  1 sibling, 2 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-03-24 23:36 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Remove a use of GIT_TEST_GETTEXT_POISON added in f276e2a4694 (config:
improve error message for boolean config, 2021-02-11).

This was simultaneously in-flight with my d162b25f956 (tests: remove
support for GIT_TEST_GETTEXT_POISON, 2021-01-20) which removed the
rest of the GIT_TEST_GETTEXT_POISON code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---

At this point I'm going to call it a win if I'm not submitting a patch
in 2022 to remove some more stray GETTEXT_POISON ... :)

 config.c          | 16 +---------------
 t/t1300-config.sh |  2 +-
 2 files changed, 2 insertions(+), 16 deletions(-)

diff --git a/config.c b/config.c
index 6428393a414..870d9534def 100644
--- a/config.c
+++ b/config.c
@@ -1180,20 +1180,6 @@ static void die_bad_number(const char *name, const char *value)
 	}
 }
 
-NORETURN
-static void die_bad_bool(const char *name, const char *value)
-{
-	if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
-		/*
-		 * We explicitly *don't* use _() here since it would
-		 * cause an infinite loop with _() needing to call
-		 * use_gettext_poison().
-		 */
-		die("bad boolean config value '%s' for '%s'", value, name);
-	else
-		die(_("bad boolean config value '%s' for '%s'"), value, name);
-}
-
 int git_config_int(const char *name, const char *value)
 {
 	int ret;
@@ -1268,7 +1254,7 @@ int git_config_bool(const char *name, const char *value)
 {
 	int v = git_parse_maybe_bool(value);
 	if (v < 0)
-		die_bad_bool(name, value);
+		die(_("bad boolean config value '%s' for '%s'"), value, name);
 	return v;
 }
 
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index e0dd5d65ced..2280c2504ac 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -679,7 +679,7 @@ test_expect_success 'invalid unit boolean' '
 	git config commit.gpgsign "1true" &&
 	test_cmp_config 1true commit.gpgsign &&
 	test_must_fail git config --bool --get commit.gpgsign 2>actual &&
-	test_i18ngrep "bad boolean config value .1true. for .commit.gpgsign." actual
+	grep "bad boolean config value .1true. for .commit.gpgsign." actual
 '
 
 test_expect_success 'line number is reported correctly' '
-- 
2.31.0.354.gc8cbd507b5a


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

* Re: [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON
  2021-03-24 23:36                             ` [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
@ 2021-03-25  0:36                               ` Jeff King
  2021-03-25  1:13                                 ` Ævar Arnfjörð Bjarmason
  2021-04-08 13:25                               ` [PATCH v2] " Ævar Arnfjörð Bjarmason
  1 sibling, 1 reply; 229+ messages in thread
From: Jeff King @ 2021-03-25  0:36 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Junio C Hamano

On Thu, Mar 25, 2021 at 12:36:09AM +0100, Ævar Arnfjörð Bjarmason wrote:

> Remove a use of GIT_TEST_GETTEXT_POISON added in f276e2a4694 (config:
> improve error message for boolean config, 2021-02-11).
> 
> This was simultaneously in-flight with my d162b25f956 (tests: remove
> support for GIT_TEST_GETTEXT_POISON, 2021-01-20) which removed the
> rest of the GIT_TEST_GETTEXT_POISON code.

Yay. :)

> diff --git a/config.c b/config.c
> index 6428393a414..870d9534def 100644
> --- a/config.c
> +++ b/config.c
> @@ -1180,20 +1180,6 @@ static void die_bad_number(const char *name, const char *value)
>  	}
>  }
>  
> -NORETURN
> -static void die_bad_bool(const char *name, const char *value)
> -{
> -	if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
> -		/*
> -		 * We explicitly *don't* use _() here since it would
> -		 * cause an infinite loop with _() needing to call
> -		 * use_gettext_poison().
> -		 */
> -		die("bad boolean config value '%s' for '%s'", value, name);
> -	else
> -		die(_("bad boolean config value '%s' for '%s'"), value, name);
> -}
> -
>  int git_config_int(const char *name, const char *value)
>  {
>  	int ret;
> @@ -1268,7 +1254,7 @@ int git_config_bool(const char *name, const char *value)
>  {
>  	int v = git_parse_maybe_bool(value);
>  	if (v < 0)
> -		die_bad_bool(name, value);
> +		die(_("bad boolean config value '%s' for '%s'"), value, name);
>  	return v;
>  }

This code change looks good, but...

> diff --git a/t/t1300-config.sh b/t/t1300-config.sh
> index e0dd5d65ced..2280c2504ac 100755
> --- a/t/t1300-config.sh
> +++ b/t/t1300-config.sh
> @@ -679,7 +679,7 @@ test_expect_success 'invalid unit boolean' '
>  	git config commit.gpgsign "1true" &&
>  	test_cmp_config 1true commit.gpgsign &&
>  	test_must_fail git config --bool --get commit.gpgsign 2>actual &&
> -	test_i18ngrep "bad boolean config value .1true. for .commit.gpgsign." actual
> +	grep "bad boolean config value .1true. for .commit.gpgsign." actual
>  '

why are we losing test_i18ngrep here? The message is still marked for
translation. I know we've discussed dropping all of the test_i18n
helpers, but that seems unrelated to the rest of the patch.

-Peff

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

* Re: [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON
  2021-03-25  0:36                               ` Jeff King
@ 2021-03-25  1:13                                 ` Ævar Arnfjörð Bjarmason
  2021-03-25 20:02                                   ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-03-25  1:13 UTC (permalink / raw)
  To: Jeff King; +Cc: git, Junio C Hamano


On Thu, Mar 25 2021, Jeff King wrote:

> On Thu, Mar 25, 2021 at 12:36:09AM +0100, Ævar Arnfjörð Bjarmason wrote:
>
>> Remove a use of GIT_TEST_GETTEXT_POISON added in f276e2a4694 (config:
>> improve error message for boolean config, 2021-02-11).
>> 
>> This was simultaneously in-flight with my d162b25f956 (tests: remove
>> support for GIT_TEST_GETTEXT_POISON, 2021-01-20) which removed the
>> rest of the GIT_TEST_GETTEXT_POISON code.
>
> Yay. :)
>
>> diff --git a/config.c b/config.c
>> index 6428393a414..870d9534def 100644
>> --- a/config.c
>> +++ b/config.c
>> @@ -1180,20 +1180,6 @@ static void die_bad_number(const char *name, const char *value)
>>  	}
>>  }
>>  
>> -NORETURN
>> -static void die_bad_bool(const char *name, const char *value)
>> -{
>> -	if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
>> -		/*
>> -		 * We explicitly *don't* use _() here since it would
>> -		 * cause an infinite loop with _() needing to call
>> -		 * use_gettext_poison().
>> -		 */
>> -		die("bad boolean config value '%s' for '%s'", value, name);
>> -	else
>> -		die(_("bad boolean config value '%s' for '%s'"), value, name);
>> -}
>> -
>>  int git_config_int(const char *name, const char *value)
>>  {
>>  	int ret;
>> @@ -1268,7 +1254,7 @@ int git_config_bool(const char *name, const char *value)
>>  {
>>  	int v = git_parse_maybe_bool(value);
>>  	if (v < 0)
>> -		die_bad_bool(name, value);
>> +		die(_("bad boolean config value '%s' for '%s'"), value, name);
>>  	return v;
>>  }
>
> This code change looks good, but...
>
>> diff --git a/t/t1300-config.sh b/t/t1300-config.sh
>> index e0dd5d65ced..2280c2504ac 100755
>> --- a/t/t1300-config.sh
>> +++ b/t/t1300-config.sh
>> @@ -679,7 +679,7 @@ test_expect_success 'invalid unit boolean' '
>>  	git config commit.gpgsign "1true" &&
>>  	test_cmp_config 1true commit.gpgsign &&
>>  	test_must_fail git config --bool --get commit.gpgsign 2>actual &&
>> -	test_i18ngrep "bad boolean config value .1true. for .commit.gpgsign." actual
>> +	grep "bad boolean config value .1true. for .commit.gpgsign." actual
>>  '
>
> why are we losing test_i18ngrep here? The message is still marked for
> translation. I know we've discussed dropping all of the test_i18n
> helpers, but that seems unrelated to the rest of the patch.

For new tests we're suggesting not to use it, so while I'm holding off
on some general s/test_i18ngrep/grep/ refactoring, it seemed natural to
adjust the test added by the commit whose code I'm modifying.

It also shows reviewers that there is such a test, so e.g. I didn't
invert the name/value parameters or something in refactoring this.

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

* Re: [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON
  2021-03-25  1:13                                 ` Ævar Arnfjörð Bjarmason
@ 2021-03-25 20:02                                   ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-03-25 20:02 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: Jeff King, git

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

>>> diff --git a/t/t1300-config.sh b/t/t1300-config.sh
>>> index e0dd5d65ced..2280c2504ac 100755
>>> --- a/t/t1300-config.sh
>>> +++ b/t/t1300-config.sh
>>> @@ -679,7 +679,7 @@ test_expect_success 'invalid unit boolean' '
>>>  	git config commit.gpgsign "1true" &&
>>>  	test_cmp_config 1true commit.gpgsign &&
>>>  	test_must_fail git config --bool --get commit.gpgsign 2>actual &&
>>> -	test_i18ngrep "bad boolean config value .1true. for .commit.gpgsign." actual
>>> +	grep "bad boolean config value .1true. for .commit.gpgsign." actual
>>>  '
>>
>> why are we losing test_i18ngrep here? The message is still marked for
>> translation. I know we've discussed dropping all of the test_i18n
>> helpers, but that seems unrelated to the rest of the patch.
>
> For new tests we're suggesting not to use it, so while I'm holding off
> on some general s/test_i18ngrep/grep/ refactoring, it seemed natural to
> adjust the test added by the commit whose code I'm modifying.

It would have been understandable if the proposed log message said

    Remove a use of GIT_TEST_GETTEXT_POISON added in f276e2a4694 (config:
    improve error message for boolean config, 2021-02-11), together with
    a new test added.

and removed the test.

But the test still has value for the remaining codebase, just like
all the other tests that happen to use test_i18n{grep,cmp}.  In a
sense, the original mixed two separate things into one commit
(i.e. use of TEST_GETTEXT_POISON to decide if the message given to
die() is localized, and a test to see how "git config --bool --get"
behaves when a malformed boolean value is given), and that may have
been justifiable back in the world where GETTEXT_POISON was a thing,
making these two things closely interrelated.  Since we left that
world behind, I think we should treat them as two separate things.

In short, I do not think "The C code we are removing was added in
the same commit" is a good excuse for this "while at it" change.

Putting it another way, imagine back then there was the t1300 test
and there was no die_bad_bool().  The test may have been expecting
"bad numeric" or "invalid unit", with grep (with a known bug that
the test would not pass under GETTEXT_POISON).

In such an alternative past, the change you are reverting may have
been only to config.c to make the die(_()) work correctly with
GETTEXT_POISON, and turned grep to test_i18ngrep.  And your "we are
reverting the whole commit" may have made more sense.

But we are not living in such an alternative world.

Having said all that, I do not particularly care when, in which
exact commit, a use of test_i18n* in t/ among 1100+ of them lost
its i18n-ness (it just felt a bit out of place in this particular
commit, that's all).

Thanks.

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

* [PATCH v2] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON
  2021-03-24 23:36                             ` [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
  2021-03-25  0:36                               ` Jeff King
@ 2021-04-08 13:25                               ` Ævar Arnfjörð Bjarmason
  2021-04-08 17:55                                 ` Junio C Hamano
  1 sibling, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-08 13:25 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Remove a use of GIT_TEST_GETTEXT_POISON added in f276e2a4694 (config:
improve error message for boolean config, 2021-02-11).

This was simultaneously in-flight with my d162b25f956 (tests: remove
support for GIT_TEST_GETTEXT_POISON, 2021-01-20) which removed the
rest of the GIT_TEST_GETTEXT_POISON code.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---

This trivial cleanup now without the objectionable and needless change
to the tests.

Range-diff:
1:  ea968affa8 ! 1:  2b2ac8471f config.c: remove last remnant of GIT_TEST_GETTEXT_POISON
    @@ config.c: int git_config_bool(const char *name, const char *value)
      	return v;
      }
      
    -
    - ## t/t1300-config.sh ##
    -@@ t/t1300-config.sh: test_expect_success 'invalid unit boolean' '
    - 	git config commit.gpgsign "1true" &&
    - 	test_cmp_config 1true commit.gpgsign &&
    - 	test_must_fail git config --bool --get commit.gpgsign 2>actual &&
    --	test_i18ngrep "bad boolean config value .1true. for .commit.gpgsign." actual
    -+	grep "bad boolean config value .1true. for .commit.gpgsign." actual
    - '
    - 
    - test_expect_success 'line number is reported correctly' '

 config.c | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/config.c b/config.c
index 6428393a41..870d9534de 100644
--- a/config.c
+++ b/config.c
@@ -1180,20 +1180,6 @@ static void die_bad_number(const char *name, const char *value)
 	}
 }
 
-NORETURN
-static void die_bad_bool(const char *name, const char *value)
-{
-	if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
-		/*
-		 * We explicitly *don't* use _() here since it would
-		 * cause an infinite loop with _() needing to call
-		 * use_gettext_poison().
-		 */
-		die("bad boolean config value '%s' for '%s'", value, name);
-	else
-		die(_("bad boolean config value '%s' for '%s'"), value, name);
-}
-
 int git_config_int(const char *name, const char *value)
 {
 	int ret;
@@ -1268,7 +1254,7 @@ int git_config_bool(const char *name, const char *value)
 {
 	int v = git_parse_maybe_bool(value);
 	if (v < 0)
-		die_bad_bool(name, value);
+		die(_("bad boolean config value '%s' for '%s'"), value, name);
 	return v;
 }
 
-- 
2.31.1.527.g9b8f7de2547


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

* Re: [PATCH v2] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON
  2021-04-08 13:25                               ` [PATCH v2] " Ævar Arnfjörð Bjarmason
@ 2021-04-08 17:55                                 ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-04-08 17:55 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> Remove a use of GIT_TEST_GETTEXT_POISON added in f276e2a4694 (config:
> improve error message for boolean config, 2021-02-11).

Thanks.  Will queue.

>
> This was simultaneously in-flight with my d162b25f956 (tests: remove
> support for GIT_TEST_GETTEXT_POISON, 2021-01-20) which removed the
> rest of the GIT_TEST_GETTEXT_POISON code.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>
> This trivial cleanup now without the objectionable and needless change
> to the tests.
>
> Range-diff:
> 1:  ea968affa8 ! 1:  2b2ac8471f config.c: remove last remnant of GIT_TEST_GETTEXT_POISON
>     @@ config.c: int git_config_bool(const char *name, const char *value)
>       	return v;
>       }
>       
>     -
>     - ## t/t1300-config.sh ##
>     -@@ t/t1300-config.sh: test_expect_success 'invalid unit boolean' '
>     - 	git config commit.gpgsign "1true" &&
>     - 	test_cmp_config 1true commit.gpgsign &&
>     - 	test_must_fail git config --bool --get commit.gpgsign 2>actual &&
>     --	test_i18ngrep "bad boolean config value .1true. for .commit.gpgsign." actual
>     -+	grep "bad boolean config value .1true. for .commit.gpgsign." actual
>     - '
>     - 
>     - test_expect_success 'line number is reported correctly' '
>
>  config.c | 16 +---------------
>  1 file changed, 1 insertion(+), 15 deletions(-)
>
> diff --git a/config.c b/config.c
> index 6428393a41..870d9534de 100644
> --- a/config.c
> +++ b/config.c
> @@ -1180,20 +1180,6 @@ static void die_bad_number(const char *name, const char *value)
>  	}
>  }
>  
> -NORETURN
> -static void die_bad_bool(const char *name, const char *value)
> -{
> -	if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
> -		/*
> -		 * We explicitly *don't* use _() here since it would
> -		 * cause an infinite loop with _() needing to call
> -		 * use_gettext_poison().
> -		 */
> -		die("bad boolean config value '%s' for '%s'", value, name);
> -	else
> -		die(_("bad boolean config value '%s' for '%s'"), value, name);
> -}
> -
>  int git_config_int(const char *name, const char *value)
>  {
>  	int ret;
> @@ -1268,7 +1254,7 @@ int git_config_bool(const char *name, const char *value)
>  {
>  	int v = git_parse_maybe_bool(value);
>  	if (v < 0)
> -		die_bad_bool(name, value);
> +		die(_("bad boolean config value '%s' for '%s'"), value, name);
>  	return v;
>  }

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

* [PATCH] tests: remove all uses of test_i18cmp
  2021-02-11  1:53                               ` [PATCH 4/4] tests: remove most uses of test_i18ncmp Ævar Arnfjörð Bjarmason
  2021-02-11 17:32                                 ` Junio C Hamano
@ 2021-04-13 12:19                                 ` Ævar Arnfjörð Bjarmason
  2021-04-13 12:28                                   ` [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup Ævar Arnfjörð Bjarmason
  1 sibling, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-13 12:19 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Finish the removal I started in 1108cea7f8e (tests: remove most uses
of test_i18ncmp, 2021-02-11). At that time the function wasn't removed
due to disruption with in-flight changes, remove the occurrences that
have landed since then.

As of writing this there are no test_i18ncmp uses between "master" and
"seen", so let's also remove the function to finally put it to rest.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t3437-rebase-fixup-options.sh | 6 +++---
 t/t6300-for-each-ref.sh         | 6 +++---
 t/test-lib-functions.sh         | 7 -------
 3 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/t/t3437-rebase-fixup-options.sh b/t/t3437-rebase-fixup-options.sh
index d0bdc7ed02d..c023fefd681 100755
--- a/t/t3437-rebase-fixup-options.sh
+++ b/t/t3437-rebase-fixup-options.sh
@@ -157,7 +157,7 @@ test_expect_success 'sequence of fixup, fixup -C & squash --signoff works' '
 		git -c commit.status=false rebase -ik --signoff A &&
 	git diff-tree --exit-code --patch HEAD B3 -- &&
 	test_cmp_rev HEAD^ A &&
-	test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
+	test_cmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
 		actual-squash-message
 '
 
@@ -191,7 +191,7 @@ test_expect_success 'sequence squash, fixup & fixup -c gives combined message' '
 	FAKE_LINES="1 squash 2 fixup 3 fixup_-c 4" \
 		FAKE_MESSAGE_COPY=actual-combined-message \
 		git -c commit.status=false rebase -i A &&
-	test_i18ncmp "$TEST_DIRECTORY/t3437/expected-combined-message" \
+	test_cmp "$TEST_DIRECTORY/t3437/expected-combined-message" \
 		actual-combined-message &&
 	test_cmp_rev HEAD^ A
 '
@@ -204,7 +204,7 @@ test_expect_success 'fixup -C works upon --autosquash with amend!' '
 						--signoff A &&
 	git diff-tree --exit-code --patch HEAD B3 -- &&
 	test_cmp_rev HEAD^ A &&
-	test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
+	test_cmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
 		actual-squash-message
 '
 
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index cac7f443d00..7cfa934913b 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -945,9 +945,9 @@ test_failing_trailer_option () {
 	test_expect_success "$title" '
 		# error message cannot be checked under i18n
 		test_must_fail git for-each-ref --format="%($option)" refs/heads/main 2>actual &&
-		test_i18ncmp expect actual &&
+		test_cmp expect actual &&
 		test_must_fail git for-each-ref --format="%(contents:$option)" refs/heads/main 2>actual &&
-		test_i18ncmp expect actual
+		test_cmp expect actual
 	'
 }
 
@@ -966,7 +966,7 @@ test_expect_success 'if arguments, %(contents:trailers) shows error if colon is
 	fatal: unrecognized %(contents) argument: trailersonly
 	EOF
 	test_must_fail git for-each-ref --format="%(contents:trailersonly)" 2>actual &&
-	test_i18ncmp expect actual
+	test_cmp expect actual
 '
 
 test_expect_success 'basic atom: head contents:trailers' '
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 6348e8d7339..b823c140271 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1025,13 +1025,6 @@ test_cmp_bin () {
 	cmp "$@"
 }
 
-# Wrapper for test_cmp which used to be used for
-# GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other
-# in-flight changes. Should not be used and will be removed soon.
-test_i18ncmp () {
-	test_cmp "$@"
-}
-
 # Wrapper for grep which used to be used for
 # GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other
 # in-flight changes. Should not be used and will be removed soon.
-- 
2.31.1.646.g06d606cb9c7


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

* [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup
  2021-04-13 12:19                                 ` [PATCH] tests: remove all uses of test_i18cmp Ævar Arnfjörð Bjarmason
@ 2021-04-13 12:28                                   ` Ævar Arnfjörð Bjarmason
  2021-04-13 12:28                                     ` [PATCH 1/2] diff tests: remove redundant case statement Ævar Arnfjörð Bjarmason
                                                       ` (2 more replies)
  0 siblings, 3 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-13 12:28 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

In reply to [1] because they're related post-GETTEXT_POISON cleanup,
but both apply on top of master.

I had a flaky t4013 test with some local WIP code that I hadn't
investigated, as it turns out re-running the test was hiding the
failure. 2/2 fixes that, 1/2 is a minor post-GETTEXT_POISON cleanup.

1. https://lore.kernel.org/git/patch-1.1-f0542cd902c-20210413T121930Z-avarab@gmail.com 

Ævar Arnfjörð Bjarmason (2):
  diff tests: remove redundant case statement
  diff tests: rewrite flakyness-causing test "aid"

 t/t4013-diff-various.sh | 31 +++++++++++++++----------------
 1 file changed, 15 insertions(+), 16 deletions(-)

-- 
2.31.1.646.g06d606cb9c7


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

* [PATCH 1/2] diff tests: remove redundant case statement
  2021-04-13 12:28                                   ` [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup Ævar Arnfjörð Bjarmason
@ 2021-04-13 12:28                                     ` Ævar Arnfjörð Bjarmason
  2021-04-13 14:18                                       ` Matheus Tavares Bernardino
  2021-04-13 12:28                                     ` [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid" Ævar Arnfjörð Bjarmason
  2021-04-13 21:42                                     ` [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup Junio C Hamano
  2 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-13 12:28 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

Remove a case statement whose two arms executed the same code. This
was added for i18n testing in 6dd88832e77 (diffstat summary line
varies by locale: miscellany, 2012-03-13), and was changed from
test_i18ncmp in my 1108cea7f8e (tests: remove most uses of
test_i18ncmp, 2021-02-11).

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t4013-diff-various.sh | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 6cca8b84a6b..67f6411aff9 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -220,13 +220,7 @@ do
 		then
 			process_diffs "$actual" >actual &&
 			process_diffs "$expect" >expect &&
-			case $cmd in
-			*format-patch* | *-stat*)
-				test_cmp expect actual;;
-			*)
-				test_cmp expect actual;;
-			esac &&
-			rm -f "$actual" actual expect
+			test_cmp expect actual
 		else
 			# this is to help developing new tests.
 			cp "$actual" "$expect"
-- 
2.31.1.646.g06d606cb9c7


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

* [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-13 12:28                                   ` [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup Ævar Arnfjörð Bjarmason
  2021-04-13 12:28                                     ` [PATCH 1/2] diff tests: remove redundant case statement Ævar Arnfjörð Bjarmason
@ 2021-04-13 12:28                                     ` Ævar Arnfjörð Bjarmason
  2021-04-13 14:44                                       ` Matheus Tavares Bernardino
  2021-04-13 21:42                                     ` [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup Junio C Hamano
  2 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-13 12:28 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano, Ævar Arnfjörð Bjarmason

If a new test is added to this "while read magic cmd" test facility
added in 3c2f75b590c (t4013: add tests for diff/log family output
options., 2006-06-26) but no test file is added it'll fail the first
time, but then succeed on subsequent runs as a new file has been added
in t4013.

Let's accomplish the same aim in way that doesn't cause subsequent
test runs to succeed. If we can't find the file we'll BUG out, and
suggest to the developer that they copy our "expect.new" file over,
unlike the previous "expect" file this won't be picked up on
subsequent runs.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 t/t4013-diff-various.sh | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 67f6411aff9..228ff100c61 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -200,10 +200,12 @@ do
 	esac
 	test=$(echo "$label" | sed -e 's|[/ ][/ ]*|_|g')
 	pfx=$(printf "%04d" $test_count)
-	expect="$TEST_DIRECTORY/t4013/diff.$test"
+	expect_relative="t4013/diff.$test"
+	expect="$TEST_DIRECTORY/$expect_relative"
 	actual="$pfx-diff.$test"
 
 	test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
+		test_when_finished "rm $actual" &&
 		{
 			echo "$ git $cmd"
 			case "$magic" in
@@ -216,16 +218,19 @@ do
 			    -e "s/^\\(.*mixed; boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/"
 			echo "\$"
 		} >"$actual" &&
-		if test -f "$expect"
+
+		if ! test -f "$expect"
 		then
-			process_diffs "$actual" >actual &&
-			process_diffs "$expect" >expect &&
-			test_cmp expect actual
-		else
-			# this is to help developing new tests.
-			cp "$actual" "$expect"
-			false
-		fi
+			expect_new="$expect.new" &&
+			cp "$actual" "$expect_new" &&
+			BUG "Have no \"$expect_relative\", new test? The output is in \"$expect_new\", maybe use that?"
+		fi &&
+
+		test_when_finished "rm actual" &&
+		process_diffs "$actual" >actual &&
+		test_when_finished "rm expect" &&
+		process_diffs "$expect" >expect &&
+		test_cmp expect actual
 	'
 done <<\EOF
 diff-tree initial
-- 
2.31.1.646.g06d606cb9c7


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

* Re: [PATCH 1/2] diff tests: remove redundant case statement
  2021-04-13 12:28                                     ` [PATCH 1/2] diff tests: remove redundant case statement Ævar Arnfjörð Bjarmason
@ 2021-04-13 14:18                                       ` Matheus Tavares Bernardino
  2021-04-13 14:23                                         ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Matheus Tavares Bernardino @ 2021-04-13 14:18 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Junio C Hamano

On Tue, Apr 13, 2021 at 9:31 AM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:
>
> diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
> index 6cca8b84a6b..67f6411aff9 100755
> --- a/t/t4013-diff-various.sh
> +++ b/t/t4013-diff-various.sh
> @@ -220,13 +220,7 @@ do
>                 then
>                         process_diffs "$actual" >actual &&
>                         process_diffs "$expect" >expect &&
> -                       case $cmd in
> -                       *format-patch* | *-stat*)
> -                               test_cmp expect actual;;
> -                       *)
> -                               test_cmp expect actual;;
> -                       esac &&
> -                       rm -f "$actual" actual expect

Was this line removed by accident? It doesn't seem related to the
described change. Shouldn't this line be left after...

> +                       test_cmp expect actual

...this one?

>                 else
>                         # this is to help developing new tests.
>                         cp "$actual" "$expect"
> --
> 2.31.1.646.g06d606cb9c7
>

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

* Re: [PATCH 1/2] diff tests: remove redundant case statement
  2021-04-13 14:18                                       ` Matheus Tavares Bernardino
@ 2021-04-13 14:23                                         ` Ævar Arnfjörð Bjarmason
  0 siblings, 0 replies; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-13 14:23 UTC (permalink / raw)
  To: Matheus Tavares Bernardino; +Cc: git, Junio C Hamano


On Tue, Apr 13 2021, Matheus Tavares Bernardino wrote:

> On Tue, Apr 13, 2021 at 9:31 AM Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>>
>> diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
>> index 6cca8b84a6b..67f6411aff9 100755
>> --- a/t/t4013-diff-various.sh
>> +++ b/t/t4013-diff-various.sh
>> @@ -220,13 +220,7 @@ do
>>                 then
>>                         process_diffs "$actual" >actual &&
>>                         process_diffs "$expect" >expect &&
>> -                       case $cmd in
>> -                       *format-patch* | *-stat*)
>> -                               test_cmp expect actual;;
>> -                       *)
>> -                               test_cmp expect actual;;
>> -                       esac &&
>> -                       rm -f "$actual" actual expect
>
> Was this line removed by accident? It doesn't seem related to the
> described change. Shouldn't this line be left after...
>
>> +                       test_cmp expect actual
>
> ...this one?

Yes, it should be in 2/2 where this gets turned into a
test_when_finished "rm [...]", sorry.

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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-13 12:28                                     ` [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid" Ævar Arnfjörð Bjarmason
@ 2021-04-13 14:44                                       ` Matheus Tavares Bernardino
  2021-04-13 19:01                                         ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Matheus Tavares Bernardino @ 2021-04-13 14:44 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Junio C Hamano

On Tue, Apr 13, 2021 at 9:31 AM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:
>
> If a new test is added to this "while read magic cmd" test facility
> added in 3c2f75b590c (t4013: add tests for diff/log family output
> options., 2006-06-26) but no test file is added it'll fail the first
> time, but then succeed on subsequent runs as a new file has been added
> in t4013.
>
> Let's accomplish the same aim in way that doesn't cause subsequent

s/in way/in a way/ ?

> test runs to succeed. If we can't find the file we'll BUG out, and
> suggest to the developer that they copy our "expect.new" file over,
> unlike the previous "expect" file this won't be picked up on
> subsequent runs.
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>  t/t4013-diff-various.sh | 25 +++++++++++++++----------
>  1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
> index 67f6411aff9..228ff100c61 100755
> --- a/t/t4013-diff-various.sh
> +++ b/t/t4013-diff-various.sh
> @@ -200,10 +200,12 @@ do
>         esac
>         test=$(echo "$label" | sed -e 's|[/ ][/ ]*|_|g')
>         pfx=$(printf "%04d" $test_count)
> -       expect="$TEST_DIRECTORY/t4013/diff.$test"
> +       expect_relative="t4013/diff.$test"
> +       expect="$TEST_DIRECTORY/$expect_relative"
>         actual="$pfx-diff.$test"
>
>         test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
> +               test_when_finished "rm $actual" &&

Nit: before these two patches, "$actual" was only removed when the
test succeeded. So, in case of failure, the failed output files would
still be there for debugging. It might be interesting to keep this
behavior and only remove "$actual" at the end of the test.

>                 {
>                         echo "$ git $cmd"
>                         case "$magic" in
> @@ -216,16 +218,19 @@ do
>                             -e "s/^\\(.*mixed; boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/"
>                         echo "\$"
>                 } >"$actual" &&
> -               if test -f "$expect"
> +
> +               if ! test -f "$expect"
>                 then
> -                       process_diffs "$actual" >actual &&
> -                       process_diffs "$expect" >expect &&
> -                       test_cmp expect actual
> -               else
> -                       # this is to help developing new tests.
> -                       cp "$actual" "$expect"
> -                       false
> -               fi
> +                       expect_new="$expect.new" &&
> +                       cp "$actual" "$expect_new" &&
> +                       BUG "Have no \"$expect_relative\", new test? The output is in \"$expect_new\", maybe use that?"
> +               fi &&
> +
> +               test_when_finished "rm actual" &&
> +               process_diffs "$actual" >actual &&
> +               test_when_finished "rm expect" &&
> +               process_diffs "$expect" >expect &&
> +               test_cmp expect actual
>         '
>  done <<\EOF
>  diff-tree initial

The rest LGTM, thanks.

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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-13 14:44                                       ` Matheus Tavares Bernardino
@ 2021-04-13 19:01                                         ` Ævar Arnfjörð Bjarmason
  2021-04-13 19:55                                           ` Matheus Tavares Bernardino
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-13 19:01 UTC (permalink / raw)
  To: Matheus Tavares Bernardino; +Cc: git, Junio C Hamano


On Tue, Apr 13 2021, Matheus Tavares Bernardino wrote:

> On Tue, Apr 13, 2021 at 9:31 AM Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>>
>> If a new test is added to this "while read magic cmd" test facility
>> added in 3c2f75b590c (t4013: add tests for diff/log family output
>> options., 2006-06-26) but no test file is added it'll fail the first
>> time, but then succeed on subsequent runs as a new file has been added
>> in t4013.
>>
>> Let's accomplish the same aim in way that doesn't cause subsequent
>
> s/in way/in a way/ ?

*nod*

>> test runs to succeed. If we can't find the file we'll BUG out, and
>> suggest to the developer that they copy our "expect.new" file over,
>> unlike the previous "expect" file this won't be picked up on
>> subsequent runs.
>>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>>  t/t4013-diff-various.sh | 25 +++++++++++++++----------
>>  1 file changed, 15 insertions(+), 10 deletions(-)
>>
>> diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
>> index 67f6411aff9..228ff100c61 100755
>> --- a/t/t4013-diff-various.sh
>> +++ b/t/t4013-diff-various.sh
>> @@ -200,10 +200,12 @@ do
>>         esac
>>         test=$(echo "$label" | sed -e 's|[/ ][/ ]*|_|g')
>>         pfx=$(printf "%04d" $test_count)
>> -       expect="$TEST_DIRECTORY/t4013/diff.$test"
>> +       expect_relative="t4013/diff.$test"
>> +       expect="$TEST_DIRECTORY/$expect_relative"
>>         actual="$pfx-diff.$test"
>>
>>         test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
>> +               test_when_finished "rm $actual" &&
>
> Nit: before these two patches, "$actual" was only removed when the
> test succeeded. So, in case of failure, the failed output files would
> still be there for debugging. It might be interesting to keep this
> behavior and only remove "$actual" at the end of the test.

Either I'm missing something or you are, that's how test_when_finished
works.

It's skipped under e.g. "--immediate --debug". See b586744a864 (test:
skip clean-up when running under --immediate mode, 2011-06-27)

Maybe there's some edge case where we'd like to keep the files that it's
not covering, but then we should patch it to do the right thing, not use
manual "rm" at the end instead.

>>                 {
>>                         echo "$ git $cmd"
>>                         case "$magic" in
>> @@ -216,16 +218,19 @@ do
>>                             -e "s/^\\(.*mixed; boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/"
>>                         echo "\$"
>>                 } >"$actual" &&
>> -               if test -f "$expect"
>> +
>> +               if ! test -f "$expect"
>>                 then
>> -                       process_diffs "$actual" >actual &&
>> -                       process_diffs "$expect" >expect &&
>> -                       test_cmp expect actual
>> -               else
>> -                       # this is to help developing new tests.
>> -                       cp "$actual" "$expect"
>> -                       false
>> -               fi
>> +                       expect_new="$expect.new" &&
>> +                       cp "$actual" "$expect_new" &&
>> +                       BUG "Have no \"$expect_relative\", new test? The output is in \"$expect_new\", maybe use that?"
>> +               fi &&
>> +
>> +               test_when_finished "rm actual" &&
>> +               process_diffs "$actual" >actual &&
>> +               test_when_finished "rm expect" &&
>> +               process_diffs "$expect" >expect &&
>> +               test_cmp expect actual
>>         '
>>  done <<\EOF
>>  diff-tree initial
>
> The rest LGTM, thanks.

Thanks a lot for the review!

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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-13 19:01                                         ` Ævar Arnfjörð Bjarmason
@ 2021-04-13 19:55                                           ` Matheus Tavares Bernardino
  2021-04-13 21:55                                             ` Junio C Hamano
                                                               ` (2 more replies)
  0 siblings, 3 replies; 229+ messages in thread
From: Matheus Tavares Bernardino @ 2021-04-13 19:55 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git, Junio C Hamano

On Tue, Apr 13, 2021 at 4:01 PM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:
>
>
> On Tue, Apr 13 2021, Matheus Tavares Bernardino wrote:
>
> > On Tue, Apr 13, 2021 at 9:31 AM Ævar Arnfjörð Bjarmason
> > <avarab@gmail.com> wrote:
> >>  t/t4013-diff-various.sh | 25 +++++++++++++++----------
> >>  1 file changed, 15 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
> >> index 67f6411aff9..228ff100c61 100755
> >> --- a/t/t4013-diff-various.sh
> >> +++ b/t/t4013-diff-various.sh
> >> @@ -200,10 +200,12 @@ do
> >>         esac
> >>         test=$(echo "$label" | sed -e 's|[/ ][/ ]*|_|g')
> >>         pfx=$(printf "%04d" $test_count)
> >> -       expect="$TEST_DIRECTORY/t4013/diff.$test"
> >> +       expect_relative="t4013/diff.$test"
> >> +       expect="$TEST_DIRECTORY/$expect_relative"
> >>         actual="$pfx-diff.$test"
> >>
> >>         test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
> >> +               test_when_finished "rm $actual" &&
> >
> > Nit: before these two patches, "$actual" was only removed when the
> > test succeeded. So, in case of failure, the failed output files would
> > still be there for debugging. It might be interesting to keep this
> > behavior and only remove "$actual" at the end of the test.
>
> Either I'm missing something or you are, that's how test_when_finished
> works.
>
> It's skipped under e.g. "--immediate --debug". See b586744a864 (test:
> skip clean-up when running under --immediate mode, 2011-06-27)

I was mostly thinking about the `artifacts` zip we get from our CI
when a test fails. I find the final trash dir quite useful for some
post-mortem analysis, especially to debug WIP tests that only fail
occasionally or test failures on OSes I don't have quick access to.

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

* Re: [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup
  2021-04-13 12:28                                   ` [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup Ævar Arnfjörð Bjarmason
  2021-04-13 12:28                                     ` [PATCH 1/2] diff tests: remove redundant case statement Ævar Arnfjörð Bjarmason
  2021-04-13 12:28                                     ` [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid" Ævar Arnfjörð Bjarmason
@ 2021-04-13 21:42                                     ` Junio C Hamano
  2 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-04-13 21:42 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: git

Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:

> In reply to [1] because they're related post-GETTEXT_POISON cleanup,
> but both apply on top of master.
>
> I had a flaky t4013 test with some local WIP code that I hadn't
> investigated, as it turns out re-running the test was hiding the
> failure. 2/2 fixes that, 1/2 is a minor post-GETTEXT_POISON cleanup.

I feel somewhat offended to see t4013's "auto preparation of the
expected output" feature (which of course I invented) as "flakey" ;-)
but I agree that was a misfeature.  Thanks for taking a look.

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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-13 19:55                                           ` Matheus Tavares Bernardino
@ 2021-04-13 21:55                                             ` Junio C Hamano
  2021-04-14  6:22                                             ` Ævar Arnfjörð Bjarmason
  2021-04-15 21:26                                             ` SZEDER Gábor
  2 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-04-13 21:55 UTC (permalink / raw)
  To: Matheus Tavares Bernardino; +Cc: Ævar Arnfjörð Bjarmason, git

Matheus Tavares Bernardino <matheus.bernardino@usp.br> writes:

> On Tue, Apr 13, 2021 at 4:01 PM Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>>
>> > Nit: before these two patches, "$actual" was only removed when the
>> > test succeeded. So, in case of failure, the failed output files would
>> > still be there for debugging. It might be interesting to keep this
>> > behavior and only remove "$actual" at the end of the test.
>>
>> Either I'm missing something or you are, that's how test_when_finished
>> works.
>>
>> It's skipped under e.g. "--immediate --debug". See b586744a864 (test:
>> skip clean-up when running under --immediate mode, 2011-06-27)
>
> I was mostly thinking about the `artifacts` zip we get from our CI
> when a test fails. I find the final trash dir quite useful for some
> post-mortem analysis, especially to debug WIP tests that only fail
> occasionally or test failures on OSes I don't have quick access to.

Yeah, without "--immediate" we do run the clean-up tasks registered
with test_when_finished, so it may be a problem.


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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-13 19:55                                           ` Matheus Tavares Bernardino
  2021-04-13 21:55                                             ` Junio C Hamano
@ 2021-04-14  6:22                                             ` Ævar Arnfjörð Bjarmason
  2021-04-14  6:35                                               ` Junio C Hamano
  2021-04-15 21:26                                             ` SZEDER Gábor
  2 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-14  6:22 UTC (permalink / raw)
  To: Matheus Tavares Bernardino; +Cc: git, Junio C Hamano


On Tue, Apr 13 2021, Matheus Tavares Bernardino wrote:

> On Tue, Apr 13, 2021 at 4:01 PM Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>>
>>
>> On Tue, Apr 13 2021, Matheus Tavares Bernardino wrote:
>>
>> > On Tue, Apr 13, 2021 at 9:31 AM Ævar Arnfjörð Bjarmason
>> > <avarab@gmail.com> wrote:
>> >>  t/t4013-diff-various.sh | 25 +++++++++++++++----------
>> >>  1 file changed, 15 insertions(+), 10 deletions(-)
>> >>
>> >> diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
>> >> index 67f6411aff9..228ff100c61 100755
>> >> --- a/t/t4013-diff-various.sh
>> >> +++ b/t/t4013-diff-various.sh
>> >> @@ -200,10 +200,12 @@ do
>> >>         esac
>> >>         test=$(echo "$label" | sed -e 's|[/ ][/ ]*|_|g')
>> >>         pfx=$(printf "%04d" $test_count)
>> >> -       expect="$TEST_DIRECTORY/t4013/diff.$test"
>> >> +       expect_relative="t4013/diff.$test"
>> >> +       expect="$TEST_DIRECTORY/$expect_relative"
>> >>         actual="$pfx-diff.$test"
>> >>
>> >>         test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
>> >> +               test_when_finished "rm $actual" &&
>> >
>> > Nit: before these two patches, "$actual" was only removed when the
>> > test succeeded. So, in case of failure, the failed output files would
>> > still be there for debugging. It might be interesting to keep this
>> > behavior and only remove "$actual" at the end of the test.
>>
>> Either I'm missing something or you are, that's how test_when_finished
>> works.
>>
>> It's skipped under e.g. "--immediate --debug". See b586744a864 (test:
>> skip clean-up when running under --immediate mode, 2011-06-27)
>
> I was mostly thinking about the `artifacts` zip we get from our CI
> when a test fails. I find the final trash dir quite useful for some
> post-mortem analysis, especially to debug WIP tests that only fail
> occasionally or test failures on OSes I don't have quick access to.

Ah, yes that's a problem we should solve, but I think we should not put
off migration to test_when_finished because of that.

The whole reason we use it is to clean up the work area for the next
test.

Thus if we do:

    git something >expected &&
    test_cmp expected actual &&
    rm expected actual

And "git something" segfaults it's only dumb luck that subsequent tests
don't fail in non-obvious ways due to the files being left behind.

If we could rely on this in general we could make everything under
test_when_finished a noop, but I think you'll find that'll fail a lot of
things in the test suite if we do that.

But the problem you cite is legitimate, but we should solve it with
something like:

 1. If we fail tests 58 and 67 out of 100 we should/could run these
    again at the end under some more exhaustive debugging mode where
    we'd save away all the intermediate files.

 2. Or, and test_when_finished helps here, we could set $PATH when it
    runs to a directory with a custom "rm", which would save away the
    temporary files, expecting that we'll tar them up if any of the
    tests whose files we saved failed (we'd delete the other ones).

 3. Similarly, wrap "rm" in some "cat and rm" for common cases like
    actual/expected files, and improve the verbose output to some
    "verbose if fails".


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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-14  6:22                                             ` Ævar Arnfjörð Bjarmason
@ 2021-04-14  6:35                                               ` Junio C Hamano
  2021-04-14  7:38                                                 ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2021-04-14  6:35 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: Matheus Tavares Bernardino, git

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> On Tue, Apr 13 2021, Matheus Tavares Bernardino wrote:
> ...
>>> >>         actual="$pfx-diff.$test"
>>> >>
>>> >>         test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
>>> >> +               test_when_finished "rm $actual" &&
>>> >
>>> > Nit: before these two patches, "$actual" was only removed when the
>>> > test succeeded. So, in case of failure, the failed output files would
>>> > still be there for debugging. It might be interesting to keep this
>>> > behavior and only remove "$actual" at the end of the test.
> ...
> Ah, yes that's a problem we should solve, but I think we should not put
> off migration to test_when_finished because of that.
>
> The whole reason we use it is to clean up the work area for the next
> test.
>
> Thus if we do:
>
>     git something >expected &&
>     test_cmp expected actual &&
>     rm expected actual

Isn't it a poor example to use to argue for your particular change,
where $actual in the original is designed to be unique among tests,
in order to ensure that $actual files left after test pieces fail
would not interfere with the tests that come later?  IOW, there is
not a reason to remove $actual until the end of the test sequence,
is there?

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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-14  6:35                                               ` Junio C Hamano
@ 2021-04-14  7:38                                                 ` Ævar Arnfjörð Bjarmason
  2021-04-14  7:53                                                   ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-14  7:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Matheus Tavares Bernardino, git


On Wed, Apr 14 2021, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> On Tue, Apr 13 2021, Matheus Tavares Bernardino wrote:
>> ...
>>>> >>         actual="$pfx-diff.$test"
>>>> >>
>>>> >>         test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
>>>> >> +               test_when_finished "rm $actual" &&
>>>> >
>>>> > Nit: before these two patches, "$actual" was only removed when the
>>>> > test succeeded. So, in case of failure, the failed output files would
>>>> > still be there for debugging. It might be interesting to keep this
>>>> > behavior and only remove "$actual" at the end of the test.
>> ...
>> Ah, yes that's a problem we should solve, but I think we should not put
>> off migration to test_when_finished because of that.
>>
>> The whole reason we use it is to clean up the work area for the next
>> test.
>>
>> Thus if we do:
>>
>>     git something >expected &&
>>     test_cmp expected actual &&
>>     rm expected actual
>
> Isn't it a poor example to use to argue for your particular change,
> where $actual in the original is designed to be unique among tests,
> in order to ensure that $actual files left after test pieces fail
> would not interfere with the tests that come later?  IOW, there is
> not a reason to remove $actual until the end of the test sequence,
> is there?

Not really, because you needed to read the rest of the test file to come
to that conclusion.

The point of using a helper that guarantees cleanup such as
test_when_finished or test_config over manual "git config" or "git rm"
isn't that we can prove that we need it because a later test needs the
cleanup, but that anyone can add new tests or functionality without
having to worry about cleaning up the existing trash directory.

So yes, it's not needed here, but that's only because we know the rest
of the tests don't have e.g. a test that does a:

    for file in t4013/*

Anyway, that's only half of the example I cited for why we should use
test_when_finished in general, the other half was noting that because
we've semantically annotated cleanup tasks we can smartly handle those
for debugging, e.g. stash the "removed" files away, and if the test
fails present them to the user.


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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-14  7:38                                                 ` Ævar Arnfjörð Bjarmason
@ 2021-04-14  7:53                                                   ` Junio C Hamano
  2021-04-14 10:08                                                     ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2021-04-14  7:53 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: Matheus Tavares Bernardino, git

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

>>> Thus if we do:
>>>
>>>     git something >expected &&
>>>     test_cmp expected actual &&
>>>     rm expected actual
>>
>> Isn't it a poor example to use to argue for your particular change,
>> where $actual in the original is designed to be unique among tests,
>> in order to ensure that $actual files left after test pieces fail
>> would not interfere with the tests that come later?  IOW, there is
>> not a reason to remove $actual until the end of the test sequence,
>> is there?
>
> Not really, because you needed to read the rest of the test file to come
> to that conclusion.
>
> The point of using a helper that guarantees cleanup such as
> test_when_finished or test_config over manual "git config" or "git rm"
> isn't that we can prove that we need it because a later test needs the
> cleanup, but that anyone can add new tests or functionality without
> having to worry about cleaning up the existing trash directory.
>
> So yes, it's not needed here, but that's only because we know the rest
> of the tests don't have e.g. a test that does a:

In this particular case, $actual files are designed to be left
behind for failed test pieces, so that the tester can come back and
inspect them.  I probably should have said it a bit more strongly
than "there is not a reason to remove".  You SHOULD NOT remove and
that is why we had "check and then remove only upon success" there,
instead of test_when_finished.  We want them left for and only for
failing test pieces.

Please do not advocate for and encourage newbies who would be
reading the discussion from sidelines to use test_when_finished out
of dogmatic principle without thinking.  Even though there are valid
cases where test_when_finished is the perfect fit, in this
particular case, use of it is a clear regression.

Thanks.

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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-14  7:53                                                   ` Junio C Hamano
@ 2021-04-14 10:08                                                     ` Ævar Arnfjörð Bjarmason
  2021-04-15  8:14                                                       ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-14 10:08 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Matheus Tavares Bernardino, git


On Wed, Apr 14 2021, Junio C Hamano wrote:

["tl;dr" below]:

> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>>>> Thus if we do:
>>>>
>>>>     git something >expected &&
>>>>     test_cmp expected actual &&
>>>>     rm expected actual
>>>
>>> Isn't it a poor example to use to argue for your particular change,
>>> where $actual in the original is designed to be unique among tests,
>>> in order to ensure that $actual files left after test pieces fail
>>> would not interfere with the tests that come later?  IOW, there is
>>> not a reason to remove $actual until the end of the test sequence,
>>> is there?
>>
>> Not really, because you needed to read the rest of the test file to come
>> to that conclusion.
>>
>> The point of using a helper that guarantees cleanup such as
>> test_when_finished or test_config over manual "git config" or "git rm"
>> isn't that we can prove that we need it because a later test needs the
>> cleanup, but that anyone can add new tests or functionality without
>> having to worry about cleaning up the existing trash directory.
>>
>> So yes, it's not needed here, but that's only because we know the rest
>> of the tests don't have e.g. a test that does a:
>
> In this particular case, $actual files are designed to be left
> behind for failed test pieces, so that the tester can come back and
> inspect them.  I probably should have said it a bit more strongly
> than "there is not a reason to remove".  You SHOULD NOT remove and
> that is why we had "check and then remove only upon success" there,
> instead of test_when_finished.  We want them left for and only for
> failing test pieces.

Yes, it's clear that it's designed to do that. I'm not disagreeing on
the intent of your commit in 2006 to set it up this way.

What I am saying is that it's incompatible to have:

 1. Failing tests
 2. Not removing scratch files that would otherwise be removed

And:

 3. Knowing that the rest of the tests pass in the case of #1 without
    reading them all.

Hence the suggestion that we should use test_when_finished without
exception for such patterns.

Because consistently using the helper would allow us to smartly get #1
and #2 without #3, i.e. some "copy them for later analysis" as suggested
upthread in:
http://lore.kernel.org/git/874kg92xn0.fsf@evledraar.gmail.com

> Please do not advocate for and encourage newbies who would be
> reading the discussion from sidelines to use test_when_finished out
> of dogmatic principle without thinking.

Is Matheus the newbie here? I think he's contributed enough to form his
own opinion.

I think it's clear to anyone else reading from the sidelines that we're
having some informed disagreement about a finer point of patterns in the
test suite.

I doubt either one of us is likely to have much of an impact on newbies
reading from the sidelines.

In any case, I don't see how you're able to read this thread and come to
the conclusion that I'm proposing the use of test_when_finished out of
"[some] dogmatic principle".

I'm not. I'm proposing to use it because I think it makes sense, and I
think the reasons you've noted for avoiding it in this case have more
downsides than upsites, as noted in the #1-3 examples above.

> Even though there are valid cases where test_when_finished is the
> perfect fit, in this particular case, use of it is a clear regression.

Well, I disagree with you.

I think even if the patch I was proposing was a mere conversion to
test_when_finished as would be typical for most newly written tests,
i.e. a diff like this:
	
	diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
	index 6cca8b84a6b..d0031aa0f7b 100755
	--- a/t/t4013-diff-various.sh
	+++ b/t/t4013-diff-various.sh
	@@ -204,6 +204,7 @@ do
	 	actual="$pfx-diff.$test"
	 
	 	test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
	+		test_when_finished "rm \"$actual\"" &&
	 		{
	 			echo "$ git $cmd"
	 			case "$magic" in
	@@ -216,22 +217,11 @@ do
	 			    -e "s/^\\(.*mixed; boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/"
	 			echo "\$"
	 		} >"$actual" &&
	-		if test -f "$expect"
	-		then
	-			process_diffs "$actual" >actual &&
	-			process_diffs "$expect" >expect &&
	-			case $cmd in
	-			*format-patch* | *-stat*)
	-				test_cmp expect actual;;
	-			*)
	-				test_cmp expect actual;;
	-			esac &&
	-			rm -f "$actual" actual expect
	-		else
	-			# this is to help developing new tests.
	-			cp "$actual" "$expect"
	-			false
	-		fi
	+		test_when_finished "rm actual" &&
	+		process_diffs "$actual" >actual &&
	+		test_when_finished "rm expect" &&
	+		process_diffs "$expect" >expect &&
	+		test_cmp expect actual
	 	'
	 done <<\EOF
	 diff-tree initial

It's a clear improvement, because, on current master, emulating the case
when you add a new test-case:

    $ rm t4013/diff.log_-GF_-p_--pickaxe-all_master

Now run it once:

    $ ./t4013-diff-various.sh
    [...]
    # failed 1 among 199 test(s)

And then to debug it:

    $ ./t4013-diff-various.sh -vixd
    [...]
    # passed all 199 test(s)

So because we copied the file around the only get the failure the first
time around.

You might rightly say that we could have narrowly just fixed that
particular bug and kept the old "copy and return false", so something
like:
	
	diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
	index 6cca8b84a6b..6f0f3c7f53c 100755
	--- a/t/t4013-diff-various.sh
	+++ b/t/t4013-diff-various.sh
	@@ -229,7 +229,7 @@ do
	 			rm -f "$actual" actual expect
	 		else
	 			# this is to help developing new tests.
	-			cp "$actual" "$expect"
	+			cp "$actual" "$expect.MAYBE-USE-THIS"
	 			false
	 		fi
	 	'

But as noted above that gets us into needing to worry about cascading
failure. I.e. any new test added later in the file needs to think about
"what if the t4013 directory is in this state?".

We also document what we'll do and how we'll do it in t/README in this
case:
	
	--immediate::
		This causes the test to immediately exit upon the first
		failed test. Cleanup commands requested with
		test_when_finished are not executed if the test failed,
		in order to keep the state for inspection by the tester
		to diagnose the bug.

So it's much more obvious and consistent to have a failure that ends on
the test_cmp and being able to see the test_when_finished for the
intermediate files in the trace output.

The hypothetical newbie might have debugged such a pattern already, but
not having it end in a special-case used only for this test:

    [...]
    + test -f /home/avar/g/git/t/t4013/diff.log_-GF_-p_--pickaxe-all_master
    + cp 0096-diff.log_-GF_-p_--pickaxe-all_master /home/avar/g/git/t/t4013/diff.log_-GF_-p_--pickaxe-all_master.MAYBE-USE-THIS
    + false

In any case, neither one of those is the patch I'm suggesting upthread.

I am suggesting not just to use test_when_finished, but that we should
use BUG here. Since not having the file itself is a bug in git's test
suite, not a mere failure of the test case. The test will never pass if
the file doesn't exist.

So even if I agreed with you that the more narrow migration to
test_when_finished would be a regression, I don't see how you think
*this* patch could be a regression.

You seem to just be focusing on the test_when_finished part of it, but
that's not all it's doing. Since we also use BUG the output is now:

    $ ./t4013-diff-various.sh 
    [...]
    error: bug in the test script: Have no "t4013/diff.log_-GF_-p_--pickaxe-all_master", new test? [...]

I.e. whether we used "rm" or "cp" or "test_when_finished 'rm [...]'"
earlier has become irrelevant to achieve the states aims in 3c2f75b590c
(t4013: add tests for diff/log family output options., 2006-06-26).

It doesn't matter how we're removing/copying etc. the file anymore,
that's no longer how we're helping the user debug the test.

tl;dr:

In any case, I think it's best to just drop this series. I wrote the
above more as a synopsis of what I belive we should be doing in general,
I do have some patches queued up to address the general debug-ability of
our test output (e.g. for CI).

For that end-goal having e.g. test_when_finished (mostly) consistently
used would help a lot, but not using it in any one test would be
fine. This is just one such case, and something I thought wouldn't be a
controversial patch.

I think at this point me trying to gleaming entrails of what you want &
you responding back is going to take both of us much more time than
replacing this series with a patch you'd be happy with, and this wasn't
something I cared about more than a one-off.

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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-14 10:08                                                     ` Ævar Arnfjörð Bjarmason
@ 2021-04-15  8:14                                                       ` Junio C Hamano
  2021-04-15 13:21                                                         ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 229+ messages in thread
From: Junio C Hamano @ 2021-04-15  8:14 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: Matheus Tavares Bernardino, git

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> What I am saying is that it's incompatible to have:
>
>  1. Failing tests
>  2. Not removing scratch files that would otherwise be removed
>
> And:
>
>  3. Knowing that the rest of the tests pass in the case of #1 without
>     reading them all.
>
> Hence the suggestion that we should use test_when_finished without
> exception for such patterns.

I disagree with the above; t4013's "read magic cmd" part is designed
to be independent from each other; I do not think you need to read
all of the parts enclosed in << ... EOF to understand that.

In short,

 * "test_when_finished 'rm ...'" is a good tool to ensure something
   gets removed no matter what else happens in the same test.  Since
   it does not run the clean-up under "-i", it can even be used on
   files that would be useful in diagnosing failures.  But under
   "-d", it does clean-up to avoid affecting the following test.

 * $actual was made unique so that even under "-d", a failing test
   would not negatively affect the subsequent ones.  Removing it for
   failure cases is actively wrong, so use of test_when_finished,
   which may be an expedient way to remove artifact that would
   negatively affect later test pieces, does not apply --- existing
   code is doing better than test_when_finished can offer, and
   replacing it with test_when_finished is a regression.

 * And the most important part: the unnecessary removal of $actual
   was not even part of the "flakyness-causing" bug you started this
   topic to fix anyway.  We should just remove the regression caused
   by unnecessary use of test_when_finished and focus on the "don't
   place the actual output from a brand new test under the file used
   for the expectation the next time---instead place it under
   temporary file and call for attention" part, which was the real
   improvement.

>> Please do not advocate for and encourage newbies who would be
>> reading the discussion from sidelines to use test_when_finished out
>> of dogmatic principle without thinking.
>
> Is Matheus the newbie here? I think he's contributed enough to form his
> own opinion.

No, those "reading the discussion from sidelines" are not on To: or
Cc:, but are eager to learn by reading what is available to git@
subscribers (including the lore archive).  I do not want those of us
whose name appear often in the list archive to be sending a wrong
signal to them.

> In any case, I think it's best to just drop this series.

That is a sad and wrong conclusion.  We should just realize what we
really wanted to fix in the first place and keep the improvement;
otherwise all the review time was wasted.

And next time, I'd suggest you not to spend too many bytes on "while
at it".  Clear and obvious clean-up while the tree and the project
is otherwise quiescent is very much no-brainer welcome, but
otherwise...

Thanks.

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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-15  8:14                                                       ` Junio C Hamano
@ 2021-04-15 13:21                                                         ` Ævar Arnfjörð Bjarmason
  2021-04-16 18:32                                                           ` Junio C Hamano
  0 siblings, 1 reply; 229+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2021-04-15 13:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Matheus Tavares Bernardino, git


On Thu, Apr 15 2021, Junio C Hamano wrote:

> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> What I am saying is that it's incompatible to have:
>>
>>  1. Failing tests
>>  2. Not removing scratch files that would otherwise be removed
>>
>> And:
>>
>>  3. Knowing that the rest of the tests pass in the case of #1 without
>>     reading them all.
>>
>> Hence the suggestion that we should use test_when_finished without
>> exception for such patterns.
>
> I disagree with the above; t4013's "read magic cmd" part is designed
> to be independent from each other; I do not think you need to read
> all of the parts enclosed in << ... EOF to understand that.
>
> In short,
>
>  * "test_when_finished 'rm ...'" is a good tool to ensure something
>    gets removed no matter what else happens in the same test.  Since
>    it does not run the clean-up under "-i", it can even be used on
>    files that would be useful in diagnosing failures.  But under
>    "-d", it does clean-up to avoid affecting the following test.
>
>  * $actual was made unique so that even under "-d", a failing test
>    would not negatively affect the subsequent ones. [...]

I don't mind disagreeing with you, but I do feel like we're just talking
past each other, either that or we've got a different understanding of
"negatively affect the subsequent ones".

I'm saying that yes I agree that *right now* it doesn't negatively
affect any of the subsequent ones, but that you can only know that if
you need all the tests in the file past the one you're modifying.

I.e. imagine if we added, obviously contrived, but a stand-in for "we
expect consistent state":
	
	diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
	index 6cca8b84a6b..a326968e8f3 100755
	--- a/t/t4013-diff-various.sh
	+++ b/t/t4013-diff-various.sh
	@@ -526,4 +526,9 @@ test_expect_success 'diff -I<regex>: detect malformed regex' '
	 	test_i18ngrep "invalid regex given to -I: " error
	 '
	 
	+test_expect_success 'stuff' '
	+	find * -type f >actual &&
	+	test_line_count = 9 actual
	+'
	+
	 test_done

Now run it, and you'll pass them all, now break one of the earlier tests
with:

    >t4013/diff.log_-GF_-p_--pickaxe-all_master

You'll fail two tests (the expected one, and the new one), instead of
just one, which is purely an artifact of the earlier test's cleanup /
state being different as a result of whether it passes or not.

With my patch you'll fail just the one earlier test, because we do the
same cleanup no matter whether we failed midway through it or not.

So yes, while this small series amounts to re-arranging some deck chairs
on the Titanic I do think not being able to rely on consistent state is
a big anti-pattern in the test suite in general.

It's a big part of the reason for why you can't reliably use --run=N or
GIT_SKIP_TESTS (especially in cases of partial failures) to selectively
skip things without what amounts to bespoke analysis of each test you'd
like to run a subset of.

Now, of course test_when_finished won't get us there by itself, we'd
also need consistently use some "test_expect_setup" to clearly delineate
"setup" and other "this must run" state changes from "just consumes
existing state and resets". But consistently writing new/modified tests
as "just consumes existing state and resets" will slowly get us there.

>    [...] Removing it for
>    failure cases is actively wrong, so use of test_when_finished,
>    which may be an expedient way to remove artifact that would
>    negatively affect later test pieces, does not apply --- existing
>    code is doing better than test_when_finished can offer, and
>    replacing it with test_when_finished is a regression.

Aside from whether we agree or disagree on whether test_when_finished
should be consistently used to clean up state I genuinely still don't
see how the sum total of replacing the current "rm && cp" with
"test_when_finished && BUG" leaves us worse off.

Are you thinking of the case where someone wants to add N new lines to
the "while read magic cmd" loop?

That's the only case I can think of that would arguably be worse, but I
think it's far outweighed by the more obvious failure mode, and a "git
blame" on the lines it consumes shows that additions are very occasional
(and not in large batches).

Other than that, under e.g. -vixd having the test suite stop on the
specific line that failed (the test_cmp, not a "false" after some "cp")
is how most other tests works, and I think makes things much more
readable and understandable at a glance.

>  * And the most important part: the unnecessary removal of $actual
>    was not even part of the "flakyness-causing" bug you started this
>    topic to fix anyway.  We should just remove the regression caused
>    by unnecessary use of test_when_finished and focus on the "don't
>    place the actual output from a brand new test under the file used
>    for the expectation the next time---instead place it under
>    temporary file and call for attention" part, which was the real
>    improvement.

I see your point and agree in theory that the "we write into the
t/t4013/ directory" and "we inconsistently clear up the trash directory
on OK/NOK" are in principle different issues.

But in this case we always removed or copied "$actual" away from its
original name before, we do the same now (just more reliably, and in a
way that doesn't cause flakyness in the "cp" case).

So I don't really see how to split up those two arguably different
changes in a way that would make sense.

The only case where "$actual" was left before was (I think) a clear of
leaking state unnecessarily outside of --immediate.

>>> Please do not advocate for and encourage newbies who would be
>>> reading the discussion from sidelines to use test_when_finished out
>>> of dogmatic principle without thinking.
>>
>> Is Matheus the newbie here? I think he's contributed enough to form his
>> own opinion.
>
> No, those "reading the discussion from sidelines" are not on To: or
> Cc:, but are eager to learn by reading what is available to git@
> subscribers (including the lore archive).  I do not want those of us
> whose name appear often in the list archive to be sending a wrong
> signal to them.

I'll endeavor to make it clear that my opinion is just my opinion
etc. in the future, I thought it was clear from the context :)

>> In any case, I think it's best to just drop this series.
>
> That is a sad and wrong conclusion.  We should just realize what we
> really wanted to fix in the first place and keep the improvement;
> otherwise all the review time was wasted.

To be clear that's not some "I can't have the change I want so I'm
taking my toys and going home" tantrum. I don't mind making changes in
response to reviews etc.

As noted above I'm genuinely still unable to see how I'd selectively
untangle the change I made in a way that both wouldn't either fix bugs
in the test, or introduce new bugs while I was at it, and that I'd be
comfortable putting my name behind.

Hence the suggestion that since we're already we past the point of just
having come up with two independent approaches to this in terms of time
investment, that doing so would be a better thing overall.

I do think (and would be willing to work on) that t/README should have
some summary of best practices for new/updated tests that we should be
striving for. Looking at our "test_when_finished" there's at least tow
independent bugs[1] in it, so ther's some room for improvement.

1. It creates a ref with echo, but removes it with update-ref -d, which
   e.g. couldn't delete a corrupt ref (if rev-parse is buggy); and more
   importantly if rev-parse dies midway through we're left with a
   corrupt repo, the "test_when_finished ... update-ref -d" should come
   *first*.


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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-13 19:55                                           ` Matheus Tavares Bernardino
  2021-04-13 21:55                                             ` Junio C Hamano
  2021-04-14  6:22                                             ` Ævar Arnfjörð Bjarmason
@ 2021-04-15 21:26                                             ` SZEDER Gábor
  2 siblings, 0 replies; 229+ messages in thread
From: SZEDER Gábor @ 2021-04-15 21:26 UTC (permalink / raw)
  To: Matheus Tavares Bernardino
  Cc: Ævar Arnfjörð Bjarmason, git, Junio C Hamano

On Tue, Apr 13, 2021 at 04:55:23PM -0300, Matheus Tavares Bernardino wrote:
> On Tue, Apr 13, 2021 at 4:01 PM Ævar Arnfjörð Bjarmason
> > >> diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
> > >> index 67f6411aff9..228ff100c61 100755
> > >> --- a/t/t4013-diff-various.sh
> > >> +++ b/t/t4013-diff-various.sh
> > >> @@ -200,10 +200,12 @@ do
> > >>         esac
> > >>         test=$(echo "$label" | sed -e 's|[/ ][/ ]*|_|g')
> > >>         pfx=$(printf "%04d" $test_count)
> > >> -       expect="$TEST_DIRECTORY/t4013/diff.$test"
> > >> +       expect_relative="t4013/diff.$test"
> > >> +       expect="$TEST_DIRECTORY/$expect_relative"
> > >>         actual="$pfx-diff.$test"
> > >>
> > >>         test_expect_$status "git $cmd # magic is ${magic:-(not used)}" '
> > >> +               test_when_finished "rm $actual" &&
> > >
> > > Nit: before these two patches, "$actual" was only removed when the
> > > test succeeded. So, in case of failure, the failed output files would
> > > still be there for debugging. It might be interesting to keep this
> > > behavior and only remove "$actual" at the end of the test.
> >
> > Either I'm missing something or you are, that's how test_when_finished
> > works.
> >
> > It's skipped under e.g. "--immediate --debug". See b586744a864 (test:
> > skip clean-up when running under --immediate mode, 2011-06-27)
> 
> I was mostly thinking about the `artifacts` zip we get from our CI
> when a test fails. I find the final trash dir quite useful for some
> post-mortem analysis, especially to debug WIP tests that only fail
> occasionally or test failures on OSes I don't have quick access to.

On Travis CI we run tests with '--immediate' for exactly this reason;
I don't know why it's done differently on other CI systems, and,
unfortunately, 'git log --grep=immediate ci/' didn't turn up any
insights.


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

* Re: [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid"
  2021-04-15 13:21                                                         ` Ævar Arnfjörð Bjarmason
@ 2021-04-16 18:32                                                           ` Junio C Hamano
  0 siblings, 0 replies; 229+ messages in thread
From: Junio C Hamano @ 2021-04-16 18:32 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: Matheus Tavares Bernardino, git

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> Are you thinking of the case where someone wants to add N new lines to
> the "while read magic cmd" loop?

No.  I think stopping with BUG is fine.  Adding a new test is a
serious event and I'd prefer to make it stop to give it undistracted
attention by the developer, instead of letting many to be handled at
once.

Of course, we _could_ instead remember the fact that we deposted
newly proposed expectation pattern that the user must audit, still
keep going and list the new files at the end, but I do not think it
is necessary.  Your newly added BUG is perfectly fine. 

>>> In any case, I think it's best to just drop this series.
>>
>> That is a sad and wrong conclusion.  We should just realize what we
>> really wanted to fix in the first place and keep the improvement;
>> otherwise all the review time was wasted.
>
> To be clear that's not some "I can't have the change I want so I'm
> taking my toys and going home" tantrum. I don't mind making changes in
> response to reviews etc.
>
> As noted above I'm genuinely still unable to see how I'd selectively
> untangle the change I made in a way that both wouldn't either fix bugs
> in the test, or introduce new bugs while I was at it, and that I'd be
> comfortable putting my name behind.

I fail to see why the "rewrite flakyness-causing test aid" that you
set out to perform should need more than a two-liner change.  There
is no reason to touch '&& rm "$actual" actual expect' at the end.
It is the success case where the flakyness-causing "aid" does not
even kick in.

 t/t4013-diff-various.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git c/t/t4013-diff-various.sh w/t/t4013-diff-various.sh
index 6cca8b84a6..da6da13920 100755
--- c/t/t4013-diff-various.sh
+++ w/t/t4013-diff-various.sh
@@ -229,8 +229,8 @@ do
 			rm -f "$actual" actual expect
 		else
 			# this is to help developing new tests.
-			cp "$actual" "$expect"
-			false
+			mv "$actual" "$expect.new"
+			BUG "No $expect; check $expect.new and use it perhaps?"
 		fi
 	'
 done <<\EOF
n

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

end of thread, other threads:[~2021-04-16 18:33 UTC | newest]

Thread overview: 229+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-18 19:16 [PATCH 00/14] Hash-independent tests, part 5 brian m. carlson
2019-08-18 19:16 ` [PATCH 01/14] t3201: abstract away SHA-1-specific constants brian m. carlson
2019-08-18 19:16 ` [PATCH 02/14] t3206: abstract away hash size constants brian m. carlson
2019-08-18 19:16 ` [PATCH 03/14] t3301: abstract away SHA-1-specific constants brian m. carlson
2019-08-18 19:16 ` [PATCH 04/14] t3305: make hash size independent brian m. carlson
2019-08-18 19:16 ` [PATCH 05/14] t3306: abstract away SHA-1-specific constants brian m. carlson
2019-08-18 19:16 ` [PATCH 06/14] t3404: " brian m. carlson
2019-08-18 19:16 ` [PATCH 07/14] t3430: avoid hard-coded object IDs brian m. carlson
2019-08-18 19:16 ` [PATCH 08/14] t3506: make hash independent brian m. carlson
2019-08-18 19:16 ` [PATCH 09/14] t3600: make hash size independent brian m. carlson
2019-08-18 19:16 ` [PATCH 10/14] t3800: make hash-size independent brian m. carlson
2019-08-18 19:16 ` [PATCH 11/14] t3903: abstract away SHA-1-specific constants brian m. carlson
2019-08-18 20:27   ` Eric Sunshine
2019-08-18 20:34     ` brian m. carlson
2019-08-18 19:16 ` [PATCH 12/14] t4000: make hash size independent brian m. carlson
2019-08-18 19:16 ` [PATCH 13/14] t4002: make hash independent brian m. carlson
2019-08-18 20:29   ` Eric Sunshine
2019-08-18 19:16 ` [PATCH 14/14] t4009: make hash size independent brian m. carlson
2019-08-26  1:43 ` [PATCH v2 00/14] Hash-independent tests, part 5 brian m. carlson
2019-08-26  1:43   ` [PATCH v2 01/14] t3201: abstract away SHA-1-specific constants brian m. carlson
2019-08-26  1:43   ` [PATCH v2 02/14] t3206: abstract away hash size constants brian m. carlson
2019-08-26  1:43   ` [PATCH v2 03/14] t3301: abstract away SHA-1-specific constants brian m. carlson
2019-08-26  1:43   ` [PATCH v2 04/14] t3305: make hash size independent brian m. carlson
2019-08-26  1:43   ` [PATCH v2 05/14] t3306: abstract away SHA-1-specific constants brian m. carlson
2019-08-26  1:43   ` [PATCH v2 06/14] t3404: " brian m. carlson
2019-08-26  1:43   ` [PATCH v2 07/14] t3430: avoid hard-coded object IDs brian m. carlson
2019-08-26  1:43   ` [PATCH v2 08/14] t3506: make hash independent brian m. carlson
2019-08-26  1:43   ` [PATCH v2 09/14] t3600: make hash size independent brian m. carlson
2019-08-26  1:43   ` [PATCH v2 10/14] t3800: make hash-size independent brian m. carlson
2020-11-23 12:01     ` [PATCH] mktag: don't check SHA-1 object length under SHA-256 Ævar Arnfjörð Bjarmason
2020-11-23 19:01       ` Junio C Hamano
2020-11-23 21:36         ` Jeff King
2020-11-23 22:17           ` Junio C Hamano
2020-11-24  0:47             ` Jeff King
2020-11-23 21:34       ` Jeff King
2020-11-24  1:07         ` brian m. carlson
2020-11-26  1:28         ` [RFC/PATCH 00/12] make "mktag" use fsck_tag() Ævar Arnfjörð Bjarmason
2020-11-26 22:22           ` [PATCH v2 00/10] " Ævar Arnfjörð Bjarmason
2020-12-01 10:08             ` Ævar Arnfjörð Bjarmason
2020-12-01 20:01               ` Junio C Hamano
2020-12-02 22:20                 ` Junio C Hamano
2020-12-03 16:38                   ` Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 " Ævar Arnfjörð Bjarmason
2020-12-09 22:30               ` Junio C Hamano
2020-12-23  1:35               ` [PATCH v4 00/20] make "mktag" use fsck_tag() & more Ævar Arnfjörð Bjarmason
2020-12-23 13:54                 ` Junio C Hamano
2020-12-24  9:16                   ` Junio C Hamano
2021-01-05 19:42                 ` [PATCH v5 00/23] " Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 01/23] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 02/23] mktag doc: grammar fix, when exists -> when it exists Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 03/23] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 04/23] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 05/23] mktag tests: use "test_commit" helper Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 06/23] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 07/23] mktag tests: don't redirect stderr to a file needlessly Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 08/23] mktag tests: don't create "mytag" twice Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 09/23] mktag tests: run "fsck" after creating "mytag" Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 10/23] mktag tests: stress test whitespace handling Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 11/23] mktag tests: test "hash-object" compatibility Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 12/23] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
2021-01-10 13:21                   ` SZEDER Gábor
2021-01-10 18:59                     ` Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false? Ævar Arnfjörð Bjarmason
2021-01-10 20:12                       ` Junio C Hamano
2021-01-11  8:43                         ` Ævar Arnfjörð Bjarmason
2021-01-11 13:14                           ` [PATCH 0/2] Makefile & gettext.c: remove warning & long comment Ævar Arnfjörð Bjarmason
2021-01-11 21:06                             ` Junio C Hamano
2021-01-11 13:14                           ` [PATCH 1/2] Makefile: remove a warning about old GETTEXT_POISON flag Ævar Arnfjörð Bjarmason
2021-01-11 13:14                           ` [PATCH 2/2] gettext.c: remove/reword a mostly-useless comment Ævar Arnfjörð Bjarmason
2021-01-11 14:47                           ` [PATCH 0/6] Remove GIT_TEST_GETTEXT_POISON facility Ævar Arnfjörð Bjarmason
2021-01-20 15:33                             ` SZEDER Gábor
2021-01-20 18:13                               ` Ævar Arnfjörð Bjarmason
2021-01-20 18:27                             ` [PATCH v2 0/3] " Ævar Arnfjörð Bjarmason
2021-02-11  1:53                               ` [PATCH 0/4] More GETTEXT_POISON removal Ævar Arnfjörð Bjarmason
2021-02-11  1:53                               ` [PATCH 1/4] tests: remove last uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
2021-03-07 13:29                                 ` [PATCH] mktag tests: fix broken "&&" chain Ævar Arnfjörð Bjarmason
2021-03-07 16:36                                   ` SZEDER Gábor
2021-03-07 20:43                                   ` Junio C Hamano
2021-03-07 20:52                                     ` Eric Sunshine
2021-03-24  2:11                                   ` [PATCH v2] " Ævar Arnfjörð Bjarmason
2021-03-24 19:57                                     ` Junio C Hamano
2021-02-11  1:53                               ` [PATCH 2/4] tests: remove most uses of C_LOCALE_OUTPUT Ævar Arnfjörð Bjarmason
2021-02-11  1:53                               ` [PATCH 3/4] tests: remove last " Ævar Arnfjörð Bjarmason
2021-02-11  1:53                               ` [PATCH 4/4] tests: remove most uses of test_i18ncmp Ævar Arnfjörð Bjarmason
2021-02-11 17:32                                 ` Junio C Hamano
2021-02-13 14:31                                   ` Ævar Arnfjörð Bjarmason
2021-02-19 21:25                                   ` Jonathan Nieder
2021-04-13 12:19                                 ` [PATCH] tests: remove all uses of test_i18cmp Ævar Arnfjörð Bjarmason
2021-04-13 12:28                                   ` [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup Ævar Arnfjörð Bjarmason
2021-04-13 12:28                                     ` [PATCH 1/2] diff tests: remove redundant case statement Ævar Arnfjörð Bjarmason
2021-04-13 14:18                                       ` Matheus Tavares Bernardino
2021-04-13 14:23                                         ` Ævar Arnfjörð Bjarmason
2021-04-13 12:28                                     ` [PATCH 2/2] diff tests: rewrite flakyness-causing test "aid" Ævar Arnfjörð Bjarmason
2021-04-13 14:44                                       ` Matheus Tavares Bernardino
2021-04-13 19:01                                         ` Ævar Arnfjörð Bjarmason
2021-04-13 19:55                                           ` Matheus Tavares Bernardino
2021-04-13 21:55                                             ` Junio C Hamano
2021-04-14  6:22                                             ` Ævar Arnfjörð Bjarmason
2021-04-14  6:35                                               ` Junio C Hamano
2021-04-14  7:38                                                 ` Ævar Arnfjörð Bjarmason
2021-04-14  7:53                                                   ` Junio C Hamano
2021-04-14 10:08                                                     ` Ævar Arnfjörð Bjarmason
2021-04-15  8:14                                                       ` Junio C Hamano
2021-04-15 13:21                                                         ` Ævar Arnfjörð Bjarmason
2021-04-16 18:32                                                           ` Junio C Hamano
2021-04-15 21:26                                             ` SZEDER Gábor
2021-04-13 21:42                                     ` [PATCH 0/2] diff tests: un-flaky and post-gettext-poison cleanup Junio C Hamano
2021-01-20 18:27                             ` [PATCH v2 1/3] ci: remove GETTEXT_POISON jobs Ævar Arnfjörð Bjarmason
2021-01-20 18:27                             ` [PATCH v2 2/3] tests: remove support for GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
2021-01-20 18:27                             ` [PATCH v2 3/3] tests: remove uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
2021-01-11 14:47                           ` [PATCH 1/6] ci: remove GETTEXT_POISON jobs Ævar Arnfjörð Bjarmason
2021-01-12  8:50                             ` SZEDER Gábor
2021-01-20 17:59                               ` Ævar Arnfjörð Bjarmason
2021-01-20 19:14                                 ` SZEDER Gábor
2021-01-27  0:47                                   ` Ævar Arnfjörð Bjarmason
2021-02-01 22:04                                     ` SZEDER Gábor
2021-02-03 12:13                                       ` Ævar Arnfjörð Bjarmason
2021-02-03 21:24                                         ` SZEDER Gábor
2021-01-11 14:47                           ` [PATCH 2/6] tests: remove support for GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
2021-01-11 21:54                             ` Junio C Hamano
2021-03-24 23:36                             ` [PATCH] config.c: remove last remnant of GIT_TEST_GETTEXT_POISON Ævar Arnfjörð Bjarmason
2021-03-25  0:36                               ` Jeff King
2021-03-25  1:13                                 ` Ævar Arnfjörð Bjarmason
2021-03-25 20:02                                   ` Junio C Hamano
2021-04-08 13:25                               ` [PATCH v2] " Ævar Arnfjörð Bjarmason
2021-04-08 17:55                                 ` Junio C Hamano
2021-01-11 14:47                           ` [PATCH 3/6] tests: remove misc use of test_i18n{cmp,grep} Ævar Arnfjörð Bjarmason
2021-01-11 14:47                           ` [PATCH 4/6] tests: (almost) remove use of "test_i18ngrep !" Ævar Arnfjörð Bjarmason
2021-01-11 14:47                           ` [PATCH 5/6] tests: (almost) remove C_LOCALE_OUTPUT prerequisites Ævar Arnfjörð Bjarmason
2021-01-11 14:47                           ` [PATCH 6/6] tests: remove uses of GIT_TEST_GETTEXT_POISON=false Ævar Arnfjörð Bjarmason
2021-01-11 21:05                           ` Should you use test_i18ngrep or GIT_TEST_GETTEXT_POISON=false? Junio C Hamano
2021-01-12 11:22                             ` Jeff King
2021-01-20 15:21                       ` SZEDER Gábor
2021-01-05 19:42                 ` [PATCH v5 13/23] mktag tests: test verify_object() with replaced objects Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 14/23] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 15/23] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 16/23] mktag: use puts(str) instead of printf("%s\n", str) Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 17/23] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 18/23] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 19/23] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 20/23] mktag: allow omitting the header/body \n separator Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 21/23] mktag: convert to parse-options Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 22/23] mktag: mark strings for translation Ævar Arnfjörð Bjarmason
2021-01-05 19:42                 ` [PATCH v5 23/23] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
2021-01-06  1:48                   ` Junio C Hamano
2021-01-06 11:47                     ` [PATCH v6 23/23] mktag: add a --[no-]strict option Ævar Arnfjörð Bjarmason
2021-01-06 22:21                       ` Junio C Hamano
2021-01-07  7:45                         ` Ævar Arnfjörð Bjarmason
2020-12-23  1:35               ` [PATCH v4 01/20] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
2020-12-23  1:35               ` [PATCH v4 02/20] mktag doc: grammar fix, when exists -> when it exists Ævar Arnfjörð Bjarmason
2020-12-23  1:35               ` [PATCH v4 03/20] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
2020-12-23  1:57                 ` Junio C Hamano
2020-12-23  1:35               ` [PATCH v4 04/20] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
2020-12-23  1:35               ` [PATCH v4 05/20] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
2020-12-23  1:35               ` [PATCH v4 06/20] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
2020-12-23  2:04                 ` Junio C Hamano
2020-12-23  1:35               ` [PATCH v4 07/20] mktag tests: don't pipe to stderr needlessly Ævar Arnfjörð Bjarmason
2020-12-23  2:10                 ` Junio C Hamano
2020-12-23  1:35               ` [PATCH v4 08/20] mktag tests: don't create "mytag" twice Ævar Arnfjörð Bjarmason
2020-12-23  2:18                 ` Junio C Hamano
2020-12-23  1:35               ` [PATCH v4 09/20] mktag tests: stress test whitespace handling Ævar Arnfjörð Bjarmason
2020-12-23  2:27                 ` Junio C Hamano
2020-12-23  1:35               ` [PATCH v4 10/20] mktag tests: test "hash-object" compatibility Ævar Arnfjörð Bjarmason
2020-12-23  2:29                 ` Junio C Hamano
2020-12-23  1:35               ` [PATCH v4 11/20] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
2020-12-23  1:35               ` [PATCH v4 12/20] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
2020-12-23  1:35               ` [PATCH v4 13/20] mktag: use puts(str) instead of printf("%s\n", str) Ævar Arnfjörð Bjarmason
2020-12-23  1:35               ` [PATCH v4 14/20] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
2020-12-23 13:34                 ` Junio C Hamano
2020-12-23  1:36               ` [PATCH v4 15/20] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
2020-12-23  1:36               ` [PATCH v4 16/20] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
2020-12-23 22:09                 ` SZEDER Gábor
2020-12-23  1:36               ` [PATCH v4 17/20] mktag: allow omitting the header/body \n separator Ævar Arnfjörð Bjarmason
2020-12-23  1:36               ` [PATCH v4 18/20] mktag: convert to parse-options Ævar Arnfjörð Bjarmason
2020-12-23  1:36               ` [PATCH v4 19/20] mktag: mark strings for translation Ævar Arnfjörð Bjarmason
2020-12-23  1:36               ` [PATCH v4 20/20] mktag: add a --no-strict option Ævar Arnfjörð Bjarmason
2020-12-23 11:54                 ` Junio C Hamano
2020-12-23 22:20                 ` SZEDER Gábor
2020-12-09 20:01             ` [PATCH v3 01/10] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 02/10] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 03/10] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 04/10] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 05/10] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 06/10] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 07/10] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 08/10] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 09/10] fsck: make fsck_config() re-usable Ævar Arnfjörð Bjarmason
2020-12-09 20:01             ` [PATCH v3 10/10] mktag: allow turning off fsck.extraHeaderEntry Ævar Arnfjörð Bjarmason
2020-11-26 22:22           ` [PATCH v2 01/10] mktag doc: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
2020-12-01 20:17             ` Junio C Hamano
2020-11-26 22:22           ` [PATCH v2 02/10] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
2020-12-01 20:19             ` Junio C Hamano
2020-11-26 22:22           ` [PATCH v2 03/10] mktag: reword write_object_file() error Ævar Arnfjörð Bjarmason
2020-12-01 20:20             ` Junio C Hamano
2020-12-01 20:49               ` Junio C Hamano
2020-11-26 22:22           ` [PATCH v2 04/10] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
2020-11-26 22:22           ` [PATCH v2 05/10] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
2020-11-26 22:22           ` [PATCH v2 06/10] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
2020-12-01 20:24             ` Junio C Hamano
2020-11-26 22:22           ` [PATCH v2 07/10] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
2020-11-26 22:22           ` [PATCH v2 08/10] fsck: add new "extra" checks for "mktag" Ævar Arnfjörð Bjarmason
2020-12-01 20:33             ` Junio C Hamano
2020-11-26 22:22           ` [PATCH v2 09/10] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
2020-12-01 20:47             ` Junio C Hamano
2020-12-01 22:28               ` Junio C Hamano
2020-11-26 22:22           ` [PATCH v2 10/10] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
2020-12-01 20:59             ` Junio C Hamano
2020-11-26  1:28         ` [RFC/PATCH 01/12] mktag: use default strbuf_read() hint Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 02/12] mktag: reword write_object_file() error Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 03/12] mktag: remove redundant braces in one-line body "if" Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 04/12] mktag tests: don't needlessly use a subshell Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 05/12] mktag tests: remove needless SHA-1 hardcoding Ævar Arnfjörð Bjarmason
2020-11-26  7:49           ` Jeff King
2020-11-26  1:28         ` [RFC/PATCH 06/12] mktag tests: improve verify_object() test coverage Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 07/12] fsck: add new "extra" checks for "mktag" Ævar Arnfjörð Bjarmason
2020-11-26  8:02           ` Jeff King
2020-11-26 12:43             ` Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 08/12] mktag: use fsck instead of custom verify_tag() Ævar Arnfjörð Bjarmason
2020-11-26  8:17           ` Jeff King
2020-11-26 12:46             ` Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 09/12] mktag: remove now-unused verify_tag() code Ævar Arnfjörð Bjarmason
2020-11-26  8:20           ` Jeff King
2020-11-26  1:28         ` [RFC/PATCH 10/12] mktag doc: update to explain why to use this Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 11/12] mktag docs: say <hash> not <sha1> Ævar Arnfjörð Bjarmason
2020-11-26  1:28         ` [RFC/PATCH 12/12] mktag: bring back some of the verify_object() logic Ævar Arnfjörð Bjarmason
2020-11-26  8:32           ` Jeff King
2019-08-26  1:43   ` [PATCH v2 11/14] t3903: abstract away SHA-1-specific constants brian m. carlson
2019-08-26  1:43   ` [PATCH v2 12/14] t4000: make hash size independent brian m. carlson
2019-08-26  1:43   ` [PATCH v2 13/14] t4002: make hash independent brian m. carlson
2019-08-26  1:43   ` [PATCH v2 14/14] t4009: make hash size independent brian m. carlson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).