git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/5] Enable protocol v2 by default
@ 2019-12-24  0:58 Jonathan Nieder
  2019-12-24  0:59 ` [PATCH 1/5] fetch test: use more robust test for filtered objects Jonathan Nieder
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-24  0:58 UTC (permalink / raw)
  To: git; +Cc: Jonathan Tan, Jeff King, Jeff Hostetler

Hi,

The Git users at $DAYJOB have been using protocol v2 as a default for
~1.5 years now and others have been also reporting good experiences
with it, so it seems like a good time to propose bumping the default
version.  It produces a significant performance improvement when
fetching from repositories with many refs, such as
https://chromium.googlesource.com/chromium/src.

This only affects the client, not the server.  (The server already
defaults to supporting protocol v2.)

This could go in 2.25 (most of the "next" population is likely already
using protocol.version=2, so the -rc period would be one of the better
ways to expand the user population using this) or could cook in "next"
for a cycle.  Either is fine by me.

Thoughts of all kinds welcome, as always.

Jonathan Nieder (5):
  fetch test: use more robust test for filtered objects
  config doc: protocol.version is not experimental
  test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate
  protocol test: let protocol.version override GIT_TEST_PROTOCOL_VERSION
  fetch: default to protocol version 2

 Documentation/config/protocol.txt    |  9 ++++-----
 protocol.c                           | 11 +++++------
 t/README                             |  4 ++--
 t/t5400-send-pack.sh                 |  2 +-
 t/t5500-fetch-pack.sh                | 23 ++++++++++++++++-------
 t/t5512-ls-remote.sh                 | 10 +++++-----
 t/t5515-fetch-merge-logic.sh         |  3 ++-
 t/t5516-fetch-push.sh                | 12 ++++++------
 t/t5539-fetch-http-shallow.sh        |  2 +-
 t/t5541-http-push-smart.sh           |  4 ++--
 t/t5551-http-fetch-smart.sh          | 12 ++++++------
 t/t5552-skipping-fetch-negotiator.sh |  2 +-
 t/t5700-protocol-v1.sh               |  3 ++-
 t/t7406-submodule-update.sh          |  2 +-
 14 files changed, 54 insertions(+), 45 deletions(-)

base-commit: 12029dc57db23baef008e77db1909367599210ee

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

* [PATCH 1/5] fetch test: use more robust test for filtered objects
  2019-12-24  0:58 [PATCH 0/5] Enable protocol v2 by default Jonathan Nieder
@ 2019-12-24  0:59 ` Jonathan Nieder
  2019-12-26 14:29   ` Derrick Stolee
  2019-12-24  1:00 ` [PATCH 2/5] config doc: protocol.version is not experimental Jonathan Nieder
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-24  0:59 UTC (permalink / raw)
  To: git; +Cc: Jonathan Tan, Jeff King, Jeff Hostetler

"git cat-file -e" uses has_object_file, which can fetch from promisor
remotes when an object is missing.  These tests end up checking that
that fetch fails instead of for the object being missing.

By luck, the tests pass anyway:

- in one of these tests ("filtering by size"), the fetch fails because
  (in protocol v0) the server does not support fetches by SHA-1

- in the second, the object is present but the test could pass even if
  it weren't if the fetch succeeds

- in the third, the test sets extensions.partialClone to "arbitrary
  string" so that when it tries to fetch, it looks up the "arbitrary
  string" remote which does not exist

Use "git rev-list --objects --missing=allow-any", so that the tests
pass for the right reason.

Noticed while testing with protocol v2, which allows fetching by sha1
by default, causing the first fetch to succeed and the test to fail.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 t/t5500-fetch-pack.sh | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 6b97923964..964930b2d2 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -917,7 +917,10 @@ test_expect_success 'filtering by size' '
 	git -C client fetch-pack --filter=blob:limit=0 ../server HEAD &&
 
 	# Ensure that object is not inadvertently fetched
-	test_must_fail git -C client cat-file -e $(git hash-object server/one.t)
+	commit=$(git -C server rev-parse HEAD) &&
+	blob=$(git hash-object server/one.t) &&
+	git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
+	! grep "$blob" oids
 '
 
 test_expect_success 'filtering by size has no effect if support for it is not advertised' '
@@ -929,7 +932,10 @@ test_expect_success 'filtering by size has no effect if support for it is not ad
 	git -C client fetch-pack --filter=blob:limit=0 ../server HEAD 2> err &&
 
 	# Ensure that object is fetched
-	git -C client cat-file -e $(git hash-object server/one.t) &&
+	commit=$(git -C server rev-parse HEAD) &&
+	blob=$(git hash-object server/one.t) &&
+	git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
+	grep "$blob" oids &&
 
 	test_i18ngrep "filtering not recognized by server" err
 '
@@ -951,9 +957,11 @@ fetch_filter_blob_limit_zero () {
 	git -C client fetch --filter=blob:limit=0 origin HEAD:somewhere &&
 
 	# Ensure that commit is fetched, but blob is not
-	test_config -C client extensions.partialclone "arbitrary string" &&
-	git -C client cat-file -e $(git -C "$SERVER" rev-parse two) &&
-	test_must_fail git -C client cat-file -e $(git hash-object "$SERVER/two.t")
+	commit=$(git -C "$SERVER" rev-parse two) &&
+	blob=$(git hash-object server/two.t) &&
+	git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
+	grep "$commit" oids &&
+	! grep "$blob" oids
 }
 
 test_expect_success 'fetch with --filter=blob:limit=0' '
-- 
2.24.1.735.g03f4e72817


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

* [PATCH 2/5] config doc: protocol.version is not experimental
  2019-12-24  0:58 [PATCH 0/5] Enable protocol v2 by default Jonathan Nieder
  2019-12-24  0:59 ` [PATCH 1/5] fetch test: use more robust test for filtered objects Jonathan Nieder
@ 2019-12-24  1:00 ` Jonathan Nieder
  2019-12-24  1:01 ` [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate Jonathan Nieder
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-24  1:00 UTC (permalink / raw)
  To: git; +Cc: Jonathan Tan, Jeff King, Jeff Hostetler

Git's protocol version 2 has been working well in production for over
a year.  Simplify documentation by no longer referring to it as
experimental.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 Documentation/config/protocol.txt | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Documentation/config/protocol.txt b/Documentation/config/protocol.txt
index bfccc07491..0b40141613 100644
--- a/Documentation/config/protocol.txt
+++ b/Documentation/config/protocol.txt
@@ -45,11 +45,10 @@ The protocol names currently used by git are:
 --
 
 protocol.version::
-	Experimental. If set, clients will attempt to communicate with a
-	server using the specified protocol version.  If unset, no
-	attempt will be made by the client to communicate using a
-	particular protocol version, this results in protocol version 0
-	being used.
+	If set, clients will attempt to communicate with a server
+	using the specified protocol version.  If the server does
+	not support it, communication falls back to version 0.
+	If unset, the default is `0`.
 	Supported versions:
 +
 --
-- 
2.24.1.735.g03f4e72817


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

* [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate
  2019-12-24  0:58 [PATCH 0/5] Enable protocol v2 by default Jonathan Nieder
  2019-12-24  0:59 ` [PATCH 1/5] fetch test: use more robust test for filtered objects Jonathan Nieder
  2019-12-24  1:00 ` [PATCH 2/5] config doc: protocol.version is not experimental Jonathan Nieder
@ 2019-12-24  1:01 ` Jonathan Nieder
  2019-12-26 19:26   ` Junio C Hamano
  2019-12-24  1:02 ` [PATCH 4/5] protocol test: let protocol.version override GIT_TEST_PROTOCOL_VERSION Jonathan Nieder
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-24  1:01 UTC (permalink / raw)
  To: git; +Cc: Jonathan Tan, Jeff King, Jeff Hostetler

Since 8cbeba0632 (tests: define GIT_TEST_PROTOCOL_VERSION,
2019-02-25), it has been possible to run tests with a newer protocol
version by setting the GIT_TEST_PROTOCOL_VERSION envvar to a version
number.  Tests that assume protocol v0 handle this by explicitly
setting

	GIT_TEST_PROTOCOL_VERSION=

or similar constructs like 'test -z "$GIT_TEST_PROTOCOL_VERSION" ||
return 0' to declare that they only handle the default (v0) protocol.

The emphasis there is a bit off: it would be clearer to specify
GIT_TEST_PROTOCOL_VERSION=0 to inform the reader that these tests are
specifically testing and relying on details of protocol v0.  Do so.

This way, a reader does not need to know what the default protocol
version is, and the tests can continue to work when the default
protocol version used by Git advances past v0.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 t/t5400-send-pack.sh                 |  2 +-
 t/t5500-fetch-pack.sh                |  5 +++--
 t/t5512-ls-remote.sh                 | 10 +++++-----
 t/t5515-fetch-merge-logic.sh         |  3 ++-
 t/t5516-fetch-push.sh                | 12 ++++++------
 t/t5539-fetch-http-shallow.sh        |  2 +-
 t/t5541-http-push-smart.sh           |  4 ++--
 t/t5551-http-fetch-smart.sh          | 12 ++++++------
 t/t5552-skipping-fetch-negotiator.sh |  2 +-
 t/t5700-protocol-v1.sh               |  3 ++-
 t/t7406-submodule-update.sh          |  2 +-
 11 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 571d620aed..b84618c925 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
@@ -288,7 +288,7 @@ test_expect_success 'receive-pack de-dupes .have lines' '
 	$shared .have
 	EOF
 
-	GIT_TRACE_PACKET=$(pwd)/trace GIT_TEST_PROTOCOL_VERSION= \
+	GIT_TRACE_PACKET=$(pwd)/trace GIT_TEST_PROTOCOL_VERSION=0 \
 	    git push \
 		--receive-pack="unset GIT_TRACE_PACKET; git-receive-pack" \
 		fork HEAD:foo &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 964930b2d2..baa1a99f45 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -440,11 +440,12 @@ test_expect_success 'setup tests for the --stdin parameter' '
 '
 
 test_expect_success 'setup fetch refs from cmdline v[12]' '
+	cp -r client client0 &&
 	cp -r client client1 &&
 	cp -r client client2
 '
 
-for version in '' 1 2
+for version in '' 0 1 2
 do
 	test_expect_success "protocol.version=$version fetch refs from cmdline" "
 		(
@@ -638,7 +639,7 @@ test_expect_success 'fetch-pack cannot fetch a raw sha1 that is not advertised a
 	git init client &&
 	# Some protocol versions (e.g. 2) support fetching
 	# unadvertised objects, so restrict this test to v0.
-	test_must_fail env GIT_TEST_PROTOCOL_VERSION= git -C client fetch-pack ../server \
+	test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -C client fetch-pack ../server \
 		$(git -C server rev-parse refs/heads/master^) 2>err &&
 	test_i18ngrep "Server does not allow request for unadvertised object" err
 '
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index d7b9f9078f..459d1fcddf 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -225,7 +225,7 @@ test_expect_success 'ls-remote --symref' '
 	EOF
 	# Protocol v2 supports sending symrefs for refs other than HEAD, so use
 	# protocol v0 here.
-	GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref >actual &&
+	GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref >actual &&
 	test_cmp expect actual
 '
 
@@ -236,7 +236,7 @@ test_expect_success 'ls-remote with filtered symref (refname)' '
 	EOF
 	# Protocol v2 supports sending symrefs for refs other than HEAD, so use
 	# protocol v0 here.
-	GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref . HEAD >actual &&
+	GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . HEAD >actual &&
 	test_cmp expect actual
 '
 
@@ -249,7 +249,7 @@ test_expect_failure 'ls-remote with filtered symref (--heads)' '
 	EOF
 	# Protocol v2 supports sending symrefs for refs other than HEAD, so use
 	# protocol v0 here.
-	GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref --heads . >actual &&
+	GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
 	test_cmp expect actual
 '
 
@@ -260,9 +260,9 @@ test_expect_success 'ls-remote --symref omits filtered-out matches' '
 	EOF
 	# Protocol v2 supports sending symrefs for refs other than HEAD, so use
 	# protocol v0 here.
-	GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref --heads . >actual &&
+	GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
 	test_cmp expect actual &&
-	GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref . "refs/heads/*" >actual &&
+	GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . "refs/heads/*" >actual &&
 	test_cmp expect actual
 '
 
diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh
index 961eb35c99..a9a7d50d3e 100755
--- a/t/t5515-fetch-merge-logic.sh
+++ b/t/t5515-fetch-merge-logic.sh
@@ -8,7 +8,8 @@ test_description='Merge logic in fetch'
 
 # NEEDSWORK: If the overspecification of the expected result is reduced, we
 # might be able to run this test in all protocol versions.
-GIT_TEST_PROTOCOL_VERSION=
+GIT_TEST_PROTOCOL_VERSION=0
+export GIT_TEST_PROTOCOL_VERSION
 
 . ./test-lib.sh
 
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index c81ca360ac..f12cbef097 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1151,7 +1151,7 @@ test_expect_success 'fetch exact SHA1' '
 		# unadvertised objects, so restrict this test to v0.
 
 		# fetching the hidden object should fail by default
-		test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+		test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 			git fetch -v ../testrepo $the_commit:refs/heads/copy 2>err &&
 		test_i18ngrep "Server does not allow request for unadvertised object" err &&
 		test_must_fail git rev-parse --verify refs/heads/copy &&
@@ -1210,7 +1210,7 @@ do
 			cd shallow &&
 			# Some protocol versions (e.g. 2) support fetching
 			# unadvertised objects, so restrict this test to v0.
-			test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+			test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 				git fetch --depth=1 ../testrepo/.git $SHA1 &&
 			git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
 			git fetch --depth=1 ../testrepo/.git $SHA1 &&
@@ -1241,9 +1241,9 @@ do
 			cd shallow &&
 			# Some protocol versions (e.g. 2) support fetching
 			# unadvertised objects, so restrict this test to v0.
-			test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+			test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 				git fetch ../testrepo/.git $SHA1_3 &&
-			test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+			test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 				git fetch ../testrepo/.git $SHA1_1 &&
 			git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
 			git fetch ../testrepo/.git $SHA1_1 &&
@@ -1251,7 +1251,7 @@ do
 			test_must_fail git cat-file commit $SHA1_2 &&
 			git fetch ../testrepo/.git $SHA1_2 &&
 			git cat-file commit $SHA1_2 &&
-			test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+			test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 				git fetch ../testrepo/.git $SHA1_3 2>err &&
 			test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
 		)
@@ -1291,7 +1291,7 @@ test_expect_success 'peeled advertisements are not considered ref tips' '
 	git -C testrepo commit --allow-empty -m two &&
 	git -C testrepo tag -m foo mytag HEAD^ &&
 	oid=$(git -C testrepo rev-parse mytag^{commit}) &&
-	test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+	test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 		git fetch testrepo $oid 2>err &&
 	test_i18ngrep "Server does not allow request for unadvertised object" err
 '
diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh
index b4ad81f006..c0d02dee89 100755
--- a/t/t5539-fetch-http-shallow.sh
+++ b/t/t5539-fetch-http-shallow.sh
@@ -69,7 +69,7 @@ test_expect_success 'no shallow lines after receiving ACK ready' '
 		test_commit new-too &&
 		# NEEDSWORK: If the overspecification of the expected result is reduced, we
 		# might be able to run this test in all protocol versions.
-		GIT_TRACE_PACKET="$TRASH_DIRECTORY/trace" GIT_TEST_PROTOCOL_VERSION= \
+		GIT_TRACE_PACKET="$TRASH_DIRECTORY/trace" GIT_TEST_PROTOCOL_VERSION=0 \
 			git fetch --depth=2 &&
 		grep "fetch-pack< ACK .* ready" ../trace &&
 		! grep "fetch-pack> done" ../trace
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 4c970787b0..23be8ce92d 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -49,7 +49,7 @@ test_expect_success 'no empty path components' '
 
 	# NEEDSWORK: If the overspecification of the expected result is reduced, we
 	# might be able to run this test in all protocol versions.
-	if test -z "$GIT_TEST_PROTOCOL_VERSION"
+	if test "$GIT_TEST_PROTOCOL_VERSION" = 0
 	then
 		check_access_log exp
 	fi
@@ -135,7 +135,7 @@ EOF
 test_expect_success 'used receive-pack service' '
 	# NEEDSWORK: If the overspecification of the expected result is reduced, we
 	# might be able to run this test in all protocol versions.
-	if test -z "$GIT_TEST_PROTOCOL_VERSION"
+	if test "$GIT_TEST_PROTOCOL_VERSION" = 0
 	then
 		check_access_log exp
 	fi
diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
index e38e543867..6788aeface 100755
--- a/t/t5551-http-fetch-smart.sh
+++ b/t/t5551-http-fetch-smart.sh
@@ -43,7 +43,7 @@ test_expect_success 'clone http repository' '
 	< Cache-Control: no-cache, max-age=0, must-revalidate
 	< Content-Type: application/x-git-upload-pack-result
 	EOF
-	GIT_TRACE_CURL=true GIT_TEST_PROTOCOL_VERSION= \
+	GIT_TRACE_CURL=true GIT_TEST_PROTOCOL_VERSION=0 \
 		git clone --quiet $HTTPD_URL/smart/repo.git clone 2>err &&
 	test_cmp file clone/file &&
 	tr '\''\015'\'' Q <err |
@@ -84,7 +84,7 @@ test_expect_success 'clone http repository' '
 
 	# NEEDSWORK: If the overspecification of the expected result is reduced, we
 	# might be able to run this test in all protocol versions.
-	if test -z "$GIT_TEST_PROTOCOL_VERSION"
+	if test "$GIT_TEST_PROTOCOL_VERSION" = 0
 	then
 		sed -e "s/^> Accept-Encoding: .*/> Accept-Encoding: ENCODINGS/" \
 				actual >actual.smudged &&
@@ -113,7 +113,7 @@ test_expect_success 'used upload-pack service' '
 
 	# NEEDSWORK: If the overspecification of the expected result is reduced, we
 	# might be able to run this test in all protocol versions.
-	if test -z "$GIT_TEST_PROTOCOL_VERSION"
+	if test "$GIT_TEST_PROTOCOL_VERSION" = 0
 	then
 		check_access_log exp
 	fi
@@ -241,7 +241,7 @@ test_expect_success 'cookies stored in http.cookiefile when http.savecookies set
 
 	# NEEDSWORK: If the overspecification of the expected result is reduced, we
 	# might be able to run this test in all protocol versions.
-	if test -z "$GIT_TEST_PROTOCOL_VERSION"
+	if test "$GIT_TEST_PROTOCOL_VERSION" = 0
 	then
 		tail -3 cookies.txt | sort >cookies_tail.txt &&
 		test_cmp expect_cookies.txt cookies_tail.txt
@@ -336,7 +336,7 @@ test_expect_success 'test allowreachablesha1inwant with unreachable' '
 	git -C test_reachable.git remote add origin "$HTTPD_URL/smart/repo.git" &&
 	# Some protocol versions (e.g. 2) support fetching
 	# unadvertised objects, so restrict this test to v0.
-	test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+	test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 		git -C test_reachable.git fetch origin "$(git rev-parse HEAD)"
 '
 
@@ -358,7 +358,7 @@ test_expect_success 'test allowanysha1inwant with unreachable' '
 	git -C test_reachable.git remote add origin "$HTTPD_URL/smart/repo.git" &&
 	# Some protocol versions (e.g. 2) support fetching
 	# unadvertised objects, so restrict this test to v0.
-	test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+	test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 		git -C test_reachable.git fetch origin "$(git rev-parse HEAD)" &&
 
 	git -C "$server" config uploadpack.allowanysha1inwant 1 &&
diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh
index f70cbcc9ca..a2a5e0743f 100755
--- a/t/t5552-skipping-fetch-negotiator.sh
+++ b/t/t5552-skipping-fetch-negotiator.sh
@@ -107,7 +107,7 @@ test_expect_success 'use ref advertisement to filter out commits' '
 
 	# The ref advertisement itself is filtered when protocol v2 is used, so
 	# use v0.
-	GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch &&
+	GIT_TEST_PROTOCOL_VERSION=0 trace_fetch client origin to_fetch &&
 	have_sent c5 c4^ c2side &&
 	have_not_sent c4 c4^^ c4^^^
 '
diff --git a/t/t5700-protocol-v1.sh b/t/t5700-protocol-v1.sh
index 2571eb90b7..022901b9eb 100755
--- a/t/t5700-protocol-v1.sh
+++ b/t/t5700-protocol-v1.sh
@@ -5,7 +5,8 @@ test_description='test git wire-protocol transition'
 TEST_NO_CREATE_REPO=1
 
 # This is a protocol-specific test.
-GIT_TEST_PROTOCOL_VERSION=
+GIT_TEST_PROTOCOL_VERSION=0
+export GIT_TEST_PROTOCOL_VERSION
 
 . ./test-lib.sh
 
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 7478f7ab7e..4fb447a143 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -960,7 +960,7 @@ test_expect_success 'submodule update clone shallow submodule outside of depth'
 		mv -f .gitmodules.tmp .gitmodules &&
 		# Some protocol versions (e.g. 2) support fetching
 		# unadvertised objects, so restrict this test to v0.
-		test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+		test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
 			git submodule update --init --depth=1 2>actual &&
 		test_i18ngrep "Direct fetching of that commit failed." actual &&
 		git -C ../submodule config uploadpack.allowReachableSHA1InWant true &&
-- 
2.24.1.735.g03f4e72817


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

* [PATCH 4/5] protocol test: let protocol.version override GIT_TEST_PROTOCOL_VERSION
  2019-12-24  0:58 [PATCH 0/5] Enable protocol v2 by default Jonathan Nieder
                   ` (2 preceding siblings ...)
  2019-12-24  1:01 ` [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate Jonathan Nieder
@ 2019-12-24  1:02 ` Jonathan Nieder
  2019-12-24  1:04 ` [PATCH 5/5] fetch: default to protocol version 2 Jonathan Nieder
  2019-12-26 14:30 ` [PATCH 0/5] Enable protocol v2 by default Derrick Stolee
  5 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-24  1:02 UTC (permalink / raw)
  To: git; +Cc: Jonathan Tan, Jeff King, Jeff Hostetler

The GIT_TEST_PROTOCOL_VERSION environment variable can be used to
upgrade the version of Git protocol used in tests.  If both
GIT_TEST_PROTOCOL_VERSION and 'protocol.version' are set, the higher
value wins.

For usage within tests, these semantics are too complex.  Instead,
always use the value from protocol.version configuration when it is
set, falling back to GIT_TEST_PROTOCOL_VERSION.  This way, the envvar
provides a reliable preview of what will happen if the default
protocol version is changed.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
I'd like to remove the built-in support for GIT_TEST_PROTOCOL_VERSION
altogether and replace it with support in the test harness for setting
protocol.version to the specified value, but that can wait for a
followup another day.

 protocol.c | 11 +++++------
 t/README   |  4 ++--
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/protocol.c b/protocol.c
index 9741f05750..d390391eba 100644
--- a/protocol.c
+++ b/protocol.c
@@ -17,9 +17,8 @@ static enum protocol_version parse_protocol_version(const char *value)
 enum protocol_version get_protocol_version_config(void)
 {
 	const char *value;
-	enum protocol_version retval = protocol_v0;
 	const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION";
-	const char *git_test_v = getenv(git_test_k);
+	const char *git_test_v;
 
 	if (!git_config_get_string_const("protocol.version", &value)) {
 		enum protocol_version version = parse_protocol_version(value);
@@ -28,19 +27,19 @@ enum protocol_version get_protocol_version_config(void)
 			die("unknown value for config 'protocol.version': %s",
 			    value);
 
-		retval = version;
+		return version;
 	}
 
+	git_test_v = getenv(git_test_k);
 	if (git_test_v && *git_test_v) {
 		enum protocol_version env = parse_protocol_version(git_test_v);
 
 		if (env == protocol_unknown_version)
 			die("unknown value for %s: %s", git_test_k, git_test_v);
-		if (retval < env)
-			retval = env;
+		return env;
 	}
 
-	return retval;
+	return protocol_v0;
 }
 
 enum protocol_version determine_protocol_version_server(void)
diff --git a/t/README b/t/README
index caa125ba9a..9afd61e3ca 100644
--- a/t/README
+++ b/t/README
@@ -352,8 +352,8 @@ 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.
 
-GIT_TEST_PROTOCOL_VERSION=<n>, when set, overrides the
-'protocol.version' setting to n if it is less than n.
+GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version'
+default to n.
 
 GIT_TEST_FULL_IN_PACK_ARRAY=<boolean> exercises the uncommon
 pack-objects code path where there are more than 1024 packs even if
-- 
2.24.1.735.g03f4e72817


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

* [PATCH 5/5] fetch: default to protocol version 2
  2019-12-24  0:58 [PATCH 0/5] Enable protocol v2 by default Jonathan Nieder
                   ` (3 preceding siblings ...)
  2019-12-24  1:02 ` [PATCH 4/5] protocol test: let protocol.version override GIT_TEST_PROTOCOL_VERSION Jonathan Nieder
@ 2019-12-24  1:04 ` Jonathan Nieder
  2019-12-26 14:30 ` [PATCH 0/5] Enable protocol v2 by default Derrick Stolee
  5 siblings, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-24  1:04 UTC (permalink / raw)
  To: git; +Cc: Jonathan Tan, Jeff King, Jeff Hostetler

The Git users at $DAYJOB have been using protocol v2 as a default for
~1.5 years now and others have been also reporting good experiences
with it, so it seems like a good time to bump the default version.  It
produces a significant performance improvement when fetching from
repositories with many refs, such as
https://chromium.googlesource.com/chromium/src.

This only affects the client, not the server.  (The server already
defaults to supporting protocol v2.)  The protocol change is backward
compatible, so this should produce no significant effect when
contacting servers that only speak protocol v0.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
That's the end of the series.  Thanks for reading.

Thoughts?

 Documentation/config/protocol.txt | 2 +-
 protocol.c                        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/config/protocol.txt b/Documentation/config/protocol.txt
index 0b40141613..756591d77b 100644
--- a/Documentation/config/protocol.txt
+++ b/Documentation/config/protocol.txt
@@ -48,7 +48,7 @@ protocol.version::
 	If set, clients will attempt to communicate with a server
 	using the specified protocol version.  If the server does
 	not support it, communication falls back to version 0.
-	If unset, the default is `0`.
+	If unset, the default is `2`.
 	Supported versions:
 +
 --
diff --git a/protocol.c b/protocol.c
index d390391eba..803bef5c87 100644
--- a/protocol.c
+++ b/protocol.c
@@ -39,7 +39,7 @@ enum protocol_version get_protocol_version_config(void)
 		return env;
 	}
 
-	return protocol_v0;
+	return protocol_v2;
 }
 
 enum protocol_version determine_protocol_version_server(void)
-- 
2.24.1.735.g03f4e72817


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

* Re: [PATCH 1/5] fetch test: use more robust test for filtered objects
  2019-12-24  0:59 ` [PATCH 1/5] fetch test: use more robust test for filtered objects Jonathan Nieder
@ 2019-12-26 14:29   ` Derrick Stolee
  0 siblings, 0 replies; 17+ messages in thread
From: Derrick Stolee @ 2019-12-26 14:29 UTC (permalink / raw)
  To: Jonathan Nieder, git; +Cc: Jonathan Tan, Jeff King, Jeff Hostetler

On 12/23/2019 7:59 PM, Jonathan Nieder wrote:
>  	# Ensure that object is not inadvertently fetched
> -	test_must_fail git -C client cat-file -e $(git hash-object server/one.t)
> +	commit=$(git -C server rev-parse HEAD) &&
> +	blob=$(git hash-object server/one.t) &&
> +	git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
> +	! grep "$blob" oids
>  '
>  
>  test_expect_success 'filtering by size has no effect if support for it is not advertised' '
> @@ -929,7 +932,10 @@ test_expect_success 'filtering by size has no effect if support for it is not ad
>  	git -C client fetch-pack --filter=blob:limit=0 ../server HEAD 2> err &&
>  
>  	# Ensure that object is fetched
> -	git -C client cat-file -e $(git hash-object server/one.t) &&
> +	commit=$(git -C server rev-parse HEAD) &&
> +	blob=$(git hash-object server/one.t) &&
> +	git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
> +	grep "$blob" oids &&
>  
>  	test_i18ngrep "filtering not recognized by server" err
>  '
> @@ -951,9 +957,11 @@ fetch_filter_blob_limit_zero () {
>  	git -C client fetch --filter=blob:limit=0 origin HEAD:somewhere &&
>  
>  	# Ensure that commit is fetched, but blob is not
> -	test_config -C client extensions.partialclone "arbitrary string" &&
> -	git -C client cat-file -e $(git -C "$SERVER" rev-parse two) &&
> -	test_must_fail git -C client cat-file -e $(git hash-object "$SERVER/two.t")
> +	commit=$(git -C "$SERVER" rev-parse two) &&
> +	blob=$(git hash-object server/two.t) &&
> +	git -C client rev-list --objects --missing=allow-any "$commit" >oids &&
> +	grep "$commit" oids &&
> +	! grep "$blob" oids

At first glance, I saw this and thought the "three is many" rule would imply
the boilerplate in these tests should be de-duplicated with a function.
However, the use of the "commit" and "blob" variables is different in each
test, so I did not find a convenient way to make this simpler.

Thanks,
-Stolee


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

* Re: [PATCH 0/5] Enable protocol v2 by default
  2019-12-24  0:58 [PATCH 0/5] Enable protocol v2 by default Jonathan Nieder
                   ` (4 preceding siblings ...)
  2019-12-24  1:04 ` [PATCH 5/5] fetch: default to protocol version 2 Jonathan Nieder
@ 2019-12-26 14:30 ` Derrick Stolee
  5 siblings, 0 replies; 17+ messages in thread
From: Derrick Stolee @ 2019-12-26 14:30 UTC (permalink / raw)
  To: Jonathan Nieder, git; +Cc: Jonathan Tan, Jeff King, Jeff Hostetler

On 12/23/2019 7:58 PM, Jonathan Nieder wrote:
> Hi,
> 
> The Git users at $DAYJOB have been using protocol v2 as a default for
> ~1.5 years now and others have been also reporting good experiences
> with it, so it seems like a good time to propose bumping the default
> version.  It produces a significant performance improvement when
> fetching from repositories with many refs, such as
> https://chromium.googlesource.com/chromium/src.

The benefits of protocol v2 are very clear, assuming the server
supports it. And I'm pretty sure there is no downside, as a v0
server continues responding to the v2 request without any extra
round trips to agree on protocol.

> This only affects the client, not the server.  (The server already
> defaults to supporting protocol v2.)
> 
> This could go in 2.25 (most of the "next" population is likely already
> using protocol.version=2, so the -rc period would be one of the better
> ways to expand the user population using this) or could cook in "next"
> for a cycle.  Either is fine by me.

I have no firm opinion on when this lands. The code change is much simpler
than I would have thought, and perhaps we had enough testing of the protocol
by experts.

This series looks good to me.

Thanks,
-Stolee

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

* Re: [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate
  2019-12-24  1:01 ` [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate Jonathan Nieder
@ 2019-12-26 19:26   ` Junio C Hamano
  2019-12-26 19:53     ` [PATCH 0/2] avoid use of "VAR= cmd" with a shell function (Re: [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate) Jonathan Nieder
  0 siblings, 1 reply; 17+ messages in thread
From: Junio C Hamano @ 2019-12-26 19:26 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git, Jonathan Tan, Jeff King, Jeff Hostetler

Jonathan Nieder <jrnieder@gmail.com> writes:

> diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh
> index f70cbcc9ca..a2a5e0743f 100755
> --- a/t/t5552-skipping-fetch-negotiator.sh
> +++ b/t/t5552-skipping-fetch-negotiator.sh
> @@ -107,7 +107,7 @@ test_expect_success 'use ref advertisement to filter out commits' '
>  
>  	# The ref advertisement itself is filtered when protocol v2 is used, so
>  	# use v0.
> -	GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch &&
> +	GIT_TEST_PROTOCOL_VERSION=0 trace_fetch client origin to_fetch &&

Didn't this trigger "FOO=bar shell_func" test lint for you?


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

* [PATCH 0/2] avoid use of "VAR= cmd" with a shell function (Re: [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate)
  2019-12-26 19:26   ` Junio C Hamano
@ 2019-12-26 19:53     ` Jonathan Nieder
  2019-12-26 19:55       ` [PATCH 1/2] fetch test: avoid use of "VAR= cmd" with a shell function Jonathan Nieder
  2019-12-26 19:57       ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Jonathan Nieder
  0 siblings, 2 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-26 19:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jonathan Tan, Jeff King, Jeff Hostetler

Hi,

Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:

>> diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh
>> index f70cbcc9ca..a2a5e0743f 100755
>> --- a/t/t5552-skipping-fetch-negotiator.sh
>> +++ b/t/t5552-skipping-fetch-negotiator.sh
>> @@ -107,7 +107,7 @@ test_expect_success 'use ref advertisement to filter out commits' '
>>  
>>  	# The ref advertisement itself is filtered when protocol v2 is used, so
>>  	# use v0.
>> -	GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch &&
>> +	GIT_TEST_PROTOCOL_VERSION=0 trace_fetch client origin to_fetch &&
>
> Didn't this trigger "FOO=bar shell_func" test lint for you?

It does indeed.  Here are some preparatory patches to handle that.

Jonathan Nieder (2):
  fetch test: avoid use of "VAR= cmd" with a shell function
  t/check-non-portable-shell: detect "FOO= shell_func", too

 t/check-non-portable-shell.pl        | 2 +-
 t/t5552-skipping-fetch-negotiator.sh | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

base-commit: 99c33bed562b41de6ce9bd3fd561303d39645048

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

* [PATCH 1/2] fetch test: avoid use of "VAR= cmd" with a shell function
  2019-12-26 19:53     ` [PATCH 0/2] avoid use of "VAR= cmd" with a shell function (Re: [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate) Jonathan Nieder
@ 2019-12-26 19:55       ` Jonathan Nieder
  2019-12-26 19:57       ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Jonathan Nieder
  1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-26 19:55 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Jonathan Tan, Jeff King, Jeff Hostetler

Just like assigning a nonempty value, assigning an empty value to a
shell variable when calling a function produces non-portable behavior:
in some shells, the assignment lasts for the duration of the function
invocation, and in others, it persists after the function returns.

Use an explicit subshell with the envvar exported to make the behavior
consistent across shells and crystal clear.

All previous instances of this pattern used "VAR=value" (with nonempty
`value`), which is already diagnosed automatically by "make test-lint"
since a0a630192d (t/check-non-portable-shell: detect "FOO=bar
shell_func", 2018-07-13).

Noticed using an improved "make test-lint".

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 t/t5552-skipping-fetch-negotiator.sh | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh
index f70cbcc9ca..a452fe32fa 100755
--- a/t/t5552-skipping-fetch-negotiator.sh
+++ b/t/t5552-skipping-fetch-negotiator.sh
@@ -107,7 +107,11 @@ test_expect_success 'use ref advertisement to filter out commits' '
 
 	# The ref advertisement itself is filtered when protocol v2 is used, so
 	# use v0.
-	GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch &&
+	(
+		GIT_TEST_PROTOCOL_VERSION= &&
+		export GIT_TEST_PROTOCOL_VERSION &&
+		trace_fetch client origin to_fetch
+	) &&
 	have_sent c5 c4^ c2side &&
 	have_not_sent c4 c4^^ c4^^^
 '
-- 
2.24.1.735.g03f4e72817


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

* [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too
  2019-12-26 19:53     ` [PATCH 0/2] avoid use of "VAR= cmd" with a shell function (Re: [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate) Jonathan Nieder
  2019-12-26 19:55       ` [PATCH 1/2] fetch test: avoid use of "VAR= cmd" with a shell function Jonathan Nieder
@ 2019-12-26 19:57       ` Jonathan Nieder
  2019-12-26 20:08         ` Junio C Hamano
                           ` (2 more replies)
  1 sibling, 3 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-26 19:57 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Jonathan Tan, Jeff King, Jeff Hostetler, Eric Sunshine

Just like assigning a nonempty value, assigning an empty value to a
shell variable when calling a function produces non-portable behavior:
in some shells, the assignment lasts for the duration of the function
invocation, and in others, it persists after the function returns.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
If it would be useful for me to send a copy of the "Enable protocol v2
by default" series rebased on top of this, let me know.

Thanks again for catching it.

Sincerely,
Jonathan

 t/check-non-portable-shell.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index 38bfeebd88..fd3303552b 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -46,7 +46,7 @@ sub err {
 	/(?:\$\(seq|^\s*seq\b)/ and err 'seq is not portable (use test_seq)';
 	/\bgrep\b.*--file\b/ and err 'grep --file FILE is not portable (use grep -f FILE)';
 	/\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)';
-	/^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
+	/^\s*([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
 		err '"FOO=bar shell_func" assignment extends beyond "shell_func"';
 	$line = '';
 	# this resets our $. for each file
-- 
2.24.1.735.g03f4e72817


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

* Re: [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too
  2019-12-26 19:57       ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Jonathan Nieder
@ 2019-12-26 20:08         ` Junio C Hamano
  2019-12-26 20:18         ` Junio C Hamano
  2019-12-26 20:39         ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Eric Sunshine
  2 siblings, 0 replies; 17+ messages in thread
From: Junio C Hamano @ 2019-12-26 20:08 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: git, Jonathan Tan, Jeff King, Jeff Hostetler, Eric Sunshine

Jonathan Nieder <jrnieder@gmail.com> writes:

> Just like assigning a nonempty value, assigning an empty value to a
> shell variable when calling a function produces non-portable behavior:
> in some shells, the assignment lasts for the duration of the function
> invocation, and in others, it persists after the function returns.
> ...
> diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
> index 38bfeebd88..fd3303552b 100755
> --- a/t/check-non-portable-shell.pl
> +++ b/t/check-non-portable-shell.pl
> @@ -46,7 +46,7 @@ sub err {
>  	/(?:\$\(seq|^\s*seq\b)/ and err 'seq is not portable (use test_seq)';
>  	/\bgrep\b.*--file\b/ and err 'grep --file FILE is not portable (use grep -f FILE)';
>  	/\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)';
> -	/^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
> +	/^\s*([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and

Thanks for a quick fix.

It is kind-of surprising that there was only one existing offender.

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

* Re: [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too
  2019-12-26 19:57       ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Jonathan Nieder
  2019-12-26 20:08         ` Junio C Hamano
@ 2019-12-26 20:18         ` Junio C Hamano
  2019-12-26 22:37           ` Jonathan Nieder
  2019-12-26 23:12           ` [PATCH jn/test-lint-one-shot-export-to-shell-function] fetch test: mark test of "skipping" haves as v0-only Jonathan Nieder
  2019-12-26 20:39         ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Eric Sunshine
  2 siblings, 2 replies; 17+ messages in thread
From: Junio C Hamano @ 2019-12-26 20:18 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: git, Jonathan Tan, Jeff King, Jeff Hostetler, Eric Sunshine

Jonathan Nieder <jrnieder@gmail.com> writes:

> Just like assigning a nonempty value, assigning an empty value to a
> shell variable when calling a function produces non-portable behavior:
> in some shells, the assignment lasts for the duration of the function
> invocation, and in others, it persists after the function returns.
>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
> ---
> If it would be useful for me to send a copy of the "Enable protocol v2
> by default" series rebased on top of this, let me know.

When rebased, t5552 passes (including the test lint) at the "request
v0 explicitly for some tests" step now.

The tip of "promote proto v2 to default" series fails at 5552.5
with or without these two patches, though.

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

* Re: [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too
  2019-12-26 19:57       ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Jonathan Nieder
  2019-12-26 20:08         ` Junio C Hamano
  2019-12-26 20:18         ` Junio C Hamano
@ 2019-12-26 20:39         ` Eric Sunshine
  2 siblings, 0 replies; 17+ messages in thread
From: Eric Sunshine @ 2019-12-26 20:39 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Junio C Hamano, Git List, Jonathan Tan, Jeff King, Jeff Hostetler

On Thu, Dec 26, 2019 at 2:57 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
> Just like assigning a nonempty value, assigning an empty value to a
> shell variable when calling a function produces non-portable behavior:
> in some shells, the assignment lasts for the duration of the function
> invocation, and in others, it persists after the function returns.
>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
> ---
> diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
> @@ -46,7 +46,7 @@ sub err {
> -       /^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
> +       /^\s*([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and
>                 err '"FOO=bar shell_func" assignment extends beyond "shell_func"';

Thanks, the change makes sense. I suspect that I simply overlooked
this case when implementing this.

Acked-by: me

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

* Re: [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too
  2019-12-26 20:18         ` Junio C Hamano
@ 2019-12-26 22:37           ` Jonathan Nieder
  2019-12-26 23:12           ` [PATCH jn/test-lint-one-shot-export-to-shell-function] fetch test: mark test of "skipping" haves as v0-only Jonathan Nieder
  1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-26 22:37 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Jonathan Tan, Jeff King, Jeff Hostetler, Eric Sunshine

Junio C Hamano wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:

>> Just like assigning a nonempty value, assigning an empty value to a
>> shell variable when calling a function produces non-portable behavior:
>> in some shells, the assignment lasts for the duration of the function
>> invocation, and in others, it persists after the function returns.
>>
>> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
>> ---
>> If it would be useful for me to send a copy of the "Enable protocol v2
>> by default" series rebased on top of this, let me know.
>
> When rebased, t5552 passes (including the test lint) at the "request
> v0 explicitly for some tests" step now.
>
> The tip of "promote proto v2 to default" series fails at 5552.5
> with or without these two patches, though.

Oh, subtle.  With shells that leak variable assignments after a
function returns (such as bash when run as 'sh'), 5552.5 was running
with GIT_TEST_PROTOCOL_VERSION=0, masking the issue.

In protocol v2, there is no "stateful" mode: negotiation always uses
the stateless-rpc path, and the stateless-rpc path involves more care
to avoid chatter during negotiation (since request size increases with
each round).

This is why b1.c14 and b1.c9 don't show up in the v2 trace.  Processing
the trace with "git name-rev --stdin" yields

 packet:        fetch> want 184bd23dc533e1e63153e7e181411bd29acca918
 packet:        fetch> have f65fc9b4d5c1cb76494a7f8df0230d8d29a33e67 (tags/b8.c19)
 packet:        fetch> have 334d40a157dec5d93023976c30cd22b24bdc279a (tags/b7.c19)
[...]
 packet:        fetch> have e3496f08debed7528bd7e4c4a12b71d1a99d697f (tags/b1.c19)
 packet:        fetch> have e7bb01cb25bebd0341c9d62f4c7e929a99b6ed4b (tags/b8.c17)
 packet:        fetch> have 7f5656e94770d527d4f909fd5e2ea274ec63177a (tags/b7.c17)
[...]
 packet:        fetch> have 17639a004fe8511fe1de57dd9ddabf2ee0de902d (tags/b1.c17)
 packet:        fetch> 0000
 packet:        fetch< acknowledgments
 packet:        fetch< ACK e3496f08debed7528bd7e4c4a12b71d1a99d697f (tags/b1.c19)
 packet:        fetch< ACK 17639a004fe8511fe1de57dd9ddabf2ee0de902d (tags/b1.c17)

By comparison, with protocol v0 over stateful bidirectional
transports, there's an additional round-trip folded in:

 packet:        fetch> have f65fc9b4d5c1cb76494a7f8df0230d8d29a33e67 (tags/b8.c19)
 packet:        fetch> have 334d40a157dec5d93023976c30cd22b24bdc279a (tags/b7.c19)
[...]
 packet:        fetch> have e3496f08debed7528bd7e4c4a12b71d1a99d697f (tags/b1.c19)
 packet:        fetch> have e7bb01cb25bebd0341c9d62f4c7e929a99b6ed4b (tags/b8.c17)
 packet:        fetch> have 7f5656e94770d527d4f909fd5e2ea274ec63177a (tags/b7.c17)
[...]
 packet:        fetch> have 17639a004fe8511fe1de57dd9ddabf2ee0de902d (tags/b1.c17)
 packet:        fetch> 0000
 packet:        fetch> have a1d75daa2f482f89171f092778da506803e54531 (tags/b8.c14)
 packet:        fetch> have b2e9b68d2650b77283421888be8a950c18bab29d (tags/b7.c14)
[...]
 packet:        fetch> have b89f6499d7cee40ef422edb15433a10f82de0206 (tags/b1.c14)
 packet:        fetch> have e4190b433240834c895347214d29426a094f2fe2 (tags/b8.c9)
 packet:        fetch> have 5f1aa7f016defcf74e5e1d4991342987c9d4b447 (tags/b7.c9)
[...]
 packet:        fetch> have b76868e654ce45adb9e06f638e48a72556843361 (tags/b1.c9)
 packet:        fetch> 0000
 packet:        fetch< ACK e3496f08debed7528bd7e4c4a12b71d1a99d697f (tags/b1.c19) common
 packet:        fetch< ACK 17639a004fe8511fe1de57dd9ddabf2ee0de902d (tags/b1.c17) common

Patch coming in a moment to force v0 here with a comment.

Thanks,
Jonathan

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

* [PATCH jn/test-lint-one-shot-export-to-shell-function] fetch test: mark test of "skipping" haves as v0-only
  2019-12-26 20:18         ` Junio C Hamano
  2019-12-26 22:37           ` Jonathan Nieder
@ 2019-12-26 23:12           ` Jonathan Nieder
  1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Nieder @ 2019-12-26 23:12 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Jonathan Tan, Jeff King, Jeff Hostetler, Eric Sunshine

Since 633a53179e (fetch test: avoid use of "VAR= cmd" with a shell
function, 2019-12-26), t5552.5 (do not send "have" with ancestors of
commits that server ACKed) fails when run with
GIT_TEST_PROTOCOL_VERSION=2.

The cause:

The progression of "have"s sent in negotiation depends on whether we
are using a stateless RPC based transport or a stateful bidirectional
one (see for example 44d8dc54e7, "Fix potential local deadlock during
fetch-pack", 2011-03-29).  In protocol v2, all transports are
stateless transports, while in protocol v0, transports such as local
access and ssh are stateful.

In stateful transports, the number of "have"s to send multiplies by
two each round until we reach PIPESAFE_FLUSH (that is, 32), and then
it increases by PIPESAFE_FLUSH each round.  In stateless transport,
the count multiplies by two each round until we reach LARGE_FLUSH
(which is 16384) and then multiplies by 1.1 each round after that.

Moreover, in stateful transports, as fetch-pack.c explains:

	We keep one window "ahead" of the other side, and will wait
	for an ACK only on the next one.

This affects t5552.5 because it looks for "have"s from the negotiator
that appear in that second window.  With protocol version 2, the
second window never arrives, and the test fails.

Until 633a53179e (2019-12-26), a previous test in the same file
contained

	GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch

In many common shells (e.g. bash when run as "sh"), the setting of
GIT_TEST_PROTOCOL_VERSION to the empty string lasts beyond the
intended duration of the trace_fetch invocation.  This causes it to
override the GIT_TEST_PROTOCOL_VERSION setting that was passed in to
the test during the remainder of the test script, so t5552.5 never got
run using protocol v2 on those shells, regardless of the
GIT_TEST_PROTOCOL_VERSION setting from the environment.  633a53179e
fixed that, revealing the failing test.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Junio C Hamano wrote:

> The tip of "promote proto v2 to default" series fails at 5552.5
> with or without these two patches, though.

Here's the promised fix, against
jn/test-lint-one-shot-export-to-shell-function.  Thanks again.

 t/t5552-skipping-fetch-negotiator.sh | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh
index a452fe32fa..8f25f4b31f 100755
--- a/t/t5552-skipping-fetch-negotiator.sh
+++ b/t/t5552-skipping-fetch-negotiator.sh
@@ -173,7 +173,17 @@ test_expect_success 'do not send "have" with ancestors of commits that server AC
 	test_commit -C server commit-on-b1 &&
 
 	test_config -C client fetch.negotiationalgorithm skipping &&
-	trace_fetch client "$(pwd)/server" to_fetch &&
+
+	# NEEDSWORK: The number of "have"s sent depends on whether the transport
+	# is stateful. If the overspecification of the result were reduced, this
+	# test could be used for both stateful and stateless transports.
+	(
+		# Force protocol v0, in which local transport is stateful (in
+		# protocol v2 it is stateless).
+		GIT_TEST_PROTOCOL_VERSION=0 &&
+		export GIT_TEST_PROTOCOL_VERSION &&
+		trace_fetch client "$(pwd)/server" to_fetch
+	) &&
 	grep "  fetch" trace &&
 
 	# fetch-pack sends 2 requests each containing 16 "have" lines before
-- 
2.24.1.735.g03f4e72817


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

end of thread, other threads:[~2019-12-26 23:12 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-24  0:58 [PATCH 0/5] Enable protocol v2 by default Jonathan Nieder
2019-12-24  0:59 ` [PATCH 1/5] fetch test: use more robust test for filtered objects Jonathan Nieder
2019-12-26 14:29   ` Derrick Stolee
2019-12-24  1:00 ` [PATCH 2/5] config doc: protocol.version is not experimental Jonathan Nieder
2019-12-24  1:01 ` [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate Jonathan Nieder
2019-12-26 19:26   ` Junio C Hamano
2019-12-26 19:53     ` [PATCH 0/2] avoid use of "VAR= cmd" with a shell function (Re: [PATCH 3/5] test: request GIT_TEST_PROTOCOL_VERSION=0 when appropriate) Jonathan Nieder
2019-12-26 19:55       ` [PATCH 1/2] fetch test: avoid use of "VAR= cmd" with a shell function Jonathan Nieder
2019-12-26 19:57       ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Jonathan Nieder
2019-12-26 20:08         ` Junio C Hamano
2019-12-26 20:18         ` Junio C Hamano
2019-12-26 22:37           ` Jonathan Nieder
2019-12-26 23:12           ` [PATCH jn/test-lint-one-shot-export-to-shell-function] fetch test: mark test of "skipping" haves as v0-only Jonathan Nieder
2019-12-26 20:39         ` [PATCH 2/2] t/check-non-portable-shell: detect "FOO= shell_func", too Eric Sunshine
2019-12-24  1:02 ` [PATCH 4/5] protocol test: let protocol.version override GIT_TEST_PROTOCOL_VERSION Jonathan Nieder
2019-12-24  1:04 ` [PATCH 5/5] fetch: default to protocol version 2 Jonathan Nieder
2019-12-26 14:30 ` [PATCH 0/5] Enable protocol v2 by default Derrick Stolee

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).