From fb20d4b1268d97646ae24f07661892cf6da64c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Mon, 21 Jun 2021 17:03:37 +0200 Subject: pack-objects tests: cover blindspots in stdin handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cover blindspots in the testing of stdin handling, including the "!len" condition added in b5d97e6b0a0 (pack-objects: run rev-list equivalent internally., 2006-09-04). The codepath taken with --revs and read_object_list_from_stdin() acts differently in some of these common cases, let's test for those. The "--stdin --revs" test being added here stresses the combination of --stdin-packs and the revision.c --stdin argument, some of this was covered in a test added in 339bce27f4f (builtin/pack-objects.c: add '--stdin-packs' option, 2021-02-22), but let's make sure that GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true keeps erroring out about --stdin, and it isn't picked up by the revision.c API's handling of that option. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- t/t5300-pack-object.sh | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 't') diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 5c5e53f0be..65e991e370 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -34,6 +34,91 @@ test_expect_success 'setup' ' } >expect ' +test_expect_success 'setup pack-object in <<-EOF && + $(git -C pack-object-stdin rev-parse one) + EOF + + git -C pack-object-stdin pack-objects basic-stdin actual && + test_line_count = 1 actual && + + git -C pack-object-stdin pack-objects --revs basic-stdin-revs actual && + test_line_count = 3 actual +' + +test_expect_success 'pack-object in <<-EOF && + $(git -C pack-object-stdin rev-parse one) + garbage + $(git -C pack-object-stdin rev-parse two) + EOF + + sed "s/^> //g" >err.expect <<-EOF && + fatal: expected object ID, got garbage: + > garbage + + EOF + test_must_fail git -C pack-object-stdin pack-objects bad-line-stdin err.actual && + test_cmp err.expect err.actual && + + cat >err.expect <<-EOF && + fatal: bad revision '"'"'garbage'"'"' + EOF + test_must_fail git -C pack-object-stdin pack-objects --revs bad-line-stdin-revs err.actual && + test_cmp err.expect err.actual +' + +test_expect_success 'pack-object in <<-EOF && + $(git -C pack-object-stdin rev-parse one) + + $(git -C pack-object-stdin rev-parse two) + EOF + + sed -e "s/^> //g" -e "s/Z$//g" >err.expect <<-EOF && + fatal: expected object ID, got garbage: + > Z + + EOF + test_must_fail git -C pack-object-stdin pack-objects empty-line-stdin err.actual && + test_cmp err.expect err.actual && + + git -C pack-object-stdin pack-objects --revs empty-line-stdin-revs actual && + test_line_count = 3 actual +' + +test_expect_success 'pack-object in <<-EOF && + $(git -C pack-object-stdin rev-parse one) + $(git -C pack-object-stdin rev-parse two) + EOF + + # There is the "--stdin-packs is incompatible with --revs" + # test below, but we should make sure that the revision.c + # --stdin is not picked up + cat >err.expect <<-EOF && + fatal: disallowed abbreviated or ambiguous option '"'"'stdin'"'"' + EOF + test_must_fail git -C pack-object-stdin pack-objects stdin-with-stdin-option --stdin err.actual && + test_cmp err.expect err.actual && + + test_must_fail git -C pack-object-stdin pack-objects --stdin --revs stdin-with-stdin-option-revs 2>err.actual # e.g.: check_deltas stderr -gt 0 check_deltas() { -- cgit v1.2.3 From 561fa03529202a36e0d77548fdcb5d81422c1865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 9 Jul 2021 12:13:48 +0200 Subject: pack-objects: fix segfault in --stdin-packs option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a segfault in the --stdin-packs option added in 339bce27f4f (builtin/pack-objects.c: add '--stdin-packs' option, 2021-02-22). The read_packs_list_from_stdin() function didn't check that the lines it was reading were valid packs, and thus when doing the QSORT() with pack_mtime_cmp() we'd have a NULL "util" field. The "util" field is used to associate the names of included/excluded packs with the packed_git structs they correspond to. The logic error was in assuming that we could iterate all packs and annotate the excluded and included packs we got, as opposed to checking the lines we got on stdin. There was a check for excluded packs, but included packs were simply assumed to be valid. As noted in the test we'll not report the first bad line, but whatever line sorted first according to the string-list.c API. In this case I think that's fine. There was further discussion of alternate approaches in [1]. Even though we're being lazy let's assert the line we do expect to get in the test, since whoever changes this code in the future might miss this case, and would want to update the test and comments. 1. http://lore.kernel.org/git/YND3h2l10PlnSNGJ@nand.local Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- t/t5300-pack-object.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 't') diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 65e991e370..e13a884207 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -119,6 +119,25 @@ test_expect_success 'pack-object in <<-EOF && + $(git -C pack-object-stdin rev-parse one) + $(git -C pack-object-stdin rev-parse two) + EOF + + # That we get "two" and not "one" has to do with OID + # ordering. It happens to be the same here under SHA-1 and + # SHA-256. See commentary in pack-objects.c + cat >err.expect <<-EOF && + fatal: could not find pack '"'"'$(git -C pack-object-stdin rev-parse two)'"'"' + EOF + test_must_fail git \ + -C pack-object-stdin \ + pack-objects stdin-with-stdin-option --stdin-packs \ + err.actual && + test_cmp err.expect err.actual +' + # usage: check_deltas # e.g.: check_deltas stderr -gt 0 check_deltas() { -- cgit v1.2.3 From 74fab8ff54e6e6a30efa254b8b5322764d119386 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Thu, 15 Jul 2021 10:44:30 -0700 Subject: send-pack: fix push.negotiate with remote helper Commit 477673d6f3 ("send-pack: support push negotiation", 2021-05-05) introduced the push.negotiate config variable and included a test. The test only covered pushing without a remote helper, so the fact that pushing with a remote helper doesn't work went unnoticed. This is ultimately caused by the "url" field not being set in the args struct. This field being unset probably went unnoticed because besides push negotiation, this field is only used to generate a "pushee" line in a push cert (and if not given, no such line is generated). Therefore, set this field. Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- t/t5549-fetch-push-http.sh | 71 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100755 t/t5549-fetch-push-http.sh (limited to 't') diff --git a/t/t5549-fetch-push-http.sh b/t/t5549-fetch-push-http.sh new file mode 100755 index 0000000000..f50d584881 --- /dev/null +++ b/t/t5549-fetch-push-http.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +test_description='fetch/push functionality using the HTTP protocol' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" +URI="$HTTPD_URL/smart/server" + +grep_wrote () { + object_count=$1 + file_name=$2 + grep 'write_pack_file/wrote.*"value":"'$1'"' $2 +} + +setup_client_and_server () { + git init client && + test_when_finished 'rm -rf client' && + test_commit -C client first_commit && + test_commit -C client second_commit && + + git init "$SERVER" && + test_when_finished 'rm -rf "$SERVER"' && + test_config -C "$SERVER" http.receivepack true && + git -C client push "$URI" first_commit:refs/remotes/origin/first_commit && + git -C "$SERVER" config receive.hideRefs refs/remotes/origin/first_commit +} + +test_expect_success 'push without negotiation (for comparing object counts with the next test)' ' + setup_client_and_server && + + GIT_TRACE2_EVENT="$(pwd)/event" git -C client -c protocol.version=2 \ + push "$URI" refs/heads/main:refs/remotes/origin/main && + test_when_finished "rm -f event" && + grep_wrote 6 event # 2 commits, 2 trees, 2 blobs +' + +test_expect_success 'push with negotiation' ' + setup_client_and_server && + + GIT_TRACE2_EVENT="$(pwd)/event" git -C client -c protocol.version=2 -c push.negotiate=1 \ + push "$URI" refs/heads/main:refs/remotes/origin/main && + test_when_finished "rm -f event" && + grep_wrote 3 event # 1 commit, 1 tree, 1 blob +' + +test_expect_success 'push with negotiation proceeds anyway even if negotiation fails' ' + setup_client_and_server && + + # Use protocol v0 to make negotiation fail (because protocol v0 does + # not support the "wait-for-done" capability, which is required for + # push negotiation) + GIT_TEST_PROTOCOL_VERSION=0 GIT_TRACE2_EVENT="$(pwd)/event" git -C client -c push.negotiate=1 \ + push "$URI" refs/heads/main:refs/remotes/origin/main 2>err && + test_when_finished "rm -f event" && + grep_wrote 6 event && # 2 commits, 2 trees, 2 blobs + + cat >warning-expect <<-EOF && + warning: --negotiate-only requires protocol v2 + warning: push negotiation failed; proceeding anyway with push +EOF + grep warning: err >warning-actual && + test_cmp warning-expect warning-actual +' + +test_done -- cgit v1.2.3 From 54a03bc7d9a7f264d511d88166afe8da7f75e90a Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Thu, 15 Jul 2021 10:44:31 -0700 Subject: send-pack: fix push nego. when remote has refs Commit 477673d6f3 ("send-pack: support push negotiation", 2021-05-05) did not test the case in which a remote advertises at least one ref. In such a case, "remote_refs" in get_commons_through_negotiation() in send-pack.c would also contain those refs with a zero ref->new_oid (in addition to the refs being pushed with a nonzero ref->new_oid). Passing them as negotiation tips to "git fetch" causes an error, so filter them out. (The exact error that would happen in "git fetch" in this case is a segmentation fault, which is unwanted. This will be fixed in the subsequent commit.) Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- t/t5516-fetch-push.sh | 4 +++- t/t5549-fetch-push-http.sh | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 0916f76302..4db8edd9c8 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -201,6 +201,7 @@ test_expect_success 'push with negotiation' ' # Without negotiation mk_empty testrepo && git push testrepo $the_first_commit:refs/remotes/origin/first_commit && + test_commit -C testrepo unrelated_commit && git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit && echo now pushing without negotiation && GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 push testrepo refs/heads/main:refs/remotes/origin/main && @@ -210,6 +211,7 @@ test_expect_success 'push with negotiation' ' rm event && mk_empty testrepo && git push testrepo $the_first_commit:refs/remotes/origin/first_commit && + test_commit -C testrepo unrelated_commit && git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit && GIT_TRACE2_EVENT="$(pwd)/event" git -c protocol.version=2 -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main && grep_wrote 2 event # 1 commit, 1 tree @@ -219,6 +221,7 @@ test_expect_success 'push with negotiation proceeds anyway even if negotiation f rm event && mk_empty testrepo && git push testrepo $the_first_commit:refs/remotes/origin/first_commit && + test_commit -C testrepo unrelated_commit && git -C testrepo config receive.hideRefs refs/remotes/origin/first_commit && GIT_TEST_PROTOCOL_VERSION=0 GIT_TRACE2_EVENT="$(pwd)/event" \ git -c push.negotiate=1 push testrepo refs/heads/main:refs/remotes/origin/main 2>err && @@ -1767,5 +1770,4 @@ test_expect_success 'denyCurrentBranch and worktrees' ' git -C cloned push origin HEAD:new-wt && test_must_fail git -C cloned push --delete origin new-wt ' - test_done diff --git a/t/t5549-fetch-push-http.sh b/t/t5549-fetch-push-http.sh index f50d584881..2cdebcb735 100755 --- a/t/t5549-fetch-push-http.sh +++ b/t/t5549-fetch-push-http.sh @@ -27,6 +27,7 @@ setup_client_and_server () { git init "$SERVER" && test_when_finished 'rm -rf "$SERVER"' && test_config -C "$SERVER" http.receivepack true && + test_commit -C "$SERVER" unrelated_commit && git -C client push "$URI" first_commit:refs/remotes/origin/first_commit && git -C "$SERVER" config receive.hideRefs refs/remotes/origin/first_commit } -- cgit v1.2.3 From 82823118b9cd397d6b626cc86a0e555069ea8253 Mon Sep 17 00:00:00 2001 From: Jonathan Tan Date: Thu, 15 Jul 2021 10:44:32 -0700 Subject: fetch: die on invalid --negotiation-tip hash If a full hexadecimal hash is given as a --negotiation-tip to "git fetch", and that hash does not correspond to an object, "git fetch" will segfault if --negotiate-only is given and will silently ignore that hash otherwise. Make these cases fatal errors, just like the case when an invalid ref name or abbreviated hash is given. While at it, mark the error messages as translatable. Signed-off-by: Jonathan Tan Signed-off-by: Junio C Hamano --- t/t5510-fetch.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 't') diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index e83b2a6506..a0faf0dd94 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -1214,6 +1214,19 @@ test_expect_success '--negotiation-tip understands abbreviated SHA-1' ' check_negotiation_tip ' +test_expect_success '--negotiation-tip rejects missing OIDs' ' + setup_negotiation_tip server server 0 && + test_must_fail git -C client fetch \ + --negotiation-tip=alpha_1 \ + --negotiation-tip=$(test_oid zero) \ + origin alpha_s beta_s 2>err && + cat >fatal-expect <<-EOF && + fatal: the object $(test_oid zero) does not exist +EOF + grep fatal: err >fatal-actual && + test_cmp fatal-expect fatal-actual +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd -- cgit v1.2.3 From be19c5ca3e28cb16d55623de2e5aa1d45bd5b5ba Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Wed, 21 Jul 2021 01:42:17 +0000 Subject: t7601: test interaction of merge/rebase/fast-forward flags and options The interaction of rebase and merge flags and options was not well tested. Add several tests to check for correct behavior from the following rules: * --ff-only vs. --[no-]rebase (and the related pull.ff=only vs. pull.rebase) * --rebase[=!false] vs. --no-ff and --ff (and the related pull.rebase=!false overrides pull.ff=!only) * command line flags take precedence over config, except: * --no-rebase heeds pull.ff=!only * pull.rebase=!false vs --no-ff and --ff For more details behind these rules and a larger table of individual cases, refer to https://lore.kernel.org/git/xmqqwnpqot4m.fsf@gitster.g/ and the links found therein. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t7601-merge-pull-config.sh | 182 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) (limited to 't') diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 52e8ccc933..a44e6e69f2 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -143,6 +143,188 @@ test_expect_success 'pull.rebase not set and --ff-only given (not-fast-forward)' test_i18ngrep ! "Pulling without specifying how to reconcile" err ' +test_does_rebase () { + git reset --hard c2 && + git "$@" . c1 && + # Check that we actually did a rebase + git rev-list --count HEAD >actual && + git rev-list --merges --count HEAD >>actual && + test_write_lines 3 0 >expect && + test_cmp expect actual && + rm actual expect +} + +# Prefers merge over fast-forward +test_does_merge_when_ff_possible () { + git reset --hard c0 && + git "$@" . c1 && + # Check that we actually did a merge + git rev-list --count HEAD >actual && + git rev-list --merges --count HEAD >>actual && + test_write_lines 3 1 >expect && + test_cmp expect actual && + rm actual expect +} + +# Prefers fast-forward over merge or rebase +test_does_fast_forward () { + git reset --hard c0 && + git "$@" . c1 && + + # Check that we did not get any merges + git rev-list --count HEAD >actual && + git rev-list --merges --count HEAD >>actual && + test_write_lines 2 0 >expect && + test_cmp expect actual && + + # Check that we ended up at c1 + git rev-parse HEAD >actual && + git rev-parse c1^{commit} >expect && + test_cmp actual expect && + + # Remove temporary files + rm actual expect +} + +# Doesn't fail when fast-forward not possible; does a merge +test_falls_back_to_full_merge () { + git reset --hard c2 && + git "$@" . c1 && + # Check that we actually did a merge + git rev-list --count HEAD >actual && + git rev-list --merges --count HEAD >>actual && + test_write_lines 4 1 >expect && + test_cmp expect actual && + rm actual expect +} + +# Attempts fast forward, which is impossible, and bails +test_attempts_fast_forward () { + git reset --hard c2 && + test_must_fail git "$@" . c1 2>err && + test_i18ngrep "Not possible to fast-forward, aborting" err +} + +# +# Group 1: Interaction of --ff-only with --[no-]rebase +# (And related interaction of pull.ff=only with pull.rebase) +# +test_expect_failure '--ff-only overrides --rebase' ' + test_attempts_fast_forward pull --rebase --ff-only +' + +test_expect_failure '--ff-only overrides --rebase even if first' ' + test_attempts_fast_forward pull --ff-only --rebase +' + +test_expect_success '--ff-only overrides --no-rebase' ' + test_attempts_fast_forward pull --ff-only --no-rebase +' + +test_expect_failure 'pull.ff=only overrides pull.rebase=true' ' + test_attempts_fast_forward -c pull.ff=only -c pull.rebase=true pull +' + +test_expect_success 'pull.ff=only overrides pull.rebase=false' ' + test_attempts_fast_forward -c pull.ff=only -c pull.rebase=false pull +' + +# Group 2: --rebase=[!false] overrides --no-ff and --ff +# (And related interaction of pull.rebase=!false and pull.ff=!only) +test_expect_success '--rebase overrides --no-ff' ' + test_does_rebase pull --rebase --no-ff +' + +test_expect_success '--rebase overrides --ff' ' + test_does_rebase pull --rebase --ff +' + +test_expect_success '--rebase fast-forwards when possible' ' + test_does_fast_forward pull --rebase --ff +' + +test_expect_success 'pull.rebase=true overrides pull.ff=false' ' + test_does_rebase -c pull.rebase=true -c pull.ff=false pull +' + +test_expect_success 'pull.rebase=true overrides pull.ff=true' ' + test_does_rebase -c pull.rebase=true -c pull.ff=true pull +' + +# Group 3: command line flags take precedence over config +test_expect_failure '--ff-only takes precedence over pull.rebase=true' ' + test_attempts_fast_forward -c pull.rebase=true pull --ff-only +' + +test_expect_success '--ff-only takes precedence over pull.rebase=false' ' + test_attempts_fast_forward -c pull.rebase=false pull --ff-only +' + +test_expect_failure '--no-rebase takes precedence over pull.ff=only' ' + test_falls_back_to_full_merge -c pull.ff=only pull --no-rebase +' + +test_expect_success '--rebase takes precedence over pull.ff=only' ' + test_does_rebase -c pull.ff=only pull --rebase +' + +test_expect_success '--rebase overrides pull.ff=true' ' + test_does_rebase -c pull.ff=true pull --rebase +' + +test_expect_success '--rebase overrides pull.ff=false' ' + test_does_rebase -c pull.ff=false pull --rebase +' + +test_expect_success '--rebase overrides pull.ff unset' ' + test_does_rebase pull --rebase +' + +# Group 4: --no-rebase heeds pull.ff=!only or explict --ff or --no-ff + +test_expect_success '--no-rebase works with --no-ff' ' + test_does_merge_when_ff_possible pull --no-rebase --no-ff +' + +test_expect_success '--no-rebase works with --ff' ' + test_does_fast_forward pull --no-rebase --ff +' + +test_expect_success '--no-rebase does ff if pull.ff unset' ' + test_does_fast_forward pull --no-rebase +' + +test_expect_success '--no-rebase heeds pull.ff=true' ' + test_does_fast_forward -c pull.ff=true pull --no-rebase +' + +test_expect_success '--no-rebase heeds pull.ff=false' ' + test_does_merge_when_ff_possible -c pull.ff=false pull --no-rebase +' + +# Group 5: pull.rebase=!false in combination with --no-ff or --ff +test_expect_success 'pull.rebase=true and --no-ff' ' + test_does_rebase -c pull.rebase=true pull --no-ff +' + +test_expect_success 'pull.rebase=true and --ff' ' + test_does_rebase -c pull.rebase=true pull --ff +' + +test_expect_success 'pull.rebase=false and --no-ff' ' + test_does_merge_when_ff_possible -c pull.rebase=false pull --no-ff +' + +test_expect_success 'pull.rebase=false and --ff, ff possible' ' + test_does_fast_forward -c pull.rebase=false pull --ff +' + +test_expect_success 'pull.rebase=false and --ff, ff not possible' ' + test_falls_back_to_full_merge -c pull.rebase=false pull --ff +' + +# End of groupings for conflicting merge vs. rebase flags/options + test_expect_success 'merge c1 with c2' ' git reset --hard c1 && test -f c0.c && -- cgit v1.2.3 From 1d25e5bdf5263a227d233eafcf028b36c72716f6 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Wed, 21 Jul 2021 01:42:18 +0000 Subject: t7601: add tests of interactions with multiple merge heads and config There were already code checking that --rebase was incompatible with a merge of multiple heads. However, we were sometimes throwing warnings about lack of specification of rebase vs. merge when given multiple heads. Since rebasing is disallowed with multiple merge heads, that seems like a poor warning to print; we should instead just assume merging is wanted. Add a few tests checking multiple merge head behavior. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t7601-merge-pull-config.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 't') diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index a44e6e69f2..21db1e9e14 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -325,6 +325,28 @@ test_expect_success 'pull.rebase=false and --ff, ff not possible' ' # End of groupings for conflicting merge vs. rebase flags/options +test_expect_failure 'Multiple heads warns about inability to fast forward' ' + git reset --hard c1 && + test_must_fail git pull . c2 c3 2>err && + test_i18ngrep "Pulling without specifying how to reconcile" err +' + +test_expect_failure 'Multiple can never be fast forwarded' ' + git reset --hard c0 && + test_must_fail git -c pull.ff=only pull . c1 c2 c3 2>err && + test_i18ngrep ! "Pulling without specifying how to reconcile" err && + # In addition to calling out "cannot fast-forward", we very much + # want the "multiple branches" piece to be called out to users. + test_i18ngrep "Cannot fast-forward to multiple branches" err +' + +test_expect_success 'Cannot rebase with multiple heads' ' + git reset --hard c0 && + test_must_fail git -c pull.rebase=true pull . c1 c2 c3 2>err && + test_i18ngrep ! "Pulling without specifying how to reconcile" err && + test_i18ngrep "Cannot rebase onto multiple branches." err +' + test_expect_success 'merge c1 with c2' ' git reset --hard c1 && test -f c0.c && -- cgit v1.2.3 From 3d5fc24daefbdf56bc36a491aed0b7990fa0c62f Mon Sep 17 00:00:00 2001 From: Alex Henrie Date: Wed, 21 Jul 2021 01:42:19 +0000 Subject: pull: abort if --ff-only is given and fast-forwarding is impossible The warning about pulling without specifying how to reconcile divergent branches says that after setting pull.rebase to true, --ff-only can still be passed on the command line to require a fast-forward. Make that actually work. Signed-off-by: Alex Henrie [en: updated tests; note 3 fixes and 1 new failure] Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t7601-merge-pull-config.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 't') diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 21db1e9e14..d1f621725a 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -209,11 +209,11 @@ test_attempts_fast_forward () { # Group 1: Interaction of --ff-only with --[no-]rebase # (And related interaction of pull.ff=only with pull.rebase) # -test_expect_failure '--ff-only overrides --rebase' ' +test_expect_success '--ff-only overrides --rebase' ' test_attempts_fast_forward pull --rebase --ff-only ' -test_expect_failure '--ff-only overrides --rebase even if first' ' +test_expect_success '--ff-only overrides --rebase even if first' ' test_attempts_fast_forward pull --ff-only --rebase ' @@ -221,7 +221,7 @@ test_expect_success '--ff-only overrides --no-rebase' ' test_attempts_fast_forward pull --ff-only --no-rebase ' -test_expect_failure 'pull.ff=only overrides pull.rebase=true' ' +test_expect_success 'pull.ff=only overrides pull.rebase=true' ' test_attempts_fast_forward -c pull.ff=only -c pull.rebase=true pull ' @@ -252,7 +252,7 @@ test_expect_success 'pull.rebase=true overrides pull.ff=true' ' ' # Group 3: command line flags take precedence over config -test_expect_failure '--ff-only takes precedence over pull.rebase=true' ' +test_expect_success '--ff-only takes precedence over pull.rebase=true' ' test_attempts_fast_forward -c pull.rebase=true pull --ff-only ' @@ -264,7 +264,7 @@ test_expect_failure '--no-rebase takes precedence over pull.ff=only' ' test_falls_back_to_full_merge -c pull.ff=only pull --no-rebase ' -test_expect_success '--rebase takes precedence over pull.ff=only' ' +test_expect_failure '--rebase takes precedence over pull.ff=only' ' test_does_rebase -c pull.ff=only pull --rebase ' -- cgit v1.2.3 From 866a3014de34d415300bdd488f2ccd7ae5fb2d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Thu, 22 Jul 2021 00:57:40 +0200 Subject: test-lib tests: move "run_sub_test" to a new lib-subtest.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the "check_sub_test_lib_test()" and its sister functions to a new lib-subtest.sh. In the future (not in this series) I'd like to test test-lib's output in a more targeted and smaller test, and I'll need these functions to do that. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- t/lib-subtest.sh | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ t/t0000-basic.sh | 88 +------------------------------------------------------- 2 files changed, 87 insertions(+), 87 deletions(-) create mode 100644 t/lib-subtest.sh (limited to 't') diff --git a/t/lib-subtest.sh b/t/lib-subtest.sh new file mode 100644 index 0000000000..3cfe09911a --- /dev/null +++ b/t/lib-subtest.sh @@ -0,0 +1,86 @@ +_run_sub_test_lib_test_common () { + neg="$1" name="$2" descr="$3" # stdin is the body of the test code + shift 3 + + # intercept pseudo-options at the front of the argument list that we + # will not pass to child script + skip= + while test $# -gt 0 + do + case "$1" in + --skip=*) + skip=${1#--*=} + shift + ;; + *) + break + ;; + esac + done + + mkdir "$name" && + ( + # Pretend we're not running under a test harness, whether we + # are or not. The test-lib output depends on the setting of + # this variable, so we need a stable setting under which to run + # the sub-test. + sane_unset HARNESS_ACTIVE && + cd "$name" && + write_script "$name.sh" "$TEST_SHELL_PATH" <<-EOF && + test_description='$descr (run in sub test-lib) + + This is run in a sub test-lib so that we do not get incorrect + passing metrics + ' + + # Point to the t/test-lib.sh, which isn't in ../ as usual + . "\$TEST_DIRECTORY"/test-lib.sh + EOF + cat >>"$name.sh" && + export TEST_DIRECTORY && + # The child test re-sources GIT-BUILD-OPTIONS and may thus + # override the test output directory. We thus pass it as an + # explicit override to the child. + TEST_OUTPUT_DIRECTORY_OVERRIDE=$(pwd) && + export TEST_OUTPUT_DIRECTORY_OVERRIDE && + GIT_SKIP_TESTS=$skip && + export GIT_SKIP_TESTS && + sane_unset GIT_TEST_FAIL_PREREQS && + if test -z "$neg" + then + ./"$name.sh" "$@" >out 2>err + else + ! ./"$name.sh" "$@" >out 2>err + fi + ) +} + +run_sub_test_lib_test () { + _run_sub_test_lib_test_common '' "$@" +} + +run_sub_test_lib_test_err () { + _run_sub_test_lib_test_common '!' "$@" +} + +check_sub_test_lib_test () { + name="$1" # stdin is the expected output from the test + ( + cd "$name" && + test_must_be_empty err && + sed -e 's/^> //' -e 's/Z$//' >expect && + test_cmp expect out + ) +} + +check_sub_test_lib_test_err () { + name="$1" # stdin is the expected output from the test + # expected error output is in descriptor 3 + ( + cd "$name" && + sed -e 's/^> //' -e 's/Z$//' >expect.out && + test_cmp expect.out out && + sed -e 's/^> //' -e 's/Z$//' <&3 >expect.err && + test_cmp expect.err err + ) +} diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index cb87768513..a3865dd77b 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -19,6 +19,7 @@ modification *should* take notice and update the test vectors here. ' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-subtest.sh try_local_xy () { local x="local" y="alsolocal" && @@ -66,93 +67,6 @@ test_expect_success 'success is reported like this' ' : ' -_run_sub_test_lib_test_common () { - neg="$1" name="$2" descr="$3" # stdin is the body of the test code - shift 3 - - # intercept pseudo-options at the front of the argument list that we - # will not pass to child script - skip= - while test $# -gt 0 - do - case "$1" in - --skip=*) - skip=${1#--*=} - shift - ;; - *) - break - ;; - esac - done - - mkdir "$name" && - ( - # Pretend we're not running under a test harness, whether we - # are or not. The test-lib output depends on the setting of - # this variable, so we need a stable setting under which to run - # the sub-test. - sane_unset HARNESS_ACTIVE && - cd "$name" && - write_script "$name.sh" "$TEST_SHELL_PATH" <<-EOF && - test_description='$descr (run in sub test-lib) - - This is run in a sub test-lib so that we do not get incorrect - passing metrics - ' - - # Point to the t/test-lib.sh, which isn't in ../ as usual - . "\$TEST_DIRECTORY"/test-lib.sh - EOF - cat >>"$name.sh" && - export TEST_DIRECTORY && - # The child test re-sources GIT-BUILD-OPTIONS and may thus - # override the test output directory. We thus pass it as an - # explicit override to the child. - TEST_OUTPUT_DIRECTORY_OVERRIDE=$(pwd) && - export TEST_OUTPUT_DIRECTORY_OVERRIDE && - GIT_SKIP_TESTS=$skip && - export GIT_SKIP_TESTS && - sane_unset GIT_TEST_FAIL_PREREQS && - if test -z "$neg" - then - ./"$name.sh" "$@" >out 2>err - else - ! ./"$name.sh" "$@" >out 2>err - fi - ) -} - -run_sub_test_lib_test () { - _run_sub_test_lib_test_common '' "$@" -} - -run_sub_test_lib_test_err () { - _run_sub_test_lib_test_common '!' "$@" -} - -check_sub_test_lib_test () { - name="$1" # stdin is the expected output from the test - ( - cd "$name" && - test_must_be_empty err && - sed -e 's/^> //' -e 's/Z$//' >expect && - test_cmp expect out - ) -} - -check_sub_test_lib_test_err () { - name="$1" # stdin is the expected output from the test - # expected error output is in descriptor 3 - ( - cd "$name" && - sed -e 's/^> //' -e 's/Z$//' >expect.out && - test_cmp expect.out out && - sed -e 's/^> //' -e 's/Z$//' <&3 >expect.err && - test_cmp expect.err err - ) -} - test_expect_success 'pretend we have a fully passing test suite' ' run_sub_test_lib_test full-pass "3 passing tests" <<-\EOF && for i in 1 2 3 -- cgit v1.2.3 From adc27d6a9374d012b091bc348c20f5bfdbee52d1 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 22 Jul 2021 05:04:47 +0000 Subject: pull: make --rebase and --no-rebase override pull.ff=only Fix the last few precedence tests failing in t7601 by now implementing the logic to have --[no-]rebase override a pull.ff=only config setting. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t7601-merge-pull-config.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index d1f621725a..0c0dfecd2a 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -260,11 +260,11 @@ test_expect_success '--ff-only takes precedence over pull.rebase=false' ' test_attempts_fast_forward -c pull.rebase=false pull --ff-only ' -test_expect_failure '--no-rebase takes precedence over pull.ff=only' ' +test_expect_success '--no-rebase takes precedence over pull.ff=only' ' test_falls_back_to_full_merge -c pull.ff=only pull --no-rebase ' -test_expect_failure '--rebase takes precedence over pull.ff=only' ' +test_expect_success '--rebase takes precedence over pull.ff=only' ' test_does_rebase -c pull.ff=only pull --rebase ' -- cgit v1.2.3 From 031e2f7ae195069d00d21cde906fce5b0318dbdd Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 22 Jul 2021 05:04:48 +0000 Subject: pull: abort by default when fast-forwarding is not possible We have for some time shown a long warning when the user does not specify how to reconcile divergent branches with git pull. Make it an error now. Initial-patch-by: Alex Henrie Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t4013-diff-various.sh | 2 +- t/t5520-pull.sh | 20 +++++++++--------- t/t5521-pull-options.sh | 4 ++-- t/t5524-pull-msg.sh | 4 ++-- t/t5553-set-upstream.sh | 14 ++++++------- t/t5604-clone-reference.sh | 4 ++-- t/t6402-merge-rename.sh | 18 ++++++++-------- t/t6409-merge-subtree.sh | 6 +++--- t/t6417-merge-ours-theirs.sh | 10 ++++----- t/t7601-merge-pull-config.sh | 48 +++++++++++++++++++++---------------------- t/t7603-merge-reduce-heads.sh | 2 +- 11 files changed, 66 insertions(+), 66 deletions(-) (limited to 't') diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 7fadc985cc..eb989f7f19 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -65,7 +65,7 @@ test_expect_success setup ' export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && git checkout master && - git pull -s ours . side && + git pull -s ours --no-rebase . side && GIT_AUTHOR_DATE="2006-06-26 00:05:00 +0000" && GIT_COMMITTER_DATE="2006-06-26 00:05:00 +0000" && diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index e2c0c51022..672001a18b 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -136,12 +136,12 @@ test_expect_success 'the default remote . should not break explicit pull' ' git reset --hard HEAD^ && echo file >expect && test_cmp expect file && - git pull . second && + git pull --no-rebase . second && echo modified >expect && test_cmp expect file && git reflog -1 >reflog.actual && sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && - echo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected && + echo "OBJID HEAD@{0}: pull --no-rebase . second: Fast-forward" >reflog.expected && test_cmp reflog.expected reflog.fuzzy ' @@ -226,7 +226,7 @@ test_expect_success 'fail if the index has unresolved entries' ' test_commit modified2 file && git ls-files -u >unmerged && test_must_be_empty unmerged && - test_must_fail git pull . second && + test_must_fail git pull --no-rebase . second && git ls-files -u >unmerged && test_file_not_empty unmerged && cp file expected && @@ -409,37 +409,37 @@ test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' ' test_expect_success 'pull succeeds with dirty working directory and merge.autostash set' ' test_config merge.autostash true && - test_pull_autostash 2 + test_pull_autostash 2 --no-rebase ' test_expect_success 'pull --autostash & merge.autostash=true' ' test_config merge.autostash true && - test_pull_autostash 2 --autostash + test_pull_autostash 2 --autostash --no-rebase ' test_expect_success 'pull --autostash & merge.autostash=false' ' test_config merge.autostash false && - test_pull_autostash 2 --autostash + test_pull_autostash 2 --autostash --no-rebase ' test_expect_success 'pull --autostash & merge.autostash unset' ' test_unconfig merge.autostash && - test_pull_autostash 2 --autostash + test_pull_autostash 2 --autostash --no-rebase ' test_expect_success 'pull --no-autostash & merge.autostash=true' ' test_config merge.autostash true && - test_pull_autostash_fail --no-autostash + test_pull_autostash_fail --no-autostash --no-rebase ' test_expect_success 'pull --no-autostash & merge.autostash=false' ' test_config merge.autostash false && - test_pull_autostash_fail --no-autostash + test_pull_autostash_fail --no-autostash --no-rebase ' test_expect_success 'pull --no-autostash & merge.autostash unset' ' test_unconfig merge.autostash && - test_pull_autostash_fail --no-autostash + test_pull_autostash_fail --no-autostash --no-rebase ' test_expect_success 'pull.rebase' ' diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 63a688bdbf..7601c919fd 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -113,7 +113,7 @@ test_expect_success 'git pull --force' ' git pull two && test_commit A && git branch -f origin && - git pull --all --force + git pull --no-rebase --all --force ) ' @@ -179,7 +179,7 @@ test_expect_success 'git pull --allow-unrelated-histories' ' ( cd dst && test_must_fail git pull ../src side && - git pull --allow-unrelated-histories ../src side + git pull --no-rebase --allow-unrelated-histories ../src side ) ' diff --git a/t/t5524-pull-msg.sh b/t/t5524-pull-msg.sh index c278adaa5a..b2be3605f5 100755 --- a/t/t5524-pull-msg.sh +++ b/t/t5524-pull-msg.sh @@ -28,7 +28,7 @@ test_expect_success setup ' test_expect_success pull ' ( cd cloned && - git pull --log && + git pull --no-rebase --log && git log -2 && git cat-file commit HEAD >result && grep Dollar result @@ -41,7 +41,7 @@ test_expect_success '--log=1 limits shortlog length' ' git reset --hard HEAD^ && test "$(cat afile)" = original && test "$(cat bfile)" = added && - git pull --log=1 && + git pull --no-rebase --log=1 && git log -3 && git cat-file commit HEAD >result && grep Dollar result && diff --git a/t/t5553-set-upstream.sh b/t/t5553-set-upstream.sh index b1d614ce18..9c12c0f8c3 100755 --- a/t/t5553-set-upstream.sh +++ b/t/t5553-set-upstream.sh @@ -108,27 +108,27 @@ test_expect_success 'setup commit on main and other pull' ' test_expect_success 'pull --set-upstream upstream main sets branch main but not other' ' clear_config main other && - git pull --set-upstream upstream main && + git pull --no-rebase --set-upstream upstream main && check_config main upstream refs/heads/main && check_config_missing other ' test_expect_success 'pull --set-upstream main:other2 does not set the branch other2' ' clear_config other2 && - git pull --set-upstream upstream main:other2 && + git pull --no-rebase --set-upstream upstream main:other2 && check_config_missing other2 ' test_expect_success 'pull --set-upstream upstream other sets branch main' ' clear_config main other && - git pull --set-upstream upstream other && + git pull --no-rebase --set-upstream upstream other && check_config main upstream refs/heads/other && check_config_missing other ' test_expect_success 'pull --set-upstream upstream tag does not set the tag' ' clear_config three && - git pull --tags --set-upstream upstream three && + git pull --no-rebase --tags --set-upstream upstream three && check_config_missing three ' @@ -144,16 +144,16 @@ test_expect_success 'pull --set-upstream http://nosuchdomain.example.com fails w test_expect_success 'pull --set-upstream upstream HEAD sets branch HEAD' ' clear_config main other && - git pull --set-upstream upstream HEAD && + git pull --no-rebase --set-upstream upstream HEAD && check_config main upstream HEAD && git checkout other && - git pull --set-upstream upstream HEAD && + git pull --no-rebase --set-upstream upstream HEAD && check_config other upstream HEAD ' test_expect_success 'pull --set-upstream upstream with more than one branch does nothing' ' clear_config main three && - git pull --set-upstream upstream main three && + git pull --no-rebase --set-upstream upstream main three && check_config_missing main && check_config_missing three ' diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index e845d621f6..24340e6d56 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -87,7 +87,7 @@ test_expect_success 'updating origin' ' ' test_expect_success 'pulling changes from origin' ' - git -C C pull origin + git -C C pull --no-rebase origin ' # the 2 local objects are commit and tree from the merge @@ -96,7 +96,7 @@ test_expect_success 'that alternate to origin gets used' ' ' test_expect_success 'pulling changes from origin' ' - git -C D pull origin + git -C D pull --no-rebase origin ' # the 5 local objects are expected; file3 blob, commit in A to add it diff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh index 425dad97d5..02a842697b 100755 --- a/t/t6402-merge-rename.sh +++ b/t/t6402-merge-rename.sh @@ -103,7 +103,7 @@ test_expect_success 'setup' ' test_expect_success 'pull renaming branch into unrenaming one' \ ' git show-branch && - test_expect_code 1 git pull . white && + test_expect_code 1 git pull --no-rebase . white && git ls-files -s && git ls-files -u B >b.stages && test_line_count = 3 b.stages && @@ -121,7 +121,7 @@ test_expect_success 'pull renaming branch into another renaming one' \ rm -f B && git reset --hard && git checkout red && - test_expect_code 1 git pull . white && + test_expect_code 1 git pull --no-rebase . white && git ls-files -u B >b.stages && test_line_count = 3 b.stages && git ls-files -s N >n.stages && @@ -137,7 +137,7 @@ test_expect_success 'pull unrenaming branch into renaming one' \ ' git reset --hard && git show-branch && - test_expect_code 1 git pull . main && + test_expect_code 1 git pull --no-rebase . main && git ls-files -u B >b.stages && test_line_count = 3 b.stages && git ls-files -s N >n.stages && @@ -153,7 +153,7 @@ test_expect_success 'pull conflicting renames' \ ' git reset --hard && git show-branch && - test_expect_code 1 git pull . blue && + test_expect_code 1 git pull --no-rebase . blue && git ls-files -u A >a.stages && test_line_count = 1 a.stages && git ls-files -u B >b.stages && @@ -173,7 +173,7 @@ test_expect_success 'interference with untracked working tree file' ' git reset --hard && git show-branch && echo >A this file should not matter && - test_expect_code 1 git pull . white && + test_expect_code 1 git pull --no-rebase . white && test_path_is_file A ' @@ -183,7 +183,7 @@ test_expect_success 'interference with untracked working tree file' ' git show-branch && rm -f A && echo >A this file should not matter && - test_expect_code 1 git pull . red && + test_expect_code 1 git pull --no-rebase . red && test_path_is_file A ' @@ -193,7 +193,7 @@ test_expect_success 'interference with untracked working tree file' ' git checkout -f main && git tag -f anchor && git show-branch && - git pull . yellow && + git pull --no-rebase . yellow && test_path_is_missing M && git reset --hard anchor ' @@ -220,7 +220,7 @@ test_expect_success 'updated working tree file should prevent the merge' ' echo >>M one line addition && cat M >M.saved && git update-index M && - test_expect_code 128 git pull . yellow && + test_expect_code 128 git pull --no-rebase . yellow && test_cmp M M.saved && rm -f M.saved ' @@ -232,7 +232,7 @@ test_expect_success 'interference with untracked working tree file' ' git tag -f anchor && git show-branch && echo >M this file should not matter && - git pull . main && + git pull --no-rebase . main && test_path_is_file M && ! { git ls-files -s | diff --git a/t/t6409-merge-subtree.sh b/t/t6409-merge-subtree.sh index d406b2343c..ba7890ec52 100755 --- a/t/t6409-merge-subtree.sh +++ b/t/t6409-merge-subtree.sh @@ -100,7 +100,7 @@ test_expect_success 'merge update' ' git checkout -b topic_2 && git commit -m "update git-gui" && cd ../git && - git pull -s subtree gui topic_2 && + git pull --no-rebase -s subtree gui topic_2 && git ls-files -s >actual && ( echo "100644 $o3 0 git-gui/git-gui.sh" && @@ -129,7 +129,7 @@ test_expect_success 'initial ambiguous subtree' ' test_expect_success 'merge using explicit' ' cd ../git && git reset --hard topic_2 && - git pull -Xsubtree=git-gui gui topic_2 && + git pull --no-rebase -Xsubtree=git-gui gui topic_2 && git ls-files -s >actual && ( echo "100644 $o3 0 git-gui/git-gui.sh" && @@ -142,7 +142,7 @@ test_expect_success 'merge using explicit' ' test_expect_success 'merge2 using explicit' ' cd ../git && git reset --hard topic_2 && - git pull -Xsubtree=git-gui2 gui topic_2 && + git pull --no-rebase -Xsubtree=git-gui2 gui topic_2 && git ls-files -s >actual && ( echo "100644 $o1 0 git-gui/git-gui.sh" && diff --git a/t/t6417-merge-ours-theirs.sh b/t/t6417-merge-ours-theirs.sh index ac9aee9a66..ec065d6a65 100755 --- a/t/t6417-merge-ours-theirs.sh +++ b/t/t6417-merge-ours-theirs.sh @@ -69,11 +69,11 @@ test_expect_success 'binary file with -Xours/-Xtheirs' ' ' test_expect_success 'pull passes -X to underlying merge' ' - git reset --hard main && git pull -s recursive -Xours . side && - git reset --hard main && git pull -s recursive -X ours . side && - git reset --hard main && git pull -s recursive -Xtheirs . side && - git reset --hard main && git pull -s recursive -X theirs . side && - git reset --hard main && test_must_fail git pull -s recursive -X bork . side + git reset --hard main && git pull --no-rebase -s recursive -Xours . side && + git reset --hard main && git pull --no-rebase -s recursive -X ours . side && + git reset --hard main && git pull --no-rebase -s recursive -Xtheirs . side && + git reset --hard main && git pull --no-rebase -s recursive -X theirs . side && + git reset --hard main && test_must_fail git pull --no-rebase -s recursive -X bork . side ' test_expect_success SYMLINKS 'symlink with -Xours/-Xtheirs' ' diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 0c0dfecd2a..742ed3981c 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -27,120 +27,120 @@ test_expect_success 'setup' ' git tag c3 ' -test_expect_success 'pull.rebase not set' ' +test_expect_success 'pull.rebase not set, ff possible' ' git reset --hard c0 && git pull . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set (not-fast-forward)' ' git reset --hard c2 && - git -c color.advice=always pull . c1 2>err && + test_must_fail git -c color.advice=always pull . c1 2>err && test_decode_color decoded && test_i18ngrep "hint: " decoded && - test_i18ngrep "Pulling without specifying how to reconcile" decoded + test_i18ngrep "You have divergent branches" decoded ' 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" 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 + test_i18ngrep ! "You have divergent branches" err ' test_does_rebase () { @@ -325,16 +325,16 @@ test_expect_success 'pull.rebase=false and --ff, ff not possible' ' # End of groupings for conflicting merge vs. rebase flags/options -test_expect_failure 'Multiple heads warns about inability to fast forward' ' +test_expect_success 'Multiple heads warns about inability to fast forward' ' git reset --hard c1 && test_must_fail git pull . c2 c3 2>err && - test_i18ngrep "Pulling without specifying how to reconcile" err + test_i18ngrep "You have divergent branches" err ' test_expect_failure 'Multiple can never be fast forwarded' ' git reset --hard c0 && test_must_fail git -c pull.ff=only pull . c1 c2 c3 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err && + test_i18ngrep ! "You have divergent branches" err && # In addition to calling out "cannot fast-forward", we very much # want the "multiple branches" piece to be called out to users. test_i18ngrep "Cannot fast-forward to multiple branches" err @@ -343,7 +343,7 @@ test_expect_failure 'Multiple can never be fast forwarded' ' test_expect_success 'Cannot rebase with multiple heads' ' git reset --hard c0 && test_must_fail git -c pull.rebase=true pull . c1 c2 c3 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err && + test_i18ngrep ! "You have divergent branches" err && test_i18ngrep "Cannot rebase onto multiple branches." err ' diff --git a/t/t7603-merge-reduce-heads.sh b/t/t7603-merge-reduce-heads.sh index 98948955ae..27cd94ad6f 100755 --- a/t/t7603-merge-reduce-heads.sh +++ b/t/t7603-merge-reduce-heads.sh @@ -68,7 +68,7 @@ test_expect_success 'merge c1 with c2, c3, c4, c5' ' test_expect_success 'pull c2, c3, c4, c5 into c1' ' git reset --hard c1 && - git pull . c2 c3 c4 c5 && + git pull --no-rebase . c2 c3 c4 c5 && test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" && test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" && -- cgit v1.2.3 From 6f843a3355ee590dfe09eb90679051e75fadf675 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 22 Jul 2021 05:04:50 +0000 Subject: pull: fix handling of multiple heads With multiple heads, we should not allow rebasing or fast-forwarding. Make sure any fast-forward request calls out specifically the fact that multiple branches are in play. Also, since we cannot fast-forward to multiple branches, fix our computation of can_ff. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t7601-merge-pull-config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 742ed3981c..1f652f433e 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -331,7 +331,7 @@ test_expect_success 'Multiple heads warns about inability to fast forward' ' test_i18ngrep "You have divergent branches" err ' -test_expect_failure 'Multiple can never be fast forwarded' ' +test_expect_success 'Multiple can never be fast forwarded' ' git reset --hard c0 && test_must_fail git -c pull.ff=only pull . c1 c2 c3 2>err && test_i18ngrep ! "You have divergent branches" err && -- cgit v1.2.3 From 2f732bf15e6dc9c2caf210784f180c6c059c570a Mon Sep 17 00:00:00 2001 From: Emily Shaffer Date: Wed, 21 Jul 2021 18:27:07 -0700 Subject: tr2: log parent process name It can be useful to tell who invoked Git - was it invoked manually by a user via CLI or script? By an IDE? In some cases - like 'repo' tool - we can influence the source code and set the GIT_TRACE2_PARENT_SID environment variable from the caller process. In 'repo''s case, that parent SID is manipulated to include the string "repo", which means we can positively identify when Git was invoked by 'repo' tool. However, identifying parents that way requires both that we know which tools invoke Git and that we have the ability to modify the source code of those tools. It cannot scale to keep up with the various IDEs and wrappers which use Git, most of which we don't know about. Learning which tools and wrappers invoke Git, and how, would give us insight to decide where to improve Git's usability and performance. Unfortunately, there's no cross-platform reliable way to gather the name of the parent process. If procfs is present, we can use that; otherwise we will need to discover the name another way. However, the process ID should be sufficient to look up the process name on most platforms, so that code may be shareable. Git for Windows gathers similar information and logs it as a "data_json" event. However, since "data_json" has a variable format, it is difficult to parse effectively in some languages; instead, let's pursue a dedicated "cmd_ancestry" event to record information about the ancestry of the current process and a consistent, parseable way. Git for Windows also gathers information about more than one generation of parent. In Linux further ancestry info can be gathered with procfs, but it's unwieldy to do so. In the interest of later moving Git for Windows ancestry logging to the 'cmd_ancestry' event, and in the interest of later adding more ancestry to the Linux implementation - or of adding this functionality to other platforms which have an easier time walking the process tree - let's make 'cmd_ancestry' accept an array of parentage. Signed-off-by: Emily Shaffer Signed-off-by: Junio C Hamano --- t/t0210/scrub_normal.perl | 6 ++++++ t/t0211/scrub_perf.perl | 5 +++++ t/t0212/parse_events.perl | 5 ++++- 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t0210/scrub_normal.perl b/t/t0210/scrub_normal.perl index c65d1a815e..7cc4de392a 100644 --- a/t/t0210/scrub_normal.perl +++ b/t/t0210/scrub_normal.perl @@ -42,6 +42,12 @@ while (<>) { # so just omit it for testing purposes. # print "cmd_path _EXE_\n"; } + elsif ($line =~ m/^cmd_ancestry/) { + # 'cmd_ancestry' is not implemented everywhere, so for portability's + # sake, skip it when parsing normal. + # + # print "$line"; + } else { print "$line"; } diff --git a/t/t0211/scrub_perf.perl b/t/t0211/scrub_perf.perl index 351af7844e..d164b750ff 100644 --- a/t/t0211/scrub_perf.perl +++ b/t/t0211/scrub_perf.perl @@ -44,6 +44,11 @@ while (<>) { # $tokens[$col_rest] = "_EXE_"; goto SKIP_LINE; } + elsif ($tokens[$col_event] =~ m/cmd_ancestry/) { + # 'cmd_ancestry' is platform-specific and not implemented everywhere, + # so skip it. + goto SKIP_LINE; + } elsif ($tokens[$col_event] =~ m/child_exit/) { $tokens[$col_rest] =~ s/ pid:\d* / pid:_PID_ /; } diff --git a/t/t0212/parse_events.perl b/t/t0212/parse_events.perl index 6584bb5634..b6408560c0 100644 --- a/t/t0212/parse_events.perl +++ b/t/t0212/parse_events.perl @@ -132,7 +132,10 @@ while (<>) { # just omit it for testing purposes. # $processes->{$sid}->{'path'} = "_EXE_"; } - + elsif ($event eq 'cmd_ancestry') { + # 'cmd_ancestry' is platform-specific and not implemented everywhere, so + # just skip it for testing purposes. + } elsif ($event eq 'cmd_name') { $processes->{$sid}->{'name'} = $line->{'name'}; $processes->{$sid}->{'hierarchy'} = $line->{'hierarchy'}; -- cgit v1.2.3 From bd0708c7eb8be43242180a1ea2a0f0acda7a4fbc Mon Sep 17 00:00:00 2001 From: ZheNing Hu Date: Mon, 26 Jul 2021 03:26:47 +0000 Subject: ref-filter: add %(raw) atom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new formatting option `%(raw)`, which will print the raw object data without any changes. It will help further to migrate all cat-file formatting logic from cat-file to ref-filter. The raw data of blob, tree objects may contain '\0', but most of the logic in `ref-filter` depends on the output of the atom being text (specifically, no embedded NULs in it). E.g. `quote_formatting()` use `strbuf_addstr()` or `*._quote_buf()` add the data to the buffer. The raw data of a tree object is `100644 one\0...`, only the `100644 one` will be added to the buffer, which is incorrect. Therefore, we need to find a way to record the length of the atom_value's member `s`. Although strbuf can already record the string and its length, if we want to replace the type of atom_value's member `s` with strbuf, many places in ref-filter that are filled with dynamically allocated mermory in `v->s` are not easy to replace. At the same time, we need to check if `v->s == NULL` in populate_value(), and strbuf cannot easily distinguish NULL and empty strings, but c-style "const char *" can do it. So add a new member in `struct atom_value`: `s_size`, which can record raw object size, it can help us add raw object data to the buffer or compare two buffers which contain raw object data. Note that `--format=%(raw)` cannot be used with `--python`, `--shell`, `--tcl`, and `--perl` because if the binary raw data is passed to a variable in such languages, these may not support arbitrary binary data in their string variable type. Reviewed-by: Jacob Keller Mentored-by: Christian Couder Mentored-by: Hariom Verma Helped-by: Bagas Sanjaya Helped-by: Ævar Arnfjörð Bjarmason Helped-by: Felipe Contreras Helped-by: Phillip Wood Helped-by: Junio C Hamano Based-on-patch-by: Olga Telezhnaya Signed-off-by: ZheNing Hu Signed-off-by: Junio C Hamano --- t/t6300-for-each-ref.sh | 216 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) (limited to 't') diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 9e0214076b..18554f62d9 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -130,6 +130,8 @@ test_atom head parent:short=10 '' test_atom head numparent 0 test_atom head object '' test_atom head type '' +test_atom head raw "$(git cat-file commit refs/heads/main) +" test_atom head '*objectname' '' test_atom head '*objecttype' '' test_atom head author 'A U Thor 1151968724 +0200' @@ -221,6 +223,15 @@ test_atom tag contents 'Tagging at 1151968727 ' test_atom tag HEAD ' ' +test_expect_success 'basic atom: refs/tags/testtag *raw' ' + git cat-file commit refs/tags/testtag^{} >expected && + git for-each-ref --format="%(*raw)" refs/tags/testtag >actual && + sanitize_pgp expected.clean && + echo >>expected.clean && + sanitize_pgp actual.clean && + test_cmp expected.clean actual.clean +' + test_expect_success 'Check invalid atoms names are errors' ' test_must_fail git for-each-ref --format="%(INVALID)" refs/heads ' @@ -686,6 +697,15 @@ test_atom refs/tags/signed-empty contents:body '' test_atom refs/tags/signed-empty contents:signature "$sig" test_atom refs/tags/signed-empty contents "$sig" +test_expect_success GPG 'basic atom: refs/tags/signed-empty raw' ' + git cat-file tag refs/tags/signed-empty >expected && + git for-each-ref --format="%(raw)" refs/tags/signed-empty >actual && + sanitize_pgp expected.clean && + echo >>expected.clean && + sanitize_pgp actual.clean && + test_cmp expected.clean actual.clean +' + test_atom refs/tags/signed-short subject 'subject line' test_atom refs/tags/signed-short subject:sanitize 'subject-line' test_atom refs/tags/signed-short contents:subject 'subject line' @@ -695,6 +715,15 @@ test_atom refs/tags/signed-short contents:signature "$sig" test_atom refs/tags/signed-short contents "subject line $sig" +test_expect_success GPG 'basic atom: refs/tags/signed-short raw' ' + git cat-file tag refs/tags/signed-short >expected && + git for-each-ref --format="%(raw)" refs/tags/signed-short >actual && + sanitize_pgp expected.clean && + echo >>expected.clean && + sanitize_pgp actual.clean && + test_cmp expected.clean actual.clean +' + test_atom refs/tags/signed-long subject 'subject line' test_atom refs/tags/signed-long subject:sanitize 'subject-line' test_atom refs/tags/signed-long contents:subject 'subject line' @@ -708,6 +737,15 @@ test_atom refs/tags/signed-long contents "subject line body contents $sig" +test_expect_success GPG 'basic atom: refs/tags/signed-long raw' ' + git cat-file tag refs/tags/signed-long >expected && + git for-each-ref --format="%(raw)" refs/tags/signed-long >actual && + sanitize_pgp expected.clean && + echo >>expected.clean && + sanitize_pgp actual.clean && + test_cmp expected.clean actual.clean +' + test_expect_success 'set up refs pointing to tree and blob' ' git update-ref refs/mytrees/first refs/heads/main^{tree} && git update-ref refs/myblobs/first refs/heads/main:one @@ -720,6 +758,16 @@ test_atom refs/mytrees/first contents:body "" test_atom refs/mytrees/first contents:signature "" test_atom refs/mytrees/first contents "" +test_expect_success 'basic atom: refs/mytrees/first raw' ' + git cat-file tree refs/mytrees/first >expected && + echo >>expected && + git for-each-ref --format="%(raw)" refs/mytrees/first >actual && + test_cmp expected actual && + git cat-file -s refs/mytrees/first >expected && + git for-each-ref --format="%(raw:size)" refs/mytrees/first >actual && + test_cmp expected actual +' + test_atom refs/myblobs/first subject "" test_atom refs/myblobs/first contents:subject "" test_atom refs/myblobs/first body "" @@ -727,6 +775,174 @@ test_atom refs/myblobs/first contents:body "" test_atom refs/myblobs/first contents:signature "" test_atom refs/myblobs/first contents "" +test_expect_success 'basic atom: refs/myblobs/first raw' ' + git cat-file blob refs/myblobs/first >expected && + echo >>expected && + git for-each-ref --format="%(raw)" refs/myblobs/first >actual && + test_cmp expected actual && + git cat-file -s refs/myblobs/first >expected && + git for-each-ref --format="%(raw:size)" refs/myblobs/first >actual && + test_cmp expected actual +' + +test_expect_success 'set up refs pointing to binary blob' ' + printf "a\0b\0c" >blob1 && + printf "a\0c\0b" >blob2 && + printf "\0a\0b\0c" >blob3 && + printf "abc" >blob4 && + printf "\0 \0 \0 " >blob5 && + printf "\0 \0a\0 " >blob6 && + printf " " >blob7 && + >blob8 && + obj=$(git hash-object -w blob1) && + git update-ref refs/myblobs/blob1 "$obj" && + obj=$(git hash-object -w blob2) && + git update-ref refs/myblobs/blob2 "$obj" && + obj=$(git hash-object -w blob3) && + git update-ref refs/myblobs/blob3 "$obj" && + obj=$(git hash-object -w blob4) && + git update-ref refs/myblobs/blob4 "$obj" && + obj=$(git hash-object -w blob5) && + git update-ref refs/myblobs/blob5 "$obj" && + obj=$(git hash-object -w blob6) && + git update-ref refs/myblobs/blob6 "$obj" && + obj=$(git hash-object -w blob7) && + git update-ref refs/myblobs/blob7 "$obj" && + obj=$(git hash-object -w blob8) && + git update-ref refs/myblobs/blob8 "$obj" +' + +test_expect_success 'Verify sorts with raw' ' + cat >expected <<-EOF && + refs/myblobs/blob8 + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/myblobs/blob3 + refs/myblobs/blob7 + refs/mytrees/first + refs/myblobs/first + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob4 + refs/heads/main + EOF + git for-each-ref --format="%(refname)" --sort=raw \ + refs/heads/main refs/myblobs/ refs/mytrees/first >actual && + test_cmp expected actual +' + +test_expect_success 'Verify sorts with raw:size' ' + cat >expected <<-EOF && + refs/myblobs/blob8 + refs/myblobs/first + refs/myblobs/blob7 + refs/heads/main + refs/myblobs/blob4 + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob3 + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/mytrees/first + EOF + git for-each-ref --format="%(refname)" --sort=raw:size \ + refs/heads/main refs/myblobs/ refs/mytrees/first >actual && + test_cmp expected actual +' + +test_expect_success 'validate raw atom with %(if:equals)' ' + cat >expected <<-EOF && + not equals + not equals + not equals + not equals + not equals + not equals + refs/myblobs/blob4 + not equals + not equals + not equals + not equals + not equals + EOF + git for-each-ref --format="%(if:equals=abc)%(raw)%(then)%(refname)%(else)not equals%(end)" \ + refs/myblobs/ refs/heads/ >actual && + test_cmp expected actual +' + +test_expect_success 'validate raw atom with %(if:notequals)' ' + cat >expected <<-EOF && + refs/heads/ambiguous + refs/heads/main + refs/heads/newtag + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob3 + equals + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/myblobs/blob7 + refs/myblobs/blob8 + refs/myblobs/first + EOF + git for-each-ref --format="%(if:notequals=abc)%(raw)%(then)%(refname)%(else)equals%(end)" \ + refs/myblobs/ refs/heads/ >actual && + test_cmp expected actual +' + +test_expect_success 'empty raw refs with %(if)' ' + cat >expected <<-EOF && + refs/myblobs/blob1 not empty + refs/myblobs/blob2 not empty + refs/myblobs/blob3 not empty + refs/myblobs/blob4 not empty + refs/myblobs/blob5 not empty + refs/myblobs/blob6 not empty + refs/myblobs/blob7 empty + refs/myblobs/blob8 empty + refs/myblobs/first not empty + EOF + git for-each-ref --format="%(refname) %(if)%(raw)%(then)not empty%(else)empty%(end)" \ + refs/myblobs/ >actual && + test_cmp expected actual +' + +test_expect_success '%(raw) with --python must fail' ' + test_must_fail git for-each-ref --format="%(raw)" --python +' + +test_expect_success '%(raw) with --tcl must fail' ' + test_must_fail git for-each-ref --format="%(raw)" --tcl +' + +test_expect_success '%(raw) with --perl must fail' ' + test_must_fail git for-each-ref --format="%(raw)" --perl +' + +test_expect_success '%(raw) with --shell must fail' ' + test_must_fail git for-each-ref --format="%(raw)" --shell +' + +test_expect_success '%(raw) with --shell and --sort=raw must fail' ' + test_must_fail git for-each-ref --format="%(raw)" --sort=raw --shell +' + +test_expect_success '%(raw:size) with --shell' ' + git for-each-ref --format="%(raw:size)" | while read line + do + echo "'\''$line'\''" >>expect + done && + git for-each-ref --format="%(raw:size)" --shell >actual && + test_cmp expect actual +' + +test_expect_success 'for-each-ref --format compare with cat-file --batch' ' + git rev-parse refs/mytrees/first | git cat-file --batch >expected && + git for-each-ref --format="%(objectname) %(objecttype) %(objectsize) +%(raw)" refs/mytrees/first >actual && + test_cmp expected actual +' + test_expect_success 'set up multiple-sort tags' ' for when in 100000 200000 do -- cgit v1.2.3 From 7121c4d4e2877115fb372b3f147fad4cd1306751 Mon Sep 17 00:00:00 2001 From: ZheNing Hu Date: Mon, 26 Jul 2021 03:26:48 +0000 Subject: ref-filter: --format=%(raw) support --perl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because the perl language can handle binary data correctly, add the function perl_quote_buf_with_len(), which can specify the length of the data and prevent the data from being truncated at '\0' to help `--format="%(raw)"` support `--perl`. Reviewed-by: Jacob Keller Helped-by: Ævar Arnfjörð Bjarmason Signed-off-by: ZheNing Hu Signed-off-by: Junio C Hamano --- t/t6300-for-each-ref.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 18554f62d9..3d15d0a536 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -915,8 +915,23 @@ test_expect_success '%(raw) with --tcl must fail' ' test_must_fail git for-each-ref --format="%(raw)" --tcl ' -test_expect_success '%(raw) with --perl must fail' ' - test_must_fail git for-each-ref --format="%(raw)" --perl +test_expect_success '%(raw) with --perl' ' + git for-each-ref --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob1 --perl | perl >actual && + cmp blob1 actual && + git for-each-ref --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob3 --perl | perl >actual && + cmp blob3 actual && + git for-each-ref --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob8 --perl | perl >actual && + cmp blob8 actual && + git for-each-ref --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/first --perl | perl >actual && + cmp one actual && + git cat-file tree refs/mytrees/first > expected && + git for-each-ref --format="\$name= %(raw); +print \"\$name\"" refs/mytrees/first --perl | perl >actual && + cmp expected actual ' test_expect_success '%(raw) with --shell must fail' ' -- cgit v1.2.3 From b9dee075eb07713a49922f7e1f90a6a9de5c5e5f Mon Sep 17 00:00:00 2001 From: ZheNing Hu Date: Mon, 26 Jul 2021 03:26:50 +0000 Subject: ref-filter: add %(rest) atom %(rest) is a atom used for cat-file batch mode, which can split the input lines at the first whitespace boundary, all characters before that whitespace are considered to be the object name; characters after that first run of whitespace (i.e., the "rest" of the line) are output in place of the %(rest) atom. In order to let "cat-file --batch=%(rest)" use the ref-filter interface, add %(rest) atom for ref-filter. Introduce the reject_atom() to reject the atom %(rest) for "git for-each-ref", "git branch", "git tag" and "git verify-tag". Reviewed-by: Jacob Keller Suggected-by: Jacob Keller Mentored-by: Christian Couder Mentored-by: Hariom Verma Signed-off-by: ZheNing Hu Signed-off-by: Junio C Hamano --- t/t3203-branch-output.sh | 4 ++++ t/t6300-for-each-ref.sh | 4 ++++ t/t7004-tag.sh | 4 ++++ t/t7030-verify-tag.sh | 4 ++++ 4 files changed, 16 insertions(+) (limited to 't') diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index 5325b9f67a..6e94c6db7b 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -340,6 +340,10 @@ test_expect_success 'git branch --format option' ' test_cmp expect actual ' +test_expect_success 'git branch with --format=%(rest) must fail' ' + test_must_fail git branch --format="%(rest)" >actual +' + test_expect_success 'worktree colors correct' ' cat >expect <<-EOF && * (HEAD detached from fromtag) diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 3d15d0a536..0d2e062f79 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -1211,6 +1211,10 @@ test_expect_success 'basic atom: head contents:trailers' ' test_cmp expect actual.clean ' +test_expect_success 'basic atom: rest must fail' ' + test_must_fail git for-each-ref --format="%(rest)" refs/heads/main +' + test_expect_success 'trailer parsing not fooled by --- line' ' git commit --allow-empty -F - <<-\EOF && this is the subject diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 2f72c5c688..082be85dff 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1998,6 +1998,10 @@ test_expect_success '--format should list tags as per format given' ' test_cmp expect actual ' +test_expect_success 'git tag -l with --format="%(rest)" must fail' ' + test_must_fail git tag -l --format="%(rest)" "v1*" +' + test_expect_success "set up color tests" ' echo "v1.0" >expect.color && echo "v1.0" >expect.bare && diff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh index 3cefde9602..10faa64515 100755 --- a/t/t7030-verify-tag.sh +++ b/t/t7030-verify-tag.sh @@ -194,6 +194,10 @@ test_expect_success GPG 'verifying tag with --format' ' test_cmp expect actual ' +test_expect_success GPG 'verifying tag with --format="%(rest)" must fail' ' + test_must_fail git verify-tag --format="%(rest)" "fourth-signed" +' + test_expect_success GPG 'verifying a forged tag with --format should fail silently' ' test_must_fail git verify-tag --format="tagname : %(tag)" $(cat forged1.tag) >actual-forged && test_must_be_empty actual-forged -- cgit v1.2.3 From b7d11a0f5d2db1eff623150cdc2a2ddccd6845b3 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 24 Jul 2021 22:06:49 +0000 Subject: tests: exercise the RUNTIME_PREFIX feature Originally, we refrained from adding a regression test in 7b6c6496374 (system_path(): Add prefix computation at runtime if RUNTIME_PREFIX set, 2008-08-10), and in 226c0ddd0d6 (exec_cmd: RUNTIME_PREFIX on some POSIX systems, 2018-04-10). The reason was that it was deemed too tricky to test. Turns out that it is not tricky to test at all: we simply create a pseudo-root, copy the `git` executable into the `git/` subdirectory of that pseudo-root, then copy a script into the `libexec/git-core/` directory and expect that to be picked up. As long as the trash directory is in a location where binaries can be executed, this works. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t0060-path-utils.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 't') diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index de4960783f..a76728c27b 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -525,4 +525,22 @@ test_expect_success MINGW 'is_valid_path() on Windows' ' "PRN./abc" ' +test_lazy_prereq RUNTIME_PREFIX ' + test true = "$RUNTIME_PREFIX" +' + +test_lazy_prereq CAN_EXEC_IN_PWD ' + cp "$GIT_EXEC_PATH"/git$X ./ && + ./git rev-parse +' + +test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' + mkdir -p pretend/bin pretend/libexec/git-core && + echo "echo HERE" | write_script pretend/libexec/git-core/git-here && + cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && + GIT_EXEC_PATH= ./pretend/bin/git here >actual && + echo HERE >expect && + test_cmp expect actual +' + test_done -- cgit v1.2.3 From e394a16023cbb62784e380f70ad8a833fb960d68 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 24 Jul 2021 22:06:53 +0000 Subject: interpolate_path(): allow specifying paths relative to the runtime prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ever since Git learned to detect its install location at runtime, there was the slightly awkward problem that it was impossible to specify paths relative to said location. For example, if a version of Git was shipped with custom SSL certificates to use, there was no portable way to specify `http.sslCAInfo`. In Git for Windows, the problem was "solved" for years by interpreting paths starting with a slash as relative to the runtime prefix. However, this is not correct: such paths _are_ legal on Windows, and they are interpreted as absolute paths in the same drive as the current directory. After a lengthy discussion, and an even lengthier time to mull over the problem and its best solution, and then more discussions, we eventually decided to introduce support for the magic sequence `%(prefix)/`. If a path starts with this, the remainder is interpreted as relative to the detected (runtime) prefix. If built without runtime prefix support, Git will simply interpolate the compiled-in prefix. If a user _wants_ to specify a path starting with the magic sequence, they can prefix the magic sequence with `./` and voilà, the path won't be expanded. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t0060-path-utils.sh | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 't') diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index a76728c27b..34d1061f32 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -540,6 +540,14 @@ test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && GIT_EXEC_PATH= ./pretend/bin/git here >actual && echo HERE >expect && + test_cmp expect actual' + +test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' ' + mkdir -p pretend/bin && + cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && + git config yes.path "%(prefix)/yes" && + GIT_EXEC_PATH= ./pretend/bin/git config --path yes.path >actual && + echo "$(pwd)/pretend/yes" >expect && test_cmp expect actual ' -- cgit v1.2.3 From 4577d26dc0aaae3bb35c8906db96ba043716f3f7 Mon Sep 17 00:00:00 2001 From: David Turner Date: Mon, 26 Jul 2021 14:33:56 -0400 Subject: t4060: remove unused variable Signed-off-by: David Turner Signed-off-by: Junio C Hamano --- t/t4060-diff-submodule-option-diff-format.sh | 1 - 1 file changed, 1 deletion(-) (limited to 't') diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh index dc7b242697..69b9946931 100755 --- a/t/t4060-diff-submodule-option-diff-format.sh +++ b/t/t4060-diff-submodule-option-diff-format.sh @@ -361,7 +361,6 @@ test_expect_success 'typechanged submodule(submodule->blob)' ' rm -f sm1 && test_create_repo sm1 && head6=$(add_file sm1 foo6 foo7) -fullhead6=$(cd sm1; git rev-parse --verify HEAD) test_expect_success 'nonexistent commit' ' git diff-index -p --submodule=diff HEAD >actual && cat >expected <<-EOF && -- cgit v1.2.3 From 83ad8ca596dd879d2907a240fb24a1603bb1decc Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Thu, 29 Jul 2021 14:52:03 +0000 Subject: t1092: test merge conflicts outside cone Conflicts can occur outside of the sparse-checkout definition, and in that case users might try to resolve the conflicts in several ways. Document a few of these ways in a test. Make it clear that this behavior is not necessarily the optimal flow, since users can become confused when Git deletes these files from the worktree in later commands. Reviewed-by: Elijah Newren Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- t/t1092-sparse-checkout-compatibility.sh | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 't') diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 91e30d6ec2..4c3bcb3499 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -114,6 +114,16 @@ test_expect_success 'setup' ' git add . && git commit -m "file to dir" && + for side in left right + do + git checkout -b merge-$side base && + echo $side >>deep/deeper2/a && + echo $side >>folder1/a && + echo $side >>folder2/a && + git add . && + git commit -m "$side" || return 1 + done && + git checkout -b deepest base && echo "updated deepest" >deep/deeper1/deepest/a && git commit -a -m "update deepest" && @@ -482,6 +492,39 @@ test_expect_success 'merge' ' test_all_match git rev-parse HEAD^{tree} ' +# NEEDSWORK: This test is documenting current behavior, but that +# behavior can be confusing to users so there is desire to change it. +# Right now, users might be using this flow to work through conflicts, +# so any solution should present advice to users who try this sequence +# of commands to follow whatever new method we create. +test_expect_success 'merge with conflict outside cone' ' + init_repos && + + test_all_match git checkout -b merge-tip merge-left && + test_all_match git status --porcelain=v2 && + test_all_match test_must_fail git merge -m merge merge-right && + test_all_match git status --porcelain=v2 && + + # Resolve the conflict in different ways: + # 1. Revert to the base + test_all_match git checkout base -- deep/deeper2/a && + test_all_match git status --porcelain=v2 && + + # 2. Add the file with conflict markers + test_all_match git add folder1/a && + test_all_match git status --porcelain=v2 && + + # 3. Rename the file to another sparse filename and + # accept conflict markers as resolved content. + run_on_all mv folder2/a folder2/z && + test_all_match git add folder2 && + test_all_match git status --porcelain=v2 && + + test_all_match git merge --continue && + test_all_match git status --porcelain=v2 && + test_all_match git rev-parse HEAD^{tree} +' + test_expect_success 'merge with outside renames' ' init_repos && -- cgit v1.2.3 From 5e7cbab19680745d4f3e0c50903025d9f02e7468 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Thu, 29 Jul 2021 14:52:04 +0000 Subject: add: allow operating on a sparse-only index Disable command_requires_full_index for 'git add'. This does not require any additional removals of ensure_full_index(). The main reason is that 'git add' discovers changes based on the pathspec and the worktree itself. These are then inserted into the index directly, and calls to index_name_pos() or index_file_exists() already call expand_to_path() at the appropriate time to support a sparse-index. Add a test to check that 'git add -A' and 'git add ' does not expand the index at all, as long as is not within a sparse directory. This does not help the global 'git add .' case. We can measure the improvement using p2000-sparse-operations.sh with these results: Test HEAD~1 HEAD ------------------------------------------------------------------------------ 2000.6: git add -A (full-index-v3) 0.35(0.30+0.05) 0.37(0.29+0.06) +5.7% 2000.7: git add -A (full-index-v4) 0.31(0.26+0.06) 0.33(0.27+0.06) +6.5% 2000.8: git add -A (sparse-index-v3) 0.57(0.53+0.07) 0.05(0.04+0.08) -91.2% 2000.9: git add -A (sparse-index-v4) 0.58(0.55+0.06) 0.05(0.05+0.06) -91.4% While the 91% improvement seems impressive, it's important to recognize that previously we had significant overhead for expanding the sparse-index. Comparing to the full index case, 'git add -A' goes from 0.37s to 0.05s, which is "only" an 86% improvement. This modification to 'git add' creates some behavior change depending on the use of a sparse index. We modify a test in t1092 to demonstrate these changes which will be remedied in future changes. Reviewed-by: Elijah Newren Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- t/t1092-sparse-checkout-compatibility.sh | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 't') diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 4c3bcb3499..77343cb6d9 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -340,21 +340,27 @@ test_expect_success 'status/add: outside sparse cone' ' test_sparse_match git status --porcelain=v2 && - # This "git add folder1/a" fails with a warning - # in the sparse repos, differing from the full - # repo. This is intentional. + # Adding the path outside of the sparse-checkout cone should fail. test_sparse_match test_must_fail git add folder1/a && - test_sparse_match test_must_fail git add --refresh folder1/a && - test_all_match git status --porcelain=v2 && + + test_must_fail git -C sparse-checkout add --refresh folder1/a 2>sparse-checkout-err && + test_must_fail git -C sparse-index add --refresh folder1/a 2>sparse-index-err && + # NEEDSWORK: A sparse index changes the error message. + ! test_cmp sparse-checkout-err sparse-index-err && + + # NEEDSWORK: Adding a newly-tracked file outside the cone succeeds + test_sparse_match git add folder1/new && test_all_match git add . && test_all_match git status --porcelain=v2 && test_all_match git commit -m folder1/new && + test_all_match git rev-parse HEAD^{tree} && run_on_all ../edit-contents folder1/newer && test_all_match git add folder1/ && test_all_match git status --porcelain=v2 && - test_all_match git commit -m folder1/newer + test_all_match git commit -m folder1/newer && + test_all_match git rev-parse HEAD^{tree} ' test_expect_success 'checkout and reset --hard' ' @@ -641,7 +647,12 @@ test_expect_success 'sparse-index is not expanded' ' git -C sparse-index reset --hard && ensure_not_expanded checkout rename-out-to-out -- deep/deeper1 && git -C sparse-index reset --hard && - ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1 + ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1 && + + echo >>sparse-index/README.md && + ensure_not_expanded add -A && + echo >>sparse-index/extra.txt && + ensure_not_expanded add extra.txt ' # NEEDSWORK: a sparse-checkout behaves differently from a full checkout -- cgit v1.2.3 From 4eaffd81a5fbffc692f1044374a3a16689fc37a5 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Thu, 29 Jul 2021 14:52:05 +0000 Subject: pathspec: stop calling ensure_full_index The add_pathspec_matches_against_index() focuses on matching a pathspec to file entries in the index. This already works correctly for its only use: checking if untracked files exist in the index. The compatibility checks in t1092 already test that 'git add ' works for a directory outside of the sparse cone. That provides coverage for removing this guard. This finalizes our ability to run 'git add .' without expanding a sparse index to a full one. This is evidenced by an update to t1092 and by these performance numbers for p2000-sparse-operations.sh: Test HEAD~1 HEAD -------------------------------------------------------------------------------- 2000.10: git add . (full-index-v3) 0.37(0.28+0.07) 0.36(0.27+0.06) -2.7% 2000.11: git add . (full-index-v4) 0.33(0.26+0.06) 0.32(0.28+0.05) -3.0% 2000.12: git add . (sparse-index-v3) 0.57(0.53+0.07) 0.06(0.06+0.07) -89.5% 2000.13: git add . (sparse-index-v4) 0.57(0.53+0.07) 0.05(0.03+0.09) -91.2% While the ~90% improvement is shown by the test results, it is worth noting that expanding the sparse index was adding overhead in previous commits. Comparing to the full index case, we see the performance go from 0.33s to 0.05s, an 85% improvement. Reviewed-by: Elijah Newren Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- t/t1092-sparse-checkout-compatibility.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 't') diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 77343cb6d9..dee20db5bb 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -322,9 +322,6 @@ test_expect_success 'commit including unstaged changes' ' test_expect_success 'status/add: outside sparse cone' ' init_repos && - # adding a "missing" file outside the cone should fail - test_sparse_match test_must_fail git add folder1/a && - # folder1 is at HEAD, but outside the sparse cone run_on_sparse mkdir folder1 && cp initial-repo/folder1/a sparse-checkout/folder1/a && @@ -652,7 +649,9 @@ test_expect_success 'sparse-index is not expanded' ' echo >>sparse-index/README.md && ensure_not_expanded add -A && echo >>sparse-index/extra.txt && - ensure_not_expanded add extra.txt + ensure_not_expanded add extra.txt && + echo >>sparse-index/untracked.txt && + ensure_not_expanded add . ' # NEEDSWORK: a sparse-checkout behaves differently from a full checkout -- cgit v1.2.3 From 939fa07582a2c9455e71f599263e2dcbe1d655b5 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Thu, 29 Jul 2021 14:52:06 +0000 Subject: add: ignore outside the sparse-checkout in refresh() Since b243012 (refresh_index(): add flag to ignore SKIP_WORKTREE entries, 2021-04-08), 'git add --refresh ' will output a warning message when the path is outside the sparse-checkout definition. The implementation of this warning happened in parallel with the sparse-index work to add ensure_full_index() calls throughout the codebase. Update this loop to have the proper logic that checks to see if the pathspec is outside the sparse-checkout definition. This avoids the need to expand the sparse directory entry and determine if the path is tracked, untracked, or ignored. We simply avoid updating the stat() information because there isn't even an entry that matches the path! Reviewed-by: Elijah Newren Signed-off-by: Derrick Stolee Signed-off-by: Junio C Hamano --- t/t1092-sparse-checkout-compatibility.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 't') diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index dee20db5bb..ddc86bb415 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -339,11 +339,7 @@ test_expect_success 'status/add: outside sparse cone' ' # Adding the path outside of the sparse-checkout cone should fail. test_sparse_match test_must_fail git add folder1/a && - - test_must_fail git -C sparse-checkout add --refresh folder1/a 2>sparse-checkout-err && - test_must_fail git -C sparse-index add --refresh folder1/a 2>sparse-index-err && - # NEEDSWORK: A sparse index changes the error message. - ! test_cmp sparse-checkout-err sparse-index-err && + test_sparse_match test_must_fail git add --refresh folder1/a && # NEEDSWORK: Adding a newly-tracked file outside the cone succeeds test_sparse_match git add folder1/new && -- cgit v1.2.3 From e6b0a8fab8e5a29f11faef898905e0b3c700e683 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:26 +0000 Subject: t6050: use git-update-ref rather than filesystem access Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t6050-replace.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index e33d512ec1..2500acc2ef 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -132,7 +132,7 @@ tagger T A Gger <> 0 +0000 EOF test_expect_success 'tag replaced commit' ' - git mktag .git/refs/tags/mytag + git update-ref refs/tags/mytag $(git mktag Date: Mon, 2 Aug 2021 16:53:27 +0000 Subject: t1503: mark symlink test as REFFILES Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t1503-rev-parse-verify.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh index bf08102391..40958615eb 100755 --- a/t/t1503-rev-parse-verify.sh +++ b/t/t1503-rev-parse-verify.sh @@ -142,7 +142,7 @@ test_expect_success 'main@{n} for various n' ' test_must_fail git rev-parse --verify main@{$Np1} ' -test_expect_success SYMLINKS 'ref resolution not confused by broken symlinks' ' +test_expect_success SYMLINKS,REFFILES 'ref resolution not confused by broken symlinks' ' ln -s does-not-exist .git/refs/heads/broken && test_must_fail git rev-parse --verify broken ' -- cgit v1.2.3 From e46775cf9e1c6ddca0ada3c1ca24876b79a23d9a Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:28 +0000 Subject: t6120: use git-update-ref rather than filesystem access Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t6120-describe.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 1a501ee09e..bae2419150 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -107,7 +107,8 @@ test_expect_success 'describe --contains defaults to HEAD without commit-ish' ' check_describe tags/A --all A^0 test_expect_success 'renaming tag A to Q locally produces a warning' " - mv .git/refs/tags/A .git/refs/tags/Q && + git update-ref refs/tags/Q $(git rev-parse refs/tags/A) && + git update-ref -d refs/tags/A && git describe HEAD 2>err >out && cat >expected <<-\EOF && warning: tag 'Q' is externally known as 'A' @@ -135,7 +136,8 @@ test_expect_success 'abbrev=0 will not break misplaced tag (2)' ' ' test_expect_success 'rename tag Q back to A' ' - mv .git/refs/tags/Q .git/refs/tags/A + git update-ref refs/tags/A $(git rev-parse refs/tags/Q) && + git update-ref -d refs/tags/Q ' test_expect_success 'pack tag refs' 'git pack-refs' -- cgit v1.2.3 From 2f566d665ac3ef97715617aae839fa2e6f7fce93 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:29 +0000 Subject: t3320: use git-symbolic-ref rather than filesystem access Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t3320-notes-merge-worktrees.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 't') diff --git a/t/t3320-notes-merge-worktrees.sh b/t/t3320-notes-merge-worktrees.sh index 052516e6c6..6b2d507f3e 100755 --- a/t/t3320-notes-merge-worktrees.sh +++ b/t/t3320-notes-merge-worktrees.sh @@ -46,8 +46,9 @@ test_expect_success 'create some new worktrees' ' test_expect_success 'merge z into y fails and sets NOTES_MERGE_REF' ' git config core.notesRef refs/notes/y && test_must_fail git notes merge z && - echo "ref: refs/notes/y" >expect && - test_cmp expect .git/NOTES_MERGE_REF + echo "refs/notes/y" >expect && + git symbolic-ref NOTES_MERGE_REF >actual && + test_cmp expect actual ' test_expect_success 'merge z into y while mid-merge in another workdir fails' ' @@ -57,7 +58,7 @@ test_expect_success 'merge z into y while mid-merge in another workdir fails' ' test_must_fail git notes merge z 2>err && test_i18ngrep "a notes merge into refs/notes/y is already in-progress at" err ) && - test_path_is_missing .git/worktrees/worktree/NOTES_MERGE_REF + test_must_fail git -C worktree symbolic-ref NOTES_MERGE_REF ' test_expect_success 'merge z into x while mid-merge on y succeeds' ' @@ -68,8 +69,9 @@ test_expect_success 'merge z into x while mid-merge on y succeeds' ' test_i18ngrep "Automatic notes merge failed" out && grep -v "A notes merge into refs/notes/x is already in-progress in" out ) && - echo "ref: refs/notes/x" >expect && - test_cmp expect .git/worktrees/worktree2/NOTES_MERGE_REF + echo "refs/notes/x" >expect && + git -C worktree2 symbolic-ref NOTES_MERGE_REF >actual && + test_cmp expect actual ' test_done -- cgit v1.2.3 From 100ac47bf364290768001b2b438a84993a7042f6 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:30 +0000 Subject: t2402: use ref-store test helper to create broken symlink Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t2402-worktree-list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh index fedcefe8de..4012bd67b0 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -230,7 +230,7 @@ test_expect_success 'broken main worktree still at the top' ' EOF cd linked && echo "worktree $(pwd)" >expected && - echo "ref: .broken" >../.git/HEAD && + (cd ../ && test-tool ref-store main create-symref HEAD .broken ) && git worktree list --porcelain >out && head -n 3 out >actual && test_cmp ../expected actual && -- cgit v1.2.3 From ace40eab9e8ee4d087b8ba7b603db4958e8ad28c Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:31 +0000 Subject: t1405: use 'git reflog exists' to check reflog existence This fixes a test failure for reftable. Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t1405-main-ref-store.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index a237d9880e..92b0487324 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -98,12 +98,12 @@ test_expect_success 'reflog_exists(HEAD)' ' test_expect_success 'delete_reflog(HEAD)' ' $RUN delete-reflog HEAD && - ! test -f .git/logs/HEAD + test_must_fail git reflog exists HEAD ' test_expect_success 'create-reflog(HEAD)' ' $RUN create-reflog HEAD 1 && - test -f .git/logs/HEAD + git reflog exists HEAD ' test_expect_success 'delete_ref(refs/heads/foo)' ' -- cgit v1.2.3 From a50234b3be9d6ff75dfca9b0802e7cf97179ff11 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:32 +0000 Subject: t1405: mark test for 'git pack-refs' as REFFILES The tests verifies that "pack-refs" causes loose refs to be packed. As both loose and packed refs are concepts specific to the files backend, mark the test as REFFILES. Check the outcome of the pack-refs operation. This was apparently forgotten in the commit introducing this test: 16feb99d (Mar 26 2017, "t1405: some basic tests on main ref store"). Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t1405-main-ref-store.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 't') diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index 92b0487324..49718b7ea7 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -9,12 +9,18 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME RUN="test-tool ref-store main" -test_expect_success 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' ' - test_commit one && + +test_expect_success 'setup' ' + test_commit one +' + +test_expect_success REFFILES 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' ' N=`find .git/refs -type f | wc -l` && test "$N" != 0 && - $RUN pack-refs 3 && - N=`find .git/refs -type f | wc -l` + ALL_OR_PRUNE_FLAG=3 && + $RUN pack-refs ${ALL_OR_PRUNE_FLAG} && + N=`find .git/refs -type f` && + test -z "$N" ' test_expect_success 'create_symref(FOO, refs/heads/main)' ' -- cgit v1.2.3 From fe1443152689fcecbbaf0213a7bebcc23ee24a37 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:33 +0000 Subject: t1410: mark test as REFFILES This test takes a lock on the target of a symref, and then verifies that it is possible to expire the symref's reflog. In reftable, one can only take a global lock (which would prevent the symref reflog from being expired altogether.) Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t1410-reflog.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 27b9080251..d42f067ff8 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -374,7 +374,9 @@ test_expect_failure 'reflog with non-commit entries displays all entries' ' test_line_count = 3 actual ' -test_expect_success 'reflog expire operates on symref not referrent' ' +# This test takes a lock on an individual ref; this is not supported in +# reftable. +test_expect_success REFFILES 'reflog expire operates on symref not referrent' ' git branch --create-reflog the_symref && git branch --create-reflog referrent && git update-ref referrent HEAD && -- cgit v1.2.3 From 2cf9f0fca1ad0fedb88f63f59b311b4d80b28f0e Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:34 +0000 Subject: t7064: use update-ref -d to remove upstream branch The previous code tested this by writing $ZERO_OID explicitly in the packed-refs file. This is a type of corruption that doesn't reflect realistic use-cases. In addition, even the ref-store test-tool refuses to write invalid OIDs. (update-ref interprets $ZERO_OID is deleting the ref). Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t7064-wtstatus-pv2.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 't') diff --git a/t/t7064-wtstatus-pv2.sh b/t/t7064-wtstatus-pv2.sh index 4613882caf..eeb0534163 100755 --- a/t/t7064-wtstatus-pv2.sh +++ b/t/t7064-wtstatus-pv2.sh @@ -373,10 +373,7 @@ test_expect_success 'verify upstream fields in branch header' ' ## Test upstream-gone case. Fake this by pointing ## origin/initial-branch at a non-existing commit. - OLD=$(git rev-parse origin/initial-branch) && - NEW=$ZERO_OID && - mv .git/packed-refs .git/old-packed-refs && - sed "s/$OLD/$NEW/g" <.git/old-packed-refs >.git/packed-refs && + git update-ref -d refs/remotes/origin/initial-branch && HUF=$(git rev-parse HEAD) && -- cgit v1.2.3 From f95661b74088f019847ee8408c8ce82012089e2e Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:35 +0000 Subject: t6500: use "ls -1" to snapshot ref database state By doing ls -1 .git/{reftable,refs/heads}, we can capture changes to both reftable and packed/loose ref storage. This relies on the fact that git-pack-refs (which we're looking for here) changes the number (loose/packed storage) and/or names (reftable) files used for ref storage. Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t6500-gc.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index 10c7ae7f09..c2021267f2 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -241,7 +241,7 @@ test_expect_success 'background auto gc respects lock for all operations' ' # create a ref whose loose presence we can use to detect a pack-refs run git update-ref refs/heads/should-be-loose HEAD && - test_path_is_file .git/refs/heads/should-be-loose && + (ls -1 .git/refs/heads .git/reftable >expect || true) && # now fake a concurrent gc that holds the lock; we can use our # shell pid so that it looks valid. @@ -258,7 +258,8 @@ test_expect_success 'background auto gc respects lock for all operations' ' # our gc should exit zero without doing anything run_and_wait_for_auto_gc && - test_path_is_file .git/refs/heads/should-be-loose + (ls -1 .git/refs/heads .git/reftable >actual || true) && + test_cmp expect actual ' # DO NOT leave a detached auto gc process running near the end of the -- cgit v1.2.3 From 977f8acefdbb5a7a39af52c82d21a9964f6ff7b0 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 2 Aug 2021 16:53:36 +0000 Subject: t6001: avoid direct file system access Signed-off-by: Han-Wen Nienhuys Signed-off-by: Junio C Hamano --- t/t6001-rev-list-graft.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t6001-rev-list-graft.sh b/t/t6001-rev-list-graft.sh index 90d93f77fa..7294147334 100755 --- a/t/t6001-rev-list-graft.sh +++ b/t/t6001-rev-list-graft.sh @@ -23,7 +23,8 @@ test_expect_success setup ' git commit -a -m "Third in one history." && A2=$(git rev-parse --verify HEAD) && - rm -f .git/refs/heads/main .git/index && + git update-ref -d refs/heads/main && + rm -f .git/index && echo >fileA fileA again && echo >subdir/fileB fileB again && -- cgit v1.2.3 From 760486a1f7a141b0d50b1c9c709ac1882968955c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Thu, 5 Aug 2021 03:25:41 +0200 Subject: {upload,receive}-pack tests: add --advertise-refs tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The --advertise-refs option had no explicit tests of its own, only other http tests that would fail at a distance if it it was broken. Let's test its behavior explicitly. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- t/t5555-http-smart-common.sh | 147 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100755 t/t5555-http-smart-common.sh (limited to 't') diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh new file mode 100755 index 0000000000..b813099ed2 --- /dev/null +++ b/t/t5555-http-smart-common.sh @@ -0,0 +1,147 @@ +#!/bin/sh + +test_description='test functionality common to smart fetch & push' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit --no-tag initial +' + +test_expect_success 'git upload-pack --advertise-refs' ' + cat >expect <<-EOF && + $(git rev-parse HEAD) HEAD + $(git rev-parse HEAD) $(git symbolic-ref HEAD) + 0000 + EOF + + # We only care about GIT_PROTOCOL, not GIT_TEST_PROTOCOL_VERSION + sane_unset GIT_PROTOCOL && + GIT_TEST_PROTOCOL_VERSION=2 \ + git upload-pack --advertise-refs . >out 2>err && + + test-tool pkt-line unpack actual && + test_must_be_empty err && + test_cmp actual expect && + + # The --advertise-refs alias works + git upload-pack --advertise-refs . >out 2>err && + + test-tool pkt-line unpack actual && + test_must_be_empty err && + test_cmp actual expect +' + +test_expect_success 'git upload-pack --advertise-refs: v0' ' + # With no specified protocol + cat >expect <<-EOF && + $(git rev-parse HEAD) HEAD + $(git rev-parse HEAD) $(git symbolic-ref HEAD) + 0000 + EOF + + git upload-pack --advertise-refs . >out 2>err && + test-tool pkt-line unpack actual && + test_must_be_empty err && + test_cmp actual expect && + + # With explicit v0 + GIT_PROTOCOL=version=0 \ + git upload-pack --advertise-refs . >out 2>err && + test-tool pkt-line unpack actual 2>err && + test_must_be_empty err && + test_cmp actual expect + +' + +test_expect_success 'git receive-pack --advertise-refs: v0' ' + # With no specified protocol + cat >expect <<-EOF && + $(git rev-parse HEAD) $(git symbolic-ref HEAD) + 0000 + EOF + + git receive-pack --advertise-refs . >out 2>err && + test-tool pkt-line unpack actual && + test_must_be_empty err && + test_cmp actual expect && + + # With explicit v0 + GIT_PROTOCOL=version=0 \ + git receive-pack --advertise-refs . >out 2>err && + test-tool pkt-line unpack actual 2>err && + test_must_be_empty err && + test_cmp actual expect + +' + +test_expect_success 'git upload-pack --advertise-refs: v1' ' + # With no specified protocol + cat >expect <<-EOF && + version 1 + $(git rev-parse HEAD) HEAD + $(git rev-parse HEAD) $(git symbolic-ref HEAD) + 0000 + EOF + + GIT_PROTOCOL=version=1 \ + git upload-pack --advertise-refs . >out && + + test-tool pkt-line unpack actual 2>err && + test_must_be_empty err && + test_cmp actual expect +' + +test_expect_success 'git receive-pack --advertise-refs: v1' ' + # With no specified protocol + cat >expect <<-EOF && + version 1 + $(git rev-parse HEAD) $(git symbolic-ref HEAD) + 0000 + EOF + + GIT_PROTOCOL=version=1 \ + git receive-pack --advertise-refs . >out && + + test-tool pkt-line unpack actual 2>err && + test_must_be_empty err && + test_cmp actual expect +' + +test_expect_success 'git upload-pack --advertise-refs: v2' ' + cat >expect <<-EOF && + version 2 + agent=FAKE + ls-refs=unborn + fetch=shallow wait-for-done + server-option + object-format=$(test_oid algo) + object-info + 0000 + EOF + + GIT_PROTOCOL=version=2 \ + GIT_USER_AGENT=FAKE \ + git upload-pack --advertise-refs . >out 2>err && + + test-tool pkt-line unpack actual && + test_must_be_empty err && + test_cmp actual expect +' + +test_expect_success 'git receive-pack --advertise-refs: v2' ' + # There is no v2 yet for receive-pack, implicit v0 + cat >expect <<-EOF && + $(git rev-parse HEAD) $(git symbolic-ref HEAD) + 0000 + EOF + + GIT_PROTOCOL=version=2 \ + git receive-pack --advertise-refs . >out 2>err && + + test-tool pkt-line unpack actual && + test_must_be_empty err && + test_cmp actual expect +' + +test_done -- cgit v1.2.3 From f234da80197b3115cd3c280e98d3393a884a9327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Thu, 5 Aug 2021 03:25:42 +0200 Subject: serve.[ch]: remove "serve_options", split up --advertise-refs code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "advertise capabilities" mode of serve.c added in ed10cb952d3 (serve: introduce git-serve, 2018-03-15) is only used by the http-backend.c to call {upload,receive}-pack with the --advertise-refs parameter. See 42526b478e3 (Add stateless RPC options to upload-pack, receive-pack, 2009-10-30). Let's just make cmd_upload_pack() take the two (v2) or three (v2) parameters the the v2/v1 servicing functions need directly, and pass those in via the function signature. The logic of whether daemon mode is implied by the timeout belongs in the v1 function (only used there). Once we split up the "advertise v2 refs" from "serve v2 request" it becomes clear that v2 never cared about those in combination. The only time it mattered was for v1 to emit its ref advertisement, in that case we wanted to emit the smart-http-only "no-done" capability. Since we only do that in the --advertise-refs codepath let's just have it set "do_done" itself in v1's upload_pack() just before send_ref(), at that point --advertise-refs and --stateless-rpc in combination are redundant (the only user is get_info_refs() in http-backend.c), so we can just pass in --advertise-refs only. Since we need to touch all the serve() and advertise_capabilities() codepaths let's rename them to less clever and obvious names, it's been suggested numerous times, the latest of which is [1]'s suggestion for protocol_v2_serve_loop(). Let's go with that. 1. https://lore.kernel.org/git/CAFQ2z_NyGb8rju5CKzmo6KhZXD0Dp21u-BbyCb2aNxLEoSPRJw@mail.gmail.com/ Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- t/helper/test-serve-v2.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 't') diff --git a/t/helper/test-serve-v2.c b/t/helper/test-serve-v2.c index aee35e5aef..28e905afc3 100644 --- a/t/helper/test-serve-v2.c +++ b/t/helper/test-serve-v2.c @@ -10,12 +10,12 @@ static char const * const serve_usage[] = { int cmd__serve_v2(int argc, const char **argv) { - struct serve_options opts = SERVE_OPTIONS_INIT; - + int stateless_rpc = 0; + int advertise_capabilities = 0; struct option options[] = { - OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc, + OPT_BOOL(0, "stateless-rpc", &stateless_rpc, N_("quit after a single request/response exchange")), - OPT_BOOL(0, "advertise-capabilities", &opts.advertise_capabilities, + OPT_BOOL(0, "advertise-capabilities", &advertise_capabilities, N_("exit immediately after advertising capabilities")), OPT_END() }; @@ -25,7 +25,11 @@ int cmd__serve_v2(int argc, const char **argv) argc = parse_options(argc, argv, prefix, options, serve_usage, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_UNKNOWN); - serve(&opts); + + if (advertise_capabilities) + protocol_v2_advertise_capabilities(); + else + protocol_v2_serve_loop(stateless_rpc); return 0; } -- cgit v1.2.3 From 98e2d9d6f7dc1aff61e99a1daed98e18c7c8526b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Thu, 5 Aug 2021 03:25:43 +0200 Subject: upload-pack: document and rename --advertise-refs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The --advertise-refs documentation in git-upload-pack added in 9812f2136b3 (upload-pack.c: use parse-options API, 2016-05-31) hasn't been entirely true ever since v2 support was implemented in e52449b6722 (connect: request remote refs using v2, 2018-03-15). Under v2 we don't advertise the refs at all, but rather dump the capabilities header. This option has always been an obscure internal implementation detail, it wasn't even documented for git-receive-pack. Since it has exactly one user let's rename it to --http-backend-info-refs, which is more accurate and points the reader in the right direction. Let's also cross-link this from the protocol v1 and v2 documentation. I'm retaining a hidden --advertise-refs alias in case there's any external users of this, and making both options hidden to the bash completion (as with most other internal-only options). Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- t/t5555-http-smart-common.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 't') diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh index b813099ed2..49faf5e283 100755 --- a/t/t5555-http-smart-common.sh +++ b/t/t5555-http-smart-common.sh @@ -8,6 +8,20 @@ test_expect_success 'setup' ' test_commit --no-tag initial ' +test_expect_success 'git upload-pack --http-backend-info-refs and --advertise-refs are aliased' ' + git upload-pack --http-backend-info-refs . >expected 2>err.expected && + git upload-pack --advertise-refs . >actual 2>err.actual && + test_cmp err.expected err.actual && + test_cmp expected actual +' + +test_expect_success 'git receive-pack --http-backend-info-refs and --advertise-refs are aliased' ' + git receive-pack --http-backend-info-refs . >expected 2>err.expected && + git receive-pack --advertise-refs . >actual 2>err.actual && + test_cmp err.expected err.actual && + test_cmp expected actual +' + test_expect_success 'git upload-pack --advertise-refs' ' cat >expect <<-EOF && $(git rev-parse HEAD) HEAD -- cgit v1.2.3 From f45022dc2fd692fd024f2eb41a86a66f19013d43 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 9 Aug 2021 10:11:50 +0200 Subject: connected: do not sort input revisions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to compute whether objects reachable from a set of tips are all connected, we do a revision walk with these tips as positive references and `--not --all`. `--not --all` will cause the revision walk to load all preexisting references as uninteresting, which can be very expensive in repositories with many references. Benchmarking the git-rev-list(1) command highlights that by far the most expensive single phase is initial sorting of the input revisions: after all references have been loaded, we first sort commits by author date. In a real-world repository with about 2.2 million references, it makes up about 40% of the total runtime of git-rev-list(1). Ultimately, the connectivity check shouldn't really bother about the order of input revisions at all. We only care whether we can actually walk all objects until we hit the cut-off point. So sorting the input is a complete waste of time. Introduce a new "--unsorted-input" flag to git-rev-list(1) which will cause it to not sort the commits and adjust the connectivity check to always pass the flag. This results in the following speedups, executed in a clone of gitlab-org/gitlab [1]: Benchmark #1: git rev-list --objects --quiet --not --all --not $(cat newrev) Time (mean ± σ): 7.639 s ± 0.065 s [User: 7.304 s, System: 0.335 s] Range (min … max): 7.543 s … 7.742 s 10 runs Benchmark #2: git rev-list --unsorted-input --objects --quiet --not --all --not $newrev Time (mean ± σ): 4.995 s ± 0.044 s [User: 4.657 s, System: 0.337 s] Range (min … max): 4.909 s … 5.048 s 10 runs Summary 'git rev-list --unsorted-input --objects --quiet --not --all --not $(cat newrev)' ran 1.53 ± 0.02 times faster than 'git rev-list --objects --quiet --not --all --not $newrev' [1]: https://gitlab.com/gitlab-org/gitlab.git. Note that not all refs are visible to clients. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- t/t6000-rev-list-misc.sh | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 't') diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index 12def7bcbf..ef849e5bc8 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -169,4 +169,35 @@ test_expect_success 'rev-list --count --objects' ' test_line_count = $count actual ' +test_expect_success 'rev-list --unsorted-input results in different sorting' ' + git rev-list --unsorted-input HEAD HEAD~ >first && + git rev-list --unsorted-input HEAD~ HEAD >second && + ! test_cmp first second && + sort first >first.sorted && + sort second >second.sorted && + test_cmp first.sorted second.sorted +' + +test_expect_success 'rev-list --unsorted-input incompatible with --no-walk' ' + cat >expect <<-EOF && + fatal: --no-walk is incompatible with --unsorted-input + EOF + test_must_fail git rev-list --unsorted-input --no-walk HEAD 2>error && + test_cmp expect error && + test_must_fail git rev-list --unsorted-input --no-walk=sorted HEAD 2>error && + test_cmp expect error && + test_must_fail git rev-list --unsorted-input --no-walk=unsorted HEAD 2>error && + test_cmp expect error && + + cat >expect <<-EOF && + fatal: --unsorted-input is incompatible with --no-walk + EOF + test_must_fail git rev-list --no-walk --unsorted-input HEAD 2>error && + test_cmp expect error && + test_must_fail git rev-list --no-walk=sorted --unsorted-input HEAD 2>error && + test_cmp expect error && + test_must_fail git rev-list --no-walk=unsorted --unsorted-input HEAD 2>error && + test_cmp expect error +' + test_done -- cgit v1.2.3 From 46d723ce57f2dd3c50504dc6f4ca73b4c392fa6f Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 9 Aug 2021 21:01:52 -0400 Subject: apply: keep buffer/size pair in sync when parsing binary hunks We parse through binary hunks by looping through the buffer with code like: llen = linelen(buffer, size); ...do something with the line... buffer += llen; size -= llen; However, before we enter the loop, there is one call that increments "buffer" but forgets to decrement "size". As a result, our "size" is off by the length of that line, and subsequent calls to linelen() may look past the end of the buffer for a newline. The fix is easy: we just need to decrement size as we do elsewhere. This bug goes all the way back to 0660626caf (binary diff: further updates., 2006-05-05). Presumably nobody noticed because it only triggers if the patch is corrupted, and even then we are often "saved" by luck. We use a strbuf to store the incoming patch, so we overallocate there, plus we add a 16-byte run of NULs as slop for memory comparisons. So if this happened accidentally, the common case is that we'd just read a few uninitialized bytes from the end of the strbuf before producing the expected "this patch is corrupted" error complaint. However, it is possible to carefully construct a case which reads off the end of the buffer. The included test does so. It will pass both before and after this patch when run normally, but using a tool like ASan shows that we get an out-of-bounds read before this patch, but not after. Reported-by: Xingman Chen Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/t4103-apply-binary.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 't') diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index 1b420e3b5f..290779406f 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -155,4 +155,27 @@ test_expect_success 'apply binary -p0 diff' ' test -z "$(git diff --name-status binary -- file3)" ' +test_expect_success 'reject truncated binary diff' ' + do_reset && + + # this length is calculated to get us very close to + # the 8192-byte strbuf we will use to read in the patch. + test-tool genrandom foo 6205 >file1 && + git diff --binary >patch && + + # truncate the patch at the second "literal" line, + # but exclude the trailing newline. We must use perl + # for this, since tools like "sed" cannot reliably + # produce output without the trailing newline. + perl -pe " + if (/^literal/ && \$count++ >= 1) { + chomp; + print; + exit 0; + } + " patch.trunc && + + do_reset && + test_must_fail git apply patch.trunc +' test_done -- cgit v1.2.3 From 626beebdf85a6ea5561dd8a0c912c9e9fb5622b4 Mon Sep 17 00:00:00 2001 From: Josh Steadmon Date: Tue, 10 Aug 2021 10:20:39 -0700 Subject: connect, protocol: log negotiated protocol version It is useful for performance monitoring and debugging purposes to know the wire protocol used for remote operations. This may differ from the version set in local configuration due to differences in version and/or configuration between the server and the client. Therefore, log the negotiated wire protocol version via trace2, for both clients and servers. Signed-off-by: Josh Steadmon Signed-off-by: Junio C Hamano --- t/t5705-session-id-in-capabilities.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 't') diff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh index f1d189d5bc..eb8c79aafd 100755 --- a/t/t5705-session-id-in-capabilities.sh +++ b/t/t5705-session-id-in-capabilities.sh @@ -73,6 +73,17 @@ do grep \"key\":\"server-sid\" tr2-client-events && grep \"key\":\"client-sid\" tr2-server-events ' + + test_expect_success "client & server log negotiated version (v${PROTO})" ' + test_when_finished "rm -rf local tr2-client-events tr2-server-events" && + cp -r "$LOCAL_PRISTINE" local && + GIT_TRACE2_EVENT="$(pwd)/tr2-client-events" \ + git -c protocol.version=$PROTO -C local fetch \ + --upload-pack "GIT_TRACE2_EVENT=\"$(pwd)/tr2-server-events\" git-upload-pack" \ + origin && + grep \"key\":\"negotiated-version\",\"value\":\"$PROTO\" tr2-client-events && + grep \"key\":\"negotiated-version\",\"value\":\"$PROTO\" tr2-server-events + ' done test_done -- cgit v1.2.3 From a8cbc895893f4c244e54374d3bf937819fb6e2e9 Mon Sep 17 00:00:00 2001 From: Tassilo Horn Date: Wed, 11 Aug 2021 19:51:04 +0200 Subject: userdiff: improve java hunk header regex Currently, the git diff hunk headers show the wrong method signature if the method has a qualified return type, an array return type, or a generic return type because the regex doesn't allow dots (.), [], or < and > in the return type. Also, type parameter declarations couldn't be matched. Add several t4018 tests asserting the right hunk headers for different cases: - enum constant change - change in generic method with bounded type parameters - change in generic method with wildcard - field change in a nested class Signed-off-by: Tassilo Horn Signed-off-by: Junio C Hamano --- t/t4018/java-class-member-function | 4 ++++ t/t4018/java-enum-constant | 6 ++++++ t/t4018/java-method-return-generic-bounded | 9 +++++++++ t/t4018/java-method-return-generic-wildcard | 9 +++++++++ t/t4018/java-nested-field | 6 ++++++ 5 files changed, 34 insertions(+) create mode 100644 t/t4018/java-enum-constant create mode 100644 t/t4018/java-method-return-generic-bounded create mode 100644 t/t4018/java-method-return-generic-wildcard create mode 100644 t/t4018/java-nested-field (limited to 't') diff --git a/t/t4018/java-class-member-function b/t/t4018/java-class-member-function index 298bc7a71b..3b95f68b3b 100644 --- a/t/t4018/java-class-member-function +++ b/t/t4018/java-class-member-function @@ -3,6 +3,10 @@ public class Beer int special; public static void main(String RIGHT[]) { + someMethodCall(); + someOtherMethod("17") + .doThat(); + // Whatever System.out.print("ChangeMe"); } } diff --git a/t/t4018/java-enum-constant b/t/t4018/java-enum-constant new file mode 100644 index 0000000000..a1931c8379 --- /dev/null +++ b/t/t4018/java-enum-constant @@ -0,0 +1,6 @@ +private enum RIGHT { + ONE, + TWO, + THREE, + ChangeMe +} diff --git a/t/t4018/java-method-return-generic-bounded b/t/t4018/java-method-return-generic-bounded new file mode 100644 index 0000000000..66dd78c379 --- /dev/null +++ b/t/t4018/java-method-return-generic-bounded @@ -0,0 +1,9 @@ +class MyExample { + public , R> Map foo(String[] RIGHT) { + someMethodCall(); + someOtherMethod() + .doThat(); + // Whatever... + return (List) Arrays.asList("ChangeMe"); + } +} diff --git a/t/t4018/java-method-return-generic-wildcard b/t/t4018/java-method-return-generic-wildcard new file mode 100644 index 0000000000..96e9e5f2c1 --- /dev/null +++ b/t/t4018/java-method-return-generic-wildcard @@ -0,0 +1,9 @@ +class MyExample { + public List foo(String[] RIGHT) { + someMethodCall(); + someOtherMethod() + .doThat(); + // Whatever... + return Arrays.asList("ChangeMe"); + } +} diff --git a/t/t4018/java-nested-field b/t/t4018/java-nested-field new file mode 100644 index 0000000000..d92d3ec688 --- /dev/null +++ b/t/t4018/java-nested-field @@ -0,0 +1,6 @@ +class MyExample { + private static class RIGHT { + // change an inner class field + String inner = "ChangeMe"; + } +} -- cgit v1.2.3 From b227bead4d8fb6e75b5c58ba511c7e935b09b24b Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Wed, 11 Aug 2021 23:16:44 +0000 Subject: t5607: avoid using prerequisites to select algorithm In this test, we currently use the SHA1 prerequisite to specify the algorithm we're using to test, since SHA-256 bundles are always v3, whereas SHA-1 bundles default to v2, and as a result the default output differs. However, this causes a problem if we run with GIT_TEST_FAIL_PREREQS set, since that means that we'll unexpectedly fail the SHA1 prerequisite, resulting in incorrect expected output. Let's fix this by checking against the built-in data called "algo", which tells us which algorithm is in use. This should work in any situation, making our test a little more robust. Signed-off-by: brian m. carlson Signed-off-by: Junio C Hamano --- t/t5607-clone-bundle.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh index ed0d911e95..51705aa86a 100755 --- a/t/t5607-clone-bundle.sh +++ b/t/t5607-clone-bundle.sh @@ -91,7 +91,8 @@ test_expect_success 'ridiculously long subject in boundary' ' git fetch long-subject-bundle.bdl && - if ! test_have_prereq SHA1 + algo=$(test_oid algo) && + if test "$algo" != sha1 then echo "@object-format=sha256" fi >expect && @@ -100,7 +101,7 @@ test_expect_success 'ridiculously long subject in boundary' ' $(git rev-parse HEAD) HEAD EOF - if test_have_prereq SHA1 + if test "$algo" = sha1 then head -n 3 long-subject-bundle.bdl else -- cgit v1.2.3 From 118ee5c6135833a8fc015833dc3e471d9d31fbd8 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 12 Aug 2021 13:42:07 +0000 Subject: t3403: fix commit authorship Setting GIT_AUTHOR_* when committing with --amend will only change the author if we also pass --reset-author. This commit is used in some tests that ensure the author ident does not change when rebasing. Creating this commit without changing the authorship meant that the test would not catch regressions that caused rebase to discard the original authorship information. Signed-off-by: Phillip Wood Reviewed-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t3403-rebase-skip.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index e26762d0b2..6365c5af2f 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -36,7 +36,8 @@ test_expect_success setup ' test_tick && GIT_AUTHOR_NAME="Another Author" \ GIT_AUTHOR_EMAIL="another.author@example.com" \ - git commit --amend --no-edit -m amended-goodbye && + git commit --amend --no-edit -m amended-goodbye \ + --reset-author && test_tick && git tag amended-goodbye && -- cgit v1.2.3 From bed9b4e3128af2c36645ba44fe19bf10af6d68ea Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 12 Aug 2021 13:42:08 +0000 Subject: rebase --apply: restore some tests 980b482d28 ("rebase tests: mark tests specific to the am-backend with --am", 2020-02-15) sought to prepare tests testing the "apply" backend in preparation for 2ac0d6273f ("rebase: change the default backend from "am" to "merge"", 2020-02-15). However some tests seem to have been missed leading to us testing the "merge" backend twice. This patch fixes some cases that I noticed while adding tests to these files, I have not audited all the other rebase test files. I've reworded a couple of the test descriptions to make it clear which backend they are testing. Signed-off-by: Phillip Wood Reviewed-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t3403-rebase-skip.sh | 2 +- t/t3418-rebase-continue.sh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 't') diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index 6365c5af2f..a44e68d0ff 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -52,7 +52,7 @@ test_expect_success setup ' ' test_expect_success 'rebase with git am -3 (default)' ' - test_must_fail git rebase main + test_must_fail git rebase --apply main ' test_expect_success 'rebase --skip can not be used with other options' ' diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index f4c2ee02bc..bda5e5db80 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -21,7 +21,7 @@ test_expect_success 'setup' ' git checkout main ' -test_expect_success 'interactive rebase --continue works with touched file' ' +test_expect_success 'merge based rebase --continue with works with touched file' ' rm -fr .git/rebase-* && git reset --hard && git checkout main && @@ -31,12 +31,12 @@ test_expect_success 'interactive rebase --continue works with touched file' ' git rebase --continue ' -test_expect_success 'non-interactive rebase --continue works with touched file' ' +test_expect_success 'apply based rebase --continue works with touched file' ' rm -fr .git/rebase-* && git reset --hard && git checkout main && - test_must_fail git rebase --onto main main topic && + test_must_fail git rebase --apply --onto main main topic && echo "Resolved" >F2 && git add F2 && test-tool chmtime =-60 F1 && @@ -254,7 +254,7 @@ test_rerere_autoupdate () { ' } -test_rerere_autoupdate +test_rerere_autoupdate --apply test_rerere_autoupdate -m GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR test_rerere_autoupdate -i -- cgit v1.2.3 From e5ee33e8551fa934862b8cbe50693f4841e7dace Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Thu, 12 Aug 2021 13:42:09 +0000 Subject: rebase --continue: remove .git/MERGE_MSG If the user skips the final commit by removing all the changes from the index and worktree with 'git restore' (or read-tree) and then runs 'git rebase --continue' .git/MERGE_MSG is left behind. This will seed the commit message the next time the user commits which is not what we want to happen. Reported-by: Victor Gambier Signed-off-by: Phillip Wood Reviewed-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t3403-rebase-skip.sh | 8 ++++++++ t/t3418-rebase-continue.sh | 10 ++++++++++ 2 files changed, 18 insertions(+) (limited to 't') diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index a44e68d0ff..f6e4864497 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -20,6 +20,7 @@ test_expect_success setup ' git add hello && git commit -m "hello" && git branch skip-reference && + git tag hello && echo world >> hello && git commit -a -m "hello world" && @@ -96,6 +97,13 @@ test_expect_success 'moved back to branch correctly' ' test_debug 'gitk --all & sleep 1' +test_expect_success 'skipping final pick removes .git/MERGE_MSG' ' + test_must_fail git rebase --onto hello reverted-goodbye^ \ + reverted-goodbye && + git rebase --skip && + test_path_is_missing .git/MERGE_MSG +' + test_expect_success 'correct advice upon picking empty commit' ' test_when_finished "git rebase --abort" && test_must_fail git rebase -i --onto goodbye \ diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index bda5e5db80..738fbae9b2 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -31,6 +31,16 @@ test_expect_success 'merge based rebase --continue with works with touched file' git rebase --continue ' +test_expect_success 'merge based rebase --continue removes .git/MERGE_MSG' ' + git checkout -f --detach topic && + + test_must_fail git rebase --onto main HEAD^ && + git read-tree --reset -u HEAD && + test_path_is_file .git/MERGE_MSG && + git rebase --continue && + test_path_is_missing .git/MERGE_MSG +' + test_expect_success 'apply based rebase --continue works with touched file' ' rm -fr .git/rebase-* && git reset --hard && -- cgit v1.2.3 From 8ef6aad664715c16caf6e36a7f6b174a06574477 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Sat, 14 Aug 2021 21:40:30 +0000 Subject: commit: restore --edit when combined with --fixup Recent changes to --fixup, adding amend suboption, caused the --edit flag to be ignored as use_editor was always set to zero. Restore edit_flag having higher priority than fixup_message when deciding the value of use_editor by moving the edit flag condition later in the method. Signed-off-by: Joel Klinghed Signed-off-by: Junio C Hamano --- t/t7500-commit-template-squash-signoff.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh index 54c2082acb..8dd0f98812 100755 --- a/t/t7500-commit-template-squash-signoff.sh +++ b/t/t7500-commit-template-squash-signoff.sh @@ -270,7 +270,7 @@ EOF test_expect_success 'commit --fixup provides correct one-line commit message' ' commit_for_rebase_autosquash_setup && - git commit --fixup HEAD~1 && + EDITOR="echo ignored >>" git commit --fixup HEAD~1 && commit_msg_is "fixup! target message subject line" ' @@ -281,6 +281,13 @@ test_expect_success 'commit --fixup -m"something" -m"extra"' ' extra" ' +test_expect_success 'commit --fixup --edit' ' + commit_for_rebase_autosquash_setup && + EDITOR="printf \"something\nextra\" >>" git commit --fixup HEAD~1 --edit && + commit_msg_is "fixup! target message subject linesomething +extra" +' + get_commit_msg () { rev="$1" && git log -1 --pretty=format:"%B" "$rev" -- cgit v1.2.3 From e9f2118ddfad4ae5e37adc7637acc9daf4ac8c9c Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Mon, 16 Aug 2021 04:10:23 -0500 Subject: completion: bash: fix for suboptions with value We need to ignore options that don't start with -- as well. Depending on the value of COMP_WORDBREAKS the last word could be duplicated otherwise. Can be tested with: git merge -X diff-algorithm= Tested-by: David Aguilar Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- t/t9902-completion.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 't') diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index cb057ef161..6b56e54fc3 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -540,6 +540,15 @@ test_expect_success '__gitcomp - expand/narrow all negative options' ' EOF ' +test_expect_success '__gitcomp - equal skip' ' + test_gitcomp "--option=" "--option=" <<-\EOF && + + EOF + test_gitcomp "option=" "option=" <<-\EOF + + EOF +' + test_expect_success '__gitcomp - doesnt fail because of invalid variable name' ' __gitcomp "$invalid_variable_name" ' @@ -2380,6 +2389,12 @@ test_expect_success 'git clone --config= - value' ' EOF ' +test_expect_success 'options with value' ' + test_completion "git merge -X diff-algorithm=" <<-\EOF + + EOF +' + test_expect_success 'sourcing the completion script clears cached commands' ' __git_compute_all_commands && verbose test -n "$__git_all_commands" && -- cgit v1.2.3 From 2be6b6f411136c6773a90d2cfdacf3cccb79d3e6 Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Fri, 20 Aug 2021 15:40:35 +0000 Subject: rebase -r: make 'merge -c' behave like reword If the user runs git log while rewording a commit it is confusing if sometimes we're amending the commit that's being reworded and at other times we're creating a new commit depending on whether we could fast-forward or not[1]. For this reason the reword command ensures that there are no uncommitted changes when rewording. The reword command also allows the user to edit the todo list while the rebase is paused. As 'merge -c' also rewords commits make it behave like reword and add a test. [1] https://lore.kernel.org/git/xmqqlfvu4be3.fsf@gitster-ct.c.googlers.com/T/#m133009cb91cf0917bcf667300f061178be56680a Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- t/lib-rebase.sh | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ t/t3430-rebase-merges.sh | 20 ++++++++++--------- 2 files changed, 61 insertions(+), 9 deletions(-) (limited to 't') diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index dc75b83451..99d9e7efd2 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -151,3 +151,53 @@ test_editor_unchanged () { EOF test_cmp expect actual } + +# Set up an editor for testing reword commands +# Checks that there are no uncommitted changes when rewording and that the +# todo-list is reread after each +set_reword_editor () { + >reword-actual && + >reword-oid && + + # Check rewording keeps the original authorship + GIT_AUTHOR_NAME="Reword Author" + GIT_AUTHOR_EMAIL="reword.author@example.com" + GIT_AUTHOR_DATE=@123456 + + write_script reword-sequence-editor.sh <<-\EOF && + todo="$(cat "$1")" && + echo "exec git log -1 --pretty=format:'%an <%ae> %at%n%B%n' \ + >>reword-actual" >"$1" && + printf "%s\n" "$todo" >>"$1" + EOF + + write_script reword-editor.sh <<-EOF && + # Save the oid of the first reworded commit so we can check rebase + # fast-forwards to it + if ! test -s reword-oid + then + git rev-parse HEAD >reword-oid + fi && + # There should be no uncommited changes + git diff --exit-code HEAD && + # The todo-list should be re-read after a reword + GIT_SEQUENCE_EDITOR="\"$PWD/reword-sequence-editor.sh\"" \ + git rebase --edit-todo && + echo edited >>"\$1" + EOF + + test_set_editor "$PWD/reword-editor.sh" +} + +# Check the results of a rebase after calling set_reword_editor +# Pass the commits that were reworded in the order that they were picked +# Expects the first pick to be a fast-forward +check_reworded_commits () { + test_cmp_rev "$(cat reword-oid)" "$1^{commit}" && + git log --format="%an <%ae> %at%n%B%nedited%n" --no-walk=unsorted "$@" \ + >reword-expected && + test_cmp reword-expected reword-actual && + git log --format="%an <%ae> %at%n%B" -n $# --first-parent --reverse \ + >reword-log && + test_cmp reword-expected reword-log +} diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index 6748070df5..183c3a2383 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -172,17 +172,19 @@ test_expect_success 'failed `merge ` does not crash' ' grep "^Merge branch ${SQ}G${SQ}$" .git/rebase-merge/message ' -test_expect_success 'fast-forward merge -c still rewords' ' - git checkout -b fast-forward-merge-c H && +test_expect_success 'merge -c commits before rewording and reloads todo-list' ' + cat >script-from-scratch <<-\EOF && + merge -c E B + merge -c H G + EOF + + git checkout -b merge-c H && ( - set_fake_editor && - FAKE_COMMIT_MESSAGE=edited \ - GIT_SEQUENCE_EDITOR="echo merge -c H G >" \ - git rebase -ir @^ + set_reword_editor && + GIT_SEQUENCE_EDITOR="\"$PWD/replace-editor.sh\"" \ + git rebase -i -r D ) && - echo edited >expected && - git log --pretty=format:%B -1 >actual && - test_cmp expected actual + check_reworded_commits E H ' test_expect_success 'with a branch tip that was cherry-picked already' ' -- cgit v1.2.3 From 0c164ae7a65f811ef3fb3188c63cd157335463bb Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Fri, 20 Aug 2021 15:40:36 +0000 Subject: rebase -i: add another reword test None of the existing reword tests check that there are no uncommitted changes when the editor is opened. Reuse the editor script from the last commit to fix this omission. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- t/t3404-rebase-interactive.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 't') diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 66bcbbf952..d877872e8f 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -839,6 +839,19 @@ test_expect_success 'reword' ' git show HEAD~2 | grep "C changed" ' +test_expect_success 'no uncommited changes when rewording the todo list is reloaded' ' + git checkout E && + test_when_finished "git checkout @{-1}" && + ( + set_fake_editor && + GIT_SEQUENCE_EDITOR="\"$PWD/fake-editor.sh\"" && + export GIT_SEQUENCE_EDITOR && + set_reword_editor && + FAKE_LINES="reword 1 reword 2" git rebase -i C + ) && + check_reworded_commits D E +' + test_expect_success 'rebase -i can copy notes' ' git config notes.rewrite.rebase true && git config notes.rewriteRef "refs/notes/*" && -- cgit v1.2.3 From baf8ec8d3a0327307f79efd31d5717a0c91c4d8c Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Fri, 20 Aug 2021 15:40:37 +0000 Subject: rebase -r: don't write .git/MERGE_MSG when fast-forwarding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When fast-forwarding we do not create a new commit so .git/MERGE_MSG is not removed and can end up seeding the message of a commit made after the rebase has finished. Avoid writing .git/MERGE_MSG when we are fast-forwarding by writing the file after the fast-forward checks. Note that there are no changes to the fast-forward code, it is simply moved. Note that the way this change is implemented means we no longer write the author script when fast-forwarding either. I believe this is safe for the reasons below but it is a departure from what we do when fast-forwarding a non-merge commit. If we reword the merge then 'git commit --amend' will keep the authorship of the commit we're rewording as it ignores GIT_AUTHOR_* unless --reset-author is passed. It will also export the correct GIT_AUTHOR_* variables to any hooks and we already test the authorship of the reworded commit. If we are not rewording then we no longer call spilt_ident() which means we are no longer checking the commit author header looks sane. However this is what we already do when fast-forwarding non-merge commits in skip_unnecessary_picks() so I don't think we're breaking any promises by not checking the author here. Reported-by: SZEDER Gábor Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- t/lib-rebase.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 99d9e7efd2..ec6b9b107d 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -173,10 +173,16 @@ set_reword_editor () { write_script reword-editor.sh <<-EOF && # Save the oid of the first reworded commit so we can check rebase - # fast-forwards to it + # fast-forwards to it. Also check that we do not write .git/MERGE_MSG + # when fast-forwarding if ! test -s reword-oid then - git rev-parse HEAD >reword-oid + git rev-parse HEAD >reword-oid && + if test -f .git/MERGE_MSG + then + echo 1>&2 "error: .git/MERGE_MSG exists" + exit 1 + fi fi && # There should be no uncommited changes git diff --exit-code HEAD && -- cgit v1.2.3 From f2563c9ef3c028b5d4165df02fdfc0fcd613102d Mon Sep 17 00:00:00 2001 From: Phillip Wood Date: Fri, 20 Aug 2021 15:40:38 +0000 Subject: rebase -r: fix merge -c with a merge strategy If a rebase is started with a --strategy option other than "ort" or "recursive" then "merge -c" does not allow the user to reword the commit message. Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- t/t3430-rebase-merges.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 't') diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index 183c3a2383..43c82d9a33 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -187,6 +187,24 @@ test_expect_success 'merge -c commits before rewording and reloads todo-list' ' check_reworded_commits E H ' +test_expect_success 'merge -c rewords when a strategy is given' ' + git checkout -b merge-c-with-strategy H && + write_script git-merge-override <<-\EOF && + echo overridden$1 >G.t + git add G.t + EOF + + PATH="$PWD:$PATH" \ + GIT_SEQUENCE_EDITOR="echo merge -c H G >" \ + GIT_EDITOR="echo edited >>" \ + git rebase --no-ff -ir -s override -Xxopt E && + test_write_lines overridden--xopt >expect && + test_cmp expect G.t && + test_write_lines H "" edited "" >expect && + git log --format=%B -1 >actual && + test_cmp expect actual + +' test_expect_success 'with a branch tip that was cherry-picked already' ' git checkout -b already-upstream main && base="$(git rev-parse --verify HEAD)" && -- cgit v1.2.3 From f172556b89822693cae70f87c73fe7b6a96b9855 Mon Sep 17 00:00:00 2001 From: ZheNing Hu Date: Sun, 22 Aug 2021 13:08:41 +0000 Subject: cherry-pick: use better advice message "git cherry-pick", upon seeing a conflict, says: hint: after resolving the conflicts, mark the corrected paths hint: with 'git add ' or 'git rm ' hint: and commit the result with 'git commit' as if running "git commit" to conclude the resolution of this single step were the end of the story. This stems from the fact that the command originally was to pick a single commit and not a range of commits, and the message was written back then and has not been adjusted. When picking a range of commits and the command stops with a conflict in the middle of the range, however, after resolving the conflict and (optionally) recording the result with "git commit", the user has to run "git cherry-pick --continue" to have the rest of the range dealt with, "--skip" to drop the current commit, or "--abort" to discard the series. Suggest use of "git cherry-pick --continue/--skip/--abort" so that the message also covers the case where a range of commits are being picked. Similarly, this optimization can be applied to git revert, suggest use of "git revert --continue/--skip/--abort" so that the message also covers the case where a range of commits are being reverted. It is worth mentioning that now we use advice() to print the content of GIT_CHERRY_PICK_HELP in print_advice(), each line of output will start with "hint: ". Mentored-by: Christian Couder Mentored-by: Hariom Verma Helped-by: Phillip Wood Helped-by: Junio C Hamano Signed-off-by: ZheNing Hu Signed-off-by: Junio C Hamano --- t/t3501-revert-cherry-pick.sh | 16 ++++++++++++++++ t/t3507-cherry-pick-conflict.sh | 17 ++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) (limited to 't') diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index 9d100cd188..4b5b607673 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -158,4 +158,20 @@ test_expect_success 'cherry-pick works with dirty renamed file' ' grep -q "^modified$" renamed ' +test_expect_success 'advice from failed revert' ' + test_commit --no-tag "add dream" dream dream && + dream_oid=$(git rev-parse --short HEAD) && + cat <<-EOF >expected && + error: could not revert $dream_oid... add dream + hint: After resolving the conflicts, mark them with + hint: "git add/rm ", then run + hint: "git revert --continue". + hint: You can instead skip this commit with "git revert --skip". + hint: To abort and get back to the state before "git revert", + hint: run "git revert --abort". + EOF + test_commit --append --no-tag "double-add dream" dream dream && + test_must_fail git revert HEAD^ 2>actual && + test_cmp expected actual +' test_done diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 014001b8f3..979e843c65 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -47,20 +47,23 @@ test_expect_success 'failed cherry-pick does not advance HEAD' ' test "$head" = "$newhead" ' -test_expect_success 'advice from failed cherry-pick' " +test_expect_success 'advice from failed cherry-pick' ' pristine_detach initial && - picked=\$(git rev-parse --short picked) && + picked=$(git rev-parse --short picked) && cat <<-EOF >expected && - error: could not apply \$picked... picked - hint: after resolving the conflicts, mark the corrected paths - hint: with 'git add ' or 'git rm ' - hint: and commit the result with 'git commit' + error: could not apply $picked... picked + hint: After resolving the conflicts, mark them with + hint: "git add/rm ", then run + hint: "git cherry-pick --continue". + hint: You can instead skip this commit with "git cherry-pick --skip". + hint: To abort and get back to the state before "git cherry-pick", + hint: run "git cherry-pick --abort". EOF test_must_fail git cherry-pick picked 2>actual && test_cmp expected actual -" +' test_expect_success 'advice from failed cherry-pick --no-commit' " pristine_detach initial && -- cgit v1.2.3 From 3ba3d0621b6822e974f06123db9394b33e454ed7 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Tue, 24 Aug 2021 12:15:54 -0400 Subject: pack-bitmap-write.c: gracefully fail to write non-closed bitmaps The set of objects covered by a bitmap must be closed under reachability, since it must be the case that there is a valid bit position assigned for every possible reachable object (otherwise the bitmaps would be incomplete). Pack bitmaps are never written from 'git repack' unless repacking all-into-one, and so we never write non-closed bitmaps (except in the case of partial clones where we aren't guaranteed to have all objects). But multi-pack bitmaps change this, since it isn't known whether the set of objects in the MIDX is closed under reachability until walking them. Plumb through a bit that is set when a reachable object isn't found. As soon as a reachable object isn't found in the set of objects to include in the bitmap, bitmap_writer_build() knows that the set is not closed, and so it now fails gracefully. A test is added in t0410 to trigger a bitmap write without full reachability closure by removing local copies of some reachable objects from a promisor remote. Signed-off-by: Taylor Blau Signed-off-by: Junio C Hamano --- t/t0410-partial-clone.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index a211a66c67..bbcc51ee8e 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -536,7 +536,13 @@ test_expect_success 'gc does not repack promisor objects if there are none' ' repack_and_check () { rm -rf repo2 && cp -r repo repo2 && - git -C repo2 repack $1 -d && + if test x"$1" = "x--must-fail" + then + shift + test_must_fail git -C repo2 repack $1 -d + else + git -C repo2 repack $1 -d + fi && git -C repo2 fsck && git -C repo2 cat-file -e $2 && @@ -561,6 +567,7 @@ test_expect_success 'repack -d does not irreversibly delete promisor objects' ' printf "$THREE\n" | pack_as_from_promisor && delete_object repo "$ONE" && + repack_and_check --must-fail -ab "$TWO" "$THREE" && repack_and_check -a "$TWO" "$THREE" && repack_and_check -A "$TWO" "$THREE" && repack_and_check -l "$TWO" "$THREE" -- cgit v1.2.3 From bd72824c6099604af9a199f6bd9e1684f839b434 Mon Sep 17 00:00:00 2001 From: Mickey Endito Date: Mon, 23 Aug 2021 20:12:40 +0000 Subject: t5582: remove spurious 'cd "$D"' line The variable D is never defined in test t5582, more severely the test fails if D is defined by something outside the test suite, so remove this spurious line. Signed-off-by: Mickey Endito Signed-off-by: Junio C Hamano --- t/t5582-fetch-negative-refspec.sh | 1 - 1 file changed, 1 deletion(-) (limited to 't') diff --git a/t/t5582-fetch-negative-refspec.sh b/t/t5582-fetch-negative-refspec.sh index e5d2e79ad3..7a80e47c2b 100755 --- a/t/t5582-fetch-negative-refspec.sh +++ b/t/t5582-fetch-negative-refspec.sh @@ -105,7 +105,6 @@ test_expect_success "fetch with negative pattern refspec does not expand prefix" ' test_expect_success "fetch with negative refspec avoids duplicate conflict" ' - cd "$D" && ( cd one && git branch dups/a && -- cgit v1.2.3 From f6a5af0f6218e82d18d79053ef49ea1c696cf167 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Tue, 24 Aug 2021 20:01:29 +0200 Subject: t9001: PATH must not use Windows-style paths On Windows, $(pwd) returns a drive-letter style path C:/foo, while $PWD contains a POSIX style /c/foo path. When we want to interpolate the current directory in the PATH variable, we must not use the C:/foo style, because the meaning of the colon is ambiguous. Use the POSIX style. Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- t/t9001-send-email.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 35289d9135..993bef48da 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -2099,7 +2099,7 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' ' test_expect_success $PREREQ 'test using command name with --sendmail-cmd' ' clean_fake_sendmail && - PATH="$(pwd):$PATH" \ + PATH="$PWD:$PATH" \ git send-email \ --from="Example " \ --to=nobody@example.com \ -- cgit v1.2.3 From a16eb6b1ff333f3e26b99f17ef3bb7dbf8135f39 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Tue, 24 Aug 2021 15:44:00 +0000 Subject: maintenance: skip bootout/bootstrap when plist is registered On macOS, we use launchctl to manage the background maintenance schedule. This uses a set of .plist files to describe the schedule, but these files are also registered with 'launchctl bootstrap'. If multiple 'git maintenance start' commands run concurrently, then they can collide replacing these schedule files and registering them with launchctl. To avoid extra launchctl commands, do a check for the .plist files on disk and check if they are registered using 'launchctl list '. This command will return with exit code 0 if it exists, or exit code 113 if it does not. We can test this behavior using the GIT_TEST_MAINT_SCHEDULER environment variable. Signed-off-by: Derrick Stolee Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t7900-maintenance.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 't') diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 58f46c77e6..fc16ac2258 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -582,6 +582,23 @@ test_expect_success 'start and stop macOS maintenance' ' test_line_count = 0 actual ' +test_expect_success 'use launchctl list to prevent extra work' ' + # ensure we are registered + GIT_TEST_MAINT_SCHEDULER=launchctl:./print-args git maintenance start && + + # do it again on a fresh args file + rm -f args && + GIT_TEST_MAINT_SCHEDULER=launchctl:./print-args git maintenance start && + + ls "$HOME/Library/LaunchAgents" >actual && + cat >expect <<-\EOF && + list org.git-scm.git.hourly + list org.git-scm.git.daily + list org.git-scm.git.weekly + EOF + test_cmp expect args +' + test_expect_success 'start and stop Windows maintenance' ' write_script print-args <<-\EOF && echo $* >>args -- cgit v1.2.3 From f58c7468cde9f4eb6be0f9cc11ad1d140a8a2657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Mon, 23 Aug 2021 15:17:49 +0200 Subject: ls-remote: set packet_trace_identity() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set packet_trace_identity() for ls-remote. This replaces the generic "git" identity in GIT_TRACE_PACKET= traces to "ls-remote", e.g.: [...] packet: upload-pack> version 2 [...] packet: upload-pack> agent=git/2.32.0-dev [...] packet: ls-remote< version 2 [...] packet: ls-remote< agent=git/2.32.0-dev Where in an "git ls-remote file://" dialog ">" is the sender (or "to the server") and "<" is the recipient (or "received by the client"). Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- t/t5702-protocol-v2.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 't') diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 66af411057..8e38aa5804 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -27,9 +27,9 @@ test_expect_success 'list refs with git:// using protocol v2' ' ls-remote --symref "$GIT_DAEMON_URL/parent" >actual && # Client requested to use protocol v2 - grep "git> .*\\\0\\\0version=2\\\0$" log && + grep "ls-remote> .*\\\0\\\0version=2\\\0$" log && # Server responded using protocol v2 - grep "git< version 2" log && + grep "ls-remote< version 2" log && git ls-remote --symref "$GIT_DAEMON_URL/parent" >expect && test_cmp expect actual @@ -151,7 +151,7 @@ test_expect_success 'list refs with file:// using protocol v2' ' ls-remote --symref "file://$(pwd)/file_parent" >actual && # Server responded using protocol v2 - grep "git< version 2" log && + grep "ls-remote< version 2" log && git ls-remote --symref "file://$(pwd)/file_parent" >expect && test_cmp expect actual -- cgit v1.2.3 From c21b2511c2b725c47da43d33c253070be6cb4f2d Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 24 Aug 2021 21:35:52 -0400 Subject: t5323: drop mentions of "master" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 0696232390 (pack-redundant: fix crash when one packfile in repo, 2020-12-16) added one some new tests to t5323. At the time, the sub-repo we used was called "master". But in a parallel branch, this was switched to "main". When the latter branch was merged in 27d7c8599b (Merge branch 'js/default-branch-name-tests-final-stretch', 2021-01-25), some of those spots caused textual conflicts, but some (for tests that were far enough away from other changed code) were just semantic. The merge resolution fixed up most spots, but missed this one. Even though this did impact actual code, it turned out not to fail the tests. Running 'cd "$master_repo"' ended up staying in the same directory, running the test in the main trash repo instead of the sub-repo. But because the point of the test is checking behavior when there are no packfiles, it worked in either repo (since both are empty at this point in the script). Reported-by: SZEDER Gábor Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/t5323-pack-redundant.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t5323-pack-redundant.sh b/t/t5323-pack-redundant.sh index 8b01793845..8dbbcc5e51 100755 --- a/t/t5323-pack-redundant.sh +++ b/t/t5323-pack-redundant.sh @@ -114,9 +114,9 @@ test_expect_success 'setup main repo' ' create_commits_in "$main_repo" A B C D E F G H I J K L M N O P Q R ' -test_expect_success 'master: pack-redundant works with no packfile' ' +test_expect_success 'main: pack-redundant works with no packfile' ' ( - cd "$master_repo" && + cd "$main_repo" && cat >expect <<-EOF && fatal: Zero packs found! EOF -- cgit v1.2.3 From 597fa8cb430179ec2b28e2d39a857af25717c98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= Date: Sat, 21 Aug 2021 08:36:33 +0700 Subject: t6300: don't run cat-file on non-existent object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In t6300, some tests are guarded behind some prerequisites. Thus, objects created by those tests ain't available if those prerequisites are unsatistified. Attempting to run "cat-file" on those objects will run into failure. In fact, running t6300 in an environment without gpg(1), we'll see those warnings: fatal: Not a valid object name refs/tags/signed-empty fatal: Not a valid object name refs/tags/signed-short fatal: Not a valid object name refs/tags/signed-long Let's put those commands into the real tests, in order to: * skip their execution if prerequisites aren't satistified. * check their exit status code The expected value for objects with type: commit needs to be computed outside the test because we can't rely on "$3" there. Furthermore, to prevent the accidental usage of that computed expected value, BUG out on unknown object's type. Signed-off-by: Đoàn Trần Công Danh Signed-off-by: Junio C Hamano --- t/t6300-for-each-ref.sh | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 't') diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 9e0214076b..ad9620efeb 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -59,18 +59,23 @@ test_atom() { # Automatically test "contents:size" atom after testing "contents" if test "$2" = "contents" then - case $(git cat-file -t "$ref") in - tag) - # We cannot use $3 as it expects sanitize_pgp to run - expect=$(git cat-file tag $ref | tail -n +6 | wc -c) ;; - tree | blob) - expect='' ;; - commit) - expect=$(printf '%s' "$3" | wc -c) ;; - esac - # Leave $expect unquoted to lose possible leading whitespaces - echo $expect >expected + # for commit leg, $3 is changed there + expect=$(printf '%s' "$3" | wc -c) test_expect_${4:-success} $PREREQ "basic atom: $1 contents:size" ' + type=$(git cat-file -t "$ref") && + case $type in + tag) + # We cannot use $3 as it expects sanitize_pgp to run + expect=$(git cat-file tag $ref | tail -n +6 | wc -c) ;; + tree | blob) + expect="" ;; + commit) + : "use the calculated expect" ;; + *) + BUG "unknown object type" ;; + esac && + # Leave $expect unquoted to lose possible leading whitespaces + echo $expect >expected && git for-each-ref --format="%(contents:size)" "$ref" >actual && test_cmp expected actual ' -- cgit v1.2.3 From 1549577338c7c3a4455e9b3f05f9c8740b8e5337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= Date: Sat, 21 Aug 2021 08:36:34 +0700 Subject: t6300: check for cat-file exit status code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In test_atom(), we're piping the output of cat-file to tail(1), thus, losing its exit status. Let's use a temporary file to preserve git exit status code. Signed-off-by: Đoàn Trần Công Danh Signed-off-by: Junio C Hamano --- t/t6300-for-each-ref.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index ad9620efeb..05a15a933a 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -66,7 +66,9 @@ test_atom() { case $type in tag) # We cannot use $3 as it expects sanitize_pgp to run - expect=$(git cat-file tag $ref | tail -n +6 | wc -c) ;; + git cat-file tag $ref >out && + expect=$(tail -n +6 out | wc -c) && + rm -f out ;; tree | blob) expect="" ;; commit) -- cgit v1.2.3 From 8174627b3d32dc80cb477b3fa46971955f26c6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?= Date: Sun, 22 Aug 2021 15:49:08 +0700 Subject: diff-lib: ignore paths that are outside $cwd if --relative asked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For diff family commands, we can tell them to exclude changes outside of some directories if --relative is requested. In diff_unmerge(), NULL will be returned if the requested path is outside of the interesting directories, thus we'll run into NULL pointer dereference in run_diff_files when trying to dereference its return value. Checking for return value of diff_unmerge before dereferencing is not sufficient, though. Since, diff engine will try to work on such pathspec later. Let's not run diff on those unintesting entries, instead. As a side effect, by skipping like that, we can save some CPU cycles. Reported-by: Thomas De Zeeuw Tested-by: Carlo Arenas Signed-off-by: Đoàn Trần Công Danh Signed-off-by: Junio C Hamano --- t/t4045-diff-relative.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 't') diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh index 7be1de736d..6afa3dffaa 100755 --- a/t/t4045-diff-relative.sh +++ b/t/t4045-diff-relative.sh @@ -162,4 +162,57 @@ check_diff_relative_option subdir file2 true --no-relative --relative check_diff_relative_option . file2 false --no-relative --relative=subdir check_diff_relative_option . file2 true --no-relative --relative=subdir +test_expect_success 'setup diff --relative unmerged' ' + test_commit zero file0 && + test_commit base subdir/file0 && + git switch -c br1 && + test_commit one file0 && + test_commit sub1 subdir/file0 && + git switch -c br2 base && + test_commit two file0 && + git switch -c br3 && + test_commit sub3 subdir/file0 +' + +test_expect_success 'diff --relative without change in subdir' ' + git switch br2 && + test_when_finished "git merge --abort" && + test_must_fail git merge one && + git -C subdir diff --relative >out && + test_must_be_empty out && + git -C subdir diff --relative --name-only >out && + test_must_be_empty out +' + +test_expect_success 'diff --relative --name-only with change in subdir' ' + git switch br3 && + test_when_finished "git merge --abort" && + test_must_fail git merge sub1 && + test_write_lines file0 file0 >expected && + git -C subdir diff --relative --name-only >out && + test_cmp expected out +' + +test_expect_failure 'diff --relative with change in subdir' ' + git switch br3 && + br1_blob=$(git rev-parse --short --verify br1:subdir/file0) && + br3_blob=$(git rev-parse --short --verify br3:subdir/file0) && + test_when_finished "git merge --abort" && + test_must_fail git merge br1 && + cat >expected <<-EOF && + diff --cc file0 + index $br3_blob,$br1_blob..0000000 + --- a/file0 + +++ b/file0 + @@@ -1,1 -1,1 +1,5 @@@ + ++<<<<<<< HEAD + +sub3 + ++======= + + sub1 + ++>>>>>>> br1 + EOF + git -C subdir diff --relative >out && + test_cmp expected out +' + test_done -- cgit v1.2.3 From c93ca46cf5d0b0cd22e357a6460fa84fd4633440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Wed, 18 Aug 2021 11:24:56 +0200 Subject: column: fix parsing of the '--nl' option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'git column's '--nl' option can be used to specify a "string to be printed at the end of each line" (quoting the man page), but this option and its mandatory argument has been parsed as OPT_INTEGER since the introduction of the command in 7e29b8254f (Add column layout skeleton and git-column, 2012-04-21). Consequently, any non-number argument is rejected by parse-options, and any number other than 0 leads to segfault: $ printf "%s\n" one two |git column --mode=plain --nl=foo error: option `nl' expects a numerical value $ printf "%s\n" one two |git column --mode=plain --nl=42 Segmentation fault (core dumped) $ printf "%s\n" one two |git column --mode=plain --nl=0 one two Parse this option as OPT_STRING. Signed-off-by: SZEDER Gábor Signed-off-by: Junio C Hamano --- t/t9002-column.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 't') diff --git a/t/t9002-column.sh b/t/t9002-column.sh index 89983527b6..6d3dbde3fe 100755 --- a/t/t9002-column.sh +++ b/t/t9002-column.sh @@ -42,6 +42,24 @@ EOF test_cmp expected actual ' +test_expect_success '--nl' ' + cat >expected <<\EOF && +oneZ +twoZ +threeZ +fourZ +fiveZ +sixZ +sevenZ +eightZ +nineZ +tenZ +elevenZ +EOF + git column --nl="Z$LF" --mode=plain actual && + test_cmp expected actual +' + test_expect_success '80 columns' ' cat >expected <<\EOF && one two three four five six seven eight nine ten eleven -- cgit v1.2.3 From 7a132c628e57b9bceeb88832ea051395c0637b16 Mon Sep 17 00:00:00 2001 From: Matheus Tavares Date: Thu, 26 Aug 2021 16:10:06 -0300 Subject: checkout: make delayed checkout respect --quiet and --no-progress The 'Filtering contents...' progress report from delayed checkout is displayed even when checkout and clone are invoked with --quiet or --no-progress. Furthermore, it is displayed unconditionally, without first checking whether stdout is a tty. Let's fix these issues and also add some regression tests for the two code paths that currently use delayed checkout: unpack_trees.c:check_updates() and builtin/checkout.c:checkout_worktree(). Signed-off-by: Matheus Tavares Signed-off-by: Junio C Hamano --- t/t0021-conversion.sh | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 't') diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index b5749f327d..33dfc9cd56 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -6,6 +6,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-terminal.sh TEST_ROOT="$PWD" PATH=$TEST_ROOT:$PATH @@ -1061,4 +1062,74 @@ test_expect_success PERL,SYMLINKS,CASE_INSENSITIVE_FS \ ) ' +test_expect_success PERL 'setup for progress tests' ' + git init progress && + ( + cd progress && + git config filter.delay.process "rot13-filter.pl delay-progress.log clean smudge delay" && + git config filter.delay.required true && + + echo "*.a filter=delay" >.gitattributes && + touch test-delay10.a && + git add . && + git commit -m files + ) +' + +test_delayed_checkout_progress () { + if test "$1" = "!" + then + local expect_progress=N && + shift + else + local expect_progress= + fi && + + if test $# -lt 1 + then + BUG "no command given to test_delayed_checkout_progress" + fi && + + ( + cd progress && + GIT_PROGRESS_DELAY=0 && + export GIT_PROGRESS_DELAY && + rm -f *.a delay-progress.log && + + "$@" 2>err && + grep "IN: smudge test-delay10.a .* \\[DELAYED\\]" delay-progress.log && + if test "$expect_progress" = N + then + ! grep "Filtering content" err + else + grep "Filtering content" err + fi + ) +} + +for mode in pathspec branch +do + case "$mode" in + pathspec) opt='.' ;; + branch) opt='-f HEAD' ;; + esac + + test_expect_success PERL,TTY "delayed checkout shows progress by default on tty ($mode checkout)" ' + test_delayed_checkout_progress test_terminal git checkout $opt + ' + + test_expect_success PERL "delayed checkout ommits progress on non-tty ($mode checkout)" ' + test_delayed_checkout_progress ! git checkout $opt + ' + + test_expect_success PERL,TTY "delayed checkout ommits progress with --quiet ($mode checkout)" ' + test_delayed_checkout_progress ! test_terminal git checkout --quiet $opt + ' + + test_expect_success PERL,TTY "delayed checkout honors --[no]-progress ($mode checkout)" ' + test_delayed_checkout_progress ! test_terminal git checkout --no-progress $opt && + test_delayed_checkout_progress test_terminal git checkout --quiet --progress $opt + ' +done + test_done -- cgit v1.2.3 From fd680bc5586ab7c846e03e181e033dbc36cc7d5d Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 27 Aug 2021 14:30:15 -0400 Subject: logmsg_reencode(): warn when iconv() fails If the user asks for a pretty-printed commit to be converted (either explicitly with --encoding=foo, or implicitly because the commit is non-utf8 and we want to convert it), we pass it through iconv(). If that fails, we fall back to showing the input verbatim, but don't tell the user that the output may be bogus. Let's add a warning to do so, along with a mention in the documentation for --encoding. Two things to note about the implementation: - we could produce the warning closer to the call to iconv() in reencode_string_len(), which would let us relay the value of errno. But this is not actually very helpful. reencode_string_len() does not know we are operating on a commit, and indeed does not know that the caller won't produce an error of its own. And the errno values from iconv() are seldom helpful (iconv_open() only ever produces EINVAL; perhaps EILSEQ from iconv() might be illuminating, but it can also return EINVAL for incomplete sequences). - if the reason for the failure is that the output charset is not supported, then the user will see this warning for every commit we try to display. That might be ugly and overwhelming, but on the other hand it is making it clear that every one of them has not been converted (and the likely outcome anyway is to re-try the command with a supported output encoding). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- t/t4210-log-i18n.sh | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 't') diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index d2dfcf164e..0141f36e33 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -131,4 +131,11 @@ do fi done +test_expect_success 'log shows warning when conversion fails' ' + enc=this-encoding-does-not-exist && + git log -1 --encoding=$enc 2>err && + echo "warning: unable to reencode commit to ${SQ}${enc}${SQ}" >expect && + test_cmp expect err +' + test_done -- cgit v1.2.3 From 597a97748924e8ce0b829f668acc8f7a6849b05f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Fri, 27 Aug 2021 20:35:35 +0200 Subject: branch: allow deleting dangling branches with --force MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git branch only allows deleting branches that point to valid commits. Skip that check if --force is given, as the caller is indicating with it that they know what they are doing and accept the consequences. This allows deleting dangling branches, which previously had to be reset to a valid start-point using --force first. Reported-by: Ulrich Windl Helped-by: Ævar Arnfjörð Bjarmason Helped-by: Junio C Hamano Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- t/t3200-branch.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 't') diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index cc4b10236e..e575ffb4ff 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -1272,6 +1272,19 @@ test_expect_success 'attempt to delete a branch merged to its base' ' test_must_fail git branch -d my10 ' +test_expect_success 'branch --delete --force removes dangling branch' ' + git checkout main && + test_commit unstable && + hash=$(git rev-parse HEAD) && + objpath=$(echo $hash | sed -e "s|^..|.git/objects/&/|") && + git branch --no-track dangling && + mv $objpath $objpath.x && + test_when_finished "mv $objpath.x $objpath" && + git branch --delete --force dangling && + git for-each-ref refs/heads/dangling >actual && + test_must_be_empty actual +' + test_expect_success 'use --edit-description' ' write_script editor <<-\EOF && echo "New contents" >"$1" -- cgit v1.2.3 From 614c3d8f2e330baedfdb09fc90803a4c360d39cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Sun, 29 Aug 2021 11:25:36 +0200 Subject: test-lib: set GIT_CEILING_DIRECTORIES to protect the surrounding repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every once in a while a test somehow manages to escape from its trash directory and modifies the surrounding repository, whether because of a bug in git itself, a bug in a test [1], or e.g. when trying to run tests with a shell that is, in general, unable to run our tests [2]. Set GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/.." as an additional safety measure to protect the surrounding repository at least from modifications by git commands executed in the tests (assuming that handling of ceiling directories during repository discovery is not broken, and, of course, it won't save us from regular shell commands, e.g. 'cd .. && rm -f ...'). [1] e.g. https://public-inbox.org/git/20210423051255.GD2947267@szeder.dev [2] $ git symbolic-ref HEAD refs/heads/master $ ksh ./t2011-checkout-invalid-head.sh [... a lot of "not ok" ...] $ git symbolic-ref HEAD refs/heads/other (In short: 'ksh' doesn't support the 'local' builtin command, which is used by 'test_oid', causing it to return with error whenever it's called, leaving ZERO_OID set to empty, so when the test 'checkout main from invalid HEAD' runs 'echo $ZERO_OID >.git/HEAD' it writes a corrupt (not invalid) HEAD, and subsequent git commands don't recognize the repository in the trash directory anymore, but operate on the surrounding repo.) Signed-off-by: SZEDER Gábor Signed-off-by: Junio C Hamano --- t/test-lib.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/test-lib.sh b/t/test-lib.sh index abcfbed6d6..fc1e521519 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1343,7 +1343,8 @@ fi GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt GIT_CONFIG_NOSYSTEM=1 GIT_ATTR_NOSYSTEM=1 -export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM +GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/.." +export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM GIT_CEILING_DIRECTORIES if test -z "$GIT_TEST_CMP" then -- cgit v1.2.3 From e0821134846b10952efc0737b9e32ca8226f0a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20H=C3=A4user?= Date: Mon, 30 Aug 2021 15:30:01 +0000 Subject: send-email: avoid incorrect header propagation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If multiple independent patches are sent with send-email, even if the "In-Reply-To" and "References" headers are not managed by --thread or --in-reply-to, their values may be propagated from prior patches to subsequent patches with no such headers defined. To mitigate this and potential future issues, make sure all global patch-specific variables are always either handled by command-specific code (e.g. threading), or are reset to their default values for every iteration. Signed-off-by: Jeff King Signed-off-by: Marvin Häuser Signed-off-by: Junio C Hamano --- t/t9001-send-email.sh | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 't') diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 4eee9c3dcb..35be6b0190 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -2097,6 +2097,51 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' ' test_cmp expected-list actual-list ' +test_expect_success $PREREQ 'set up in-reply-to/references patches' ' + cat >has-reply.patch <<-\EOF && + From: A U Thor + Subject: patch with in-reply-to + Message-ID: + In-Reply-To: + References: + + This is the body. + EOF + cat >no-reply.patch <<-\EOF + From: A U Thor + Subject: patch without in-reply-to + Message-ID: + + This is the body. + EOF +' + +test_expect_success $PREREQ 'patch reply headers correct with --no-thread' ' + clean_fake_sendmail && + git send-email \ + --no-thread \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + has-reply.patch no-reply.patch && + grep "In-Reply-To: " msgtxt1 && + grep "References: " msgtxt1 && + ! grep replied.to@example.com msgtxt2 +' + +test_expect_success $PREREQ 'cmdline in-reply-to used with --no-thread' ' + clean_fake_sendmail && + git send-email \ + --no-thread \ + --in-reply-to="" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + has-reply.patch no-reply.patch && + grep "In-Reply-To: " msgtxt1 && + grep "References: " msgtxt1 && + grep "In-Reply-To: " msgtxt2 && + grep "References: " msgtxt2 +' + test_expect_success $PREREQ 'invoke hook' ' mkdir -p .git/hooks && -- cgit v1.2.3 From 48072e3d68049a6bbb4f99f3a381e8b7f3647c52 Mon Sep 17 00:00:00 2001 From: Mahi Kolla Date: Sat, 14 Aug 2021 01:09:56 +0000 Subject: clone: set submodule.recurse=true if submodule.stickyRecursiveClone enabled Based on current experience, when running git clone --recurse-submodules, developers do not expect other commands such as pull or checkout to run recursively into active submodules. However, setting submodule.recurse=true at this step could make for a simpler workflow by eliminating the need for the --recurse-submodules option in subsequent commands. To collect more data on developers' preference in regards to making submodule.recurse=true a default config value in the future, deploy this feature under the opt in submodule.stickyRecursiveClone flag. Signed-off-by: Mahi Kolla Signed-off-by: Junio C Hamano --- t/t5606-clone-options.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 't') diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh index 3a595c0f82..d822153e4d 100755 --- a/t/t5606-clone-options.sh +++ b/t/t5606-clone-options.sh @@ -16,6 +16,18 @@ test_expect_success 'setup' ' ' +test_expect_success 'submodule.stickyRecursiveClone flag manipulates submodule.recurse value' ' + + test_config_global submodule.stickyRecursiveClone true && + git clone --recurse-submodules parent clone_recurse_true && + test_cmp_config -C clone_recurse_true true submodule.recurse && + + test_config_global submodule.stickyRecursiveClone false && + git clone --recurse-submodules parent clone_recurse_false && + test_expect_code 1 git -C clone_recurse_false config --get submodule.recurse + +' + test_expect_success 'clone -o' ' git clone -o foo parent clone-o && -- cgit v1.2.3 From 6d209a01f89fd27d42e0a74a5ada29cef1dcac29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Mon, 23 Aug 2021 14:30:20 +0200 Subject: commit-graph: show usage on "commit-graph [write|verify] garbage" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the parse_options() invocation in the commit-graph code to error on unknown leftover argv elements, in addition to the existing and implicit erroring via parse_options() on unknown options. We'd already error in cmd_commit_graph() on e.g.: git commit-graph unknown verify git commit-graph --unknown verify But here we're calling parse_options() twice more for the "write" and "verify" subcommands. We did not do the same checking for leftover argv elements there. As a result we'd silently accept garbage in these subcommands, let's not do that. Signed-off-by: Ævar Arnfjörð Bjarmason Reviewed-by: Taylor Blau Signed-off-by: Junio C Hamano --- t/t5318-commit-graph.sh | 5 +++++ 1 file changed, 5 insertions(+) (limited to 't') diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index af88f805aa..09a2ccd292 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -5,6 +5,11 @@ test_description='commit graph' GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0 +test_expect_success 'usage' ' + test_expect_code 129 git commit-graph write blah && + test_expect_code 129 git commit-graph write verify +' + test_expect_success 'setup full repo' ' mkdir full && cd "$TRASH_DIRECTORY/full" && -- cgit v1.2.3 From 367c5f36a6a0fa7f8f706b10f9bb2f0e28baaa1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Mon, 23 Aug 2021 14:30:21 +0200 Subject: commit-graph: show "unexpected subcommand" error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring the "commit-graph" command in line with the error output and general pattern in cmd_multi_pack_index(). Let's test for that output, and also cover the same potential bug as was fixed in the multi-pack-index command in 88617d11f9d (multi-pack-index: fix potential segfault without sub-command, 2021-07-19). Signed-off-by: Ævar Arnfjörð Bjarmason Reviewed-by: Taylor Blau Signed-off-by: Junio C Hamano --- t/t5318-commit-graph.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 09a2ccd292..295c5bd94d 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -6,10 +6,24 @@ test_description='commit graph' GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0 test_expect_success 'usage' ' - test_expect_code 129 git commit-graph write blah && + test_expect_code 129 git commit-graph write blah 2>err && test_expect_code 129 git commit-graph write verify ' +test_expect_success 'usage shown without sub-command' ' + test_expect_code 129 git commit-graph 2>err && + ! grep error: err +' + +test_expect_success 'usage shown with an error on unknown sub-command' ' + cat >expect <<-\EOF && + error: unrecognized subcommand: unknown + EOF + test_expect_code 129 git commit-graph unknown 2>stderr && + grep error stderr >actual && + test_cmp expect actual +' + test_expect_success 'setup full repo' ' mkdir full && cd "$TRASH_DIRECTORY/full" && -- cgit v1.2.3 From f1c0368da4d64f394e4c099cb3c232671040d725 Mon Sep 17 00:00:00 2001 From: David Turner Date: Tue, 31 Aug 2021 09:12:56 -0400 Subject: diff --submodule=diff: do not fail on ever-initialied deleted submodules If you have ever initialized a submodule, open_submodule will open it. If you then delete the submodule's worktree directory (but don't remove it from .gitmodules), git diff --submodule=diff would error out as it attempted to chdir into the now-deleted working tree directory. This only matters if the submodules git dir is absorbed. If not, then we no longer have anywhere to run the diff. But that case does not trigger this error, because in that case, open_submodule fails, so we don't resolve a left commit, so we exit early, which is the only thing we could do. If absorbed, then we can run the diff from the submodule's absorbed git dir (.git/modules/sm2). In practice, that's a bit more complicated, because `git diff` expects to be run from inside a working directory, not a git dir. So it looks in the config for core.worktree, and does chdir("../../../sm2"), which is the very dir that we're trying to avoid visiting because it's been deleted. We work around this by setting GIT_WORK_TREE (and GIT_DIR) to ".". It is little weird to set GIT_WORK_TREE to something that is not a working tree just to avoid an unnecessary chdir, but it works. Signed-off-by: David Turner --- t/t4060-diff-submodule-option-diff-format.sh | 158 +++++++++++++++++++++++++-- 1 file changed, 151 insertions(+), 7 deletions(-) (limited to 't') diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh index 69b9946931..d86e38abd8 100755 --- a/t/t4060-diff-submodule-option-diff-format.sh +++ b/t/t4060-diff-submodule-option-diff-format.sh @@ -703,10 +703,26 @@ test_expect_success 'path filter' ' diff_cmp expected actual ' -commit_file sm2 +cat >.gitmodules <<-EOF +[submodule "sm2"] + path = sm2 + url = bogus_url +EOF +git add .gitmodules +commit_file sm2 .gitmodules + test_expect_success 'given commit' ' git diff-index -p --submodule=diff HEAD^ >actual && cat >expected <<-EOF && + diff --git a/.gitmodules b/.gitmodules + new file mode 100644 + index 1234567..89abcde + --- /dev/null + +++ b/.gitmodules + @@ -0,0 +1,3 @@ + +[submodule "sm2"] + +path = sm2 + +url = bogus_url Submodule sm1 $head7...0000000 (submodule deleted) Submodule sm2 0000000...$head9 (new submodule) diff --git a/sm2/foo8 b/sm2/foo8 @@ -728,15 +744,21 @@ test_expect_success 'given commit' ' ' test_expect_success 'setup .git file for sm2' ' - (cd sm2 && - REAL="$(pwd)/../.real" && - mv .git "$REAL" && - echo "gitdir: $REAL" >.git) + git submodule absorbgitdirs sm2 ' test_expect_success 'diff --submodule=diff with .git file' ' git diff --submodule=diff HEAD^ >actual && cat >expected <<-EOF && + diff --git a/.gitmodules b/.gitmodules + new file mode 100644 + index 1234567..89abcde + --- /dev/null + +++ b/.gitmodules + @@ -0,0 +1,3 @@ + +[submodule "sm2"] + +path = sm2 + +url = bogus_url Submodule sm1 $head7...0000000 (submodule deleted) Submodule sm2 0000000...$head9 (new submodule) diff --git a/sm2/foo8 b/sm2/foo8 @@ -757,9 +779,67 @@ test_expect_success 'diff --submodule=diff with .git file' ' diff_cmp expected actual ' +mv sm2 sm2-bak + +test_expect_success 'deleted submodule with .git file' ' + git diff-index -p --submodule=diff HEAD >actual && + cat >expected <<-EOF && + Submodule sm1 $head7...0000000 (submodule deleted) + Submodule sm2 $head9...0000000 (submodule deleted) + diff --git a/sm2/foo8 b/sm2/foo8 + deleted file mode 100644 + index 1234567..89abcde + --- a/sm2/foo8 + +++ /dev/null + @@ -1 +0,0 @@ + -foo8 + diff --git a/sm2/foo9 b/sm2/foo9 + deleted file mode 100644 + index 1234567..89abcde + --- a/sm2/foo9 + +++ /dev/null + @@ -1 +0,0 @@ + -foo9 + EOF + diff_cmp expected actual +' + +echo submodule-to-blob>sm2 + +test_expect_success 'typechanged(submodule->blob) submodule with .git file' ' + git diff-index -p --submodule=diff HEAD >actual && + cat >expected <<-EOF && + Submodule sm1 $head7...0000000 (submodule deleted) + Submodule sm2 $head9...0000000 (submodule deleted) + diff --git a/sm2/foo8 b/sm2/foo8 + deleted file mode 100644 + index 1234567..89abcde + --- a/sm2/foo8 + +++ /dev/null + @@ -1 +0,0 @@ + -foo8 + diff --git a/sm2/foo9 b/sm2/foo9 + deleted file mode 100644 + index 1234567..89abcde + --- a/sm2/foo9 + +++ /dev/null + @@ -1 +0,0 @@ + -foo9 + diff --git a/sm2 b/sm2 + new file mode 100644 + index 1234567..89abcde + --- /dev/null + +++ b/sm2 + @@ -0,0 +1 @@ + +submodule-to-blob + EOF + diff_cmp expected actual +' + +rm sm2 +mv sm2-bak sm2 + test_expect_success 'setup nested submodule' ' - git submodule add -f ./sm2 && - git commit -a -m "add sm2" && git -C sm2 submodule add ../sm2 nested && git -C sm2 commit -a -m "nested sub" && head10=$(git -C sm2 rev-parse --short --verify HEAD) @@ -790,6 +870,7 @@ test_expect_success 'diff --submodule=diff with moved nested submodule HEAD' ' test_expect_success 'diff --submodule=diff recurses into nested submodules' ' cat >expected <<-EOF && + Submodule sm1 $head7...0000000 (submodule deleted) Submodule sm2 contains modified content Submodule sm2 $head9..$head10: diff --git a/sm2/.gitmodules b/sm2/.gitmodules @@ -829,4 +910,67 @@ test_expect_success 'diff --submodule=diff recurses into nested submodules' ' diff_cmp expected actual ' +(cd sm2; commit_file nested) +commit_file sm2 +head12=$(cd sm2; git rev-parse --short --verify HEAD) + +mv sm2 sm2-bak + +test_expect_success 'diff --submodule=diff recurses into deleted nested submodules' ' + cat >expected <<-EOF && + Submodule sm1 $head7...0000000 (submodule deleted) + Submodule sm2 $head12...0000000 (submodule deleted) + diff --git a/sm2/.gitmodules b/sm2/.gitmodules + deleted file mode 100644 + index 3a816b8..0000000 + --- a/sm2/.gitmodules + +++ /dev/null + @@ -1,3 +0,0 @@ + -[submodule "nested"] + - path = nested + - url = ../sm2 + diff --git a/sm2/foo8 b/sm2/foo8 + deleted file mode 100644 + index db9916b..0000000 + --- a/sm2/foo8 + +++ /dev/null + @@ -1 +0,0 @@ + -foo8 + diff --git a/sm2/foo9 b/sm2/foo9 + deleted file mode 100644 + index 9c3b4f6..0000000 + --- a/sm2/foo9 + +++ /dev/null + @@ -1 +0,0 @@ + -foo9 + Submodule nested $head11...0000000 (submodule deleted) + diff --git a/sm2/nested/file b/sm2/nested/file + deleted file mode 100644 + index ca281f5..0000000 + --- a/sm2/nested/file + +++ /dev/null + @@ -1 +0,0 @@ + -nested content + diff --git a/sm2/nested/foo8 b/sm2/nested/foo8 + deleted file mode 100644 + index db9916b..0000000 + --- a/sm2/nested/foo8 + +++ /dev/null + @@ -1 +0,0 @@ + -foo8 + diff --git a/sm2/nested/foo9 b/sm2/nested/foo9 + deleted file mode 100644 + index 9c3b4f6..0000000 + --- a/sm2/nested/foo9 + +++ /dev/null + @@ -1 +0,0 @@ + -foo9 + EOF + git diff --submodule=diff >actual 2>err && + test_must_be_empty err && + diff_cmp expected actual +' + +mv sm2-bak sm2 + test_done -- cgit v1.2.3 From 2f040a96711aaa576ce983b962b4e92abfa238b4 Mon Sep 17 00:00:00 2001 From: Tal Kelrich Date: Tue, 31 Aug 2021 15:55:54 +0000 Subject: fast-export: fix anonymized tag using original length Commit 7f4075949686 (fast-export: tighten anonymize_mem() interface to handle only strings, 2020-06-23) changed the interface used in anonymizing strings, but failed to update the size of annotated tag messages to match the new anonymized string. As a result, exporting tags having messages longer than 13 characters would create output that couldn't be parsed by fast-import, as the data length indicated was larger than the data output. Reset the message size when anonymizing, and add a tag with a "long" message to the test. Signed-off-by: Tal Kelrich Signed-off-by: Junio C Hamano --- t/t9351-fast-export-anonymize.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 't') diff --git a/t/t9351-fast-export-anonymize.sh b/t/t9351-fast-export-anonymize.sh index 1c6e6fcdaf..77047e250d 100755 --- a/t/t9351-fast-export-anonymize.sh +++ b/t/t9351-fast-export-anonymize.sh @@ -18,7 +18,8 @@ test_expect_success 'setup simple repo' ' git update-index --add --cacheinfo 160000,$fake_commit,link1 && git update-index --add --cacheinfo 160000,$fake_commit,link2 && git commit -m "add gitlink" && - git tag -m "annotated tag" mytag + git tag -m "annotated tag" mytag && + git tag -m "annotated tag with long message" longtag ' test_expect_success 'export anonymized stream' ' @@ -55,7 +56,8 @@ test_expect_success 'stream retains other as refname' ' test_expect_success 'stream omits other refnames' ' ! grep main stream && - ! grep mytag stream + ! grep mytag stream && + ! grep longtag stream ' test_expect_success 'stream omits identities' ' @@ -118,9 +120,9 @@ test_expect_success 'identical gitlinks got identical oid' ' test_line_count = 1 commits ' -test_expect_success 'tag points to branch tip' ' +test_expect_success 'all tags point to branch tip' ' git rev-parse $other_branch >expect && - git for-each-ref --format="%(*objectname)" | grep . >actual && + git for-each-ref --format="%(*objectname)" | grep . | uniq >actual && test_cmp expect actual ' -- cgit v1.2.3 From 2c7f3aacd31b564beca3a3d93a98f4efded6af58 Mon Sep 17 00:00:00 2001 From: USAMI Kenta Date: Tue, 31 Aug 2021 06:01:25 +0000 Subject: userdiff: support enum keyword in PHP hunk header "enum" keyword will be introduced in PHP 8.1. https://wiki.php.net/rfc/enumerations Signed-off-by: USAMI Kenta Signed-off-by: Junio C Hamano --- t/t4018/php-enum | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 t/t4018/php-enum (limited to 't') diff --git a/t/t4018/php-enum b/t/t4018/php-enum new file mode 100644 index 0000000000..91a69c1a2b --- /dev/null +++ b/t/t4018/php-enum @@ -0,0 +1,4 @@ +enum RIGHT: string +{ + case Foo = 'ChangeMe'; +} -- cgit v1.2.3 From bac01c6469b2489042b867d409894a3152ec98a1 Mon Sep 17 00:00:00 2001 From: Kim Altintop Date: Fri, 13 Aug 2021 06:23:40 +0000 Subject: t5730: introduce fetch command helper Assembling a "raw" fetch command to be fed directly to "test-tool serve-v2" is extracted into a test helper. Suggested-by: Junio C Hamano Signed-off-by: Kim Altintop Reviewed-by: Jonathan Tan Signed-off-by: Junio C Hamano --- t/t5703-upload-pack-ref-in-want.sh | 73 +++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 36 deletions(-) (limited to 't') diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index e9e471621d..3dad21ff45 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -40,6 +40,30 @@ write_command () { fi } +# Write a complete fetch command to stdout, suitable for use with `test-tool +# pkt-line`. "want-ref", "want", and "have" lines are read from stdin. +# +# Examples: +# +# write_fetch_command <<-EOF +# want-ref refs/heads/main +# have $(git rev-parse a) +# EOF +# +# write_fetch_command <<-EOF +# want $(git rev-parse b) +# have $(git rev-parse a) +# EOF +# +write_fetch_command () { + write_command fetch && + echo "0001" && + echo "no-progress" && + cat && + echo "done" && + echo "0000" +} + # c(o/foo) d(o/bar) # \ / # b e(baz) f(main) @@ -77,15 +101,11 @@ test_expect_success 'config controls ref-in-want advertisement' ' ' test_expect_success 'invalid want-ref line' ' - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/non-existent - done - 0000 EOF + test-tool pkt-line pack in && test_must_fail test-tool serve-v2 --stateless-rpc 2>out expected_commits && - oid=$(git rev-parse a) && - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/main - have $oid - done - 0000 + have $(git rev-parse a) EOF + test-tool pkt-line pack in && test-tool serve-v2 --stateless-rpc >out expected_commits && - oid=$(git rev-parse b) && - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/o/foo want-ref refs/heads/o/bar - have $oid - done - 0000 + have $(git rev-parse b) EOF + test-tool pkt-line pack in && test-tool serve-v2 --stateless-rpc >out expected_commits && - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/main want $(git rev-parse e) have $(git rev-parse a) - done - 0000 EOF + test-tool pkt-line pack in && test-tool serve-v2 --stateless-rpc >out expected_commits && - oid=$(git rev-parse c) && - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/o/foo - have $oid - done - 0000 + have $(git rev-parse c) EOF + test-tool pkt-line pack in && test-tool serve-v2 --stateless-rpc >out Date: Fri, 13 Aug 2021 06:23:50 +0000 Subject: upload-pack.c: treat want-ref relative to namespace When 'upload-pack' runs within the context of a git namespace, treat any 'want-ref' lines the client sends as relative to that namespace. Also check if the wanted ref is hidden via 'hideRefs'. If it is hidden, respond with an error as if the ref didn't exist. Helped-by: Jonathan Tan Signed-off-by: Kim Altintop Reviewed-by: Jonathan Tan Signed-off-by: Junio C Hamano --- t/t5703-upload-pack-ref-in-want.sh | 135 +++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) (limited to 't') diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index 3dad21ff45..220098523a 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -299,6 +299,141 @@ test_expect_success 'fetching with wildcard that matches multiple refs' ' grep "want-ref refs/heads/o/bar" log ' +REPO="$(pwd)/repo-ns" + +test_expect_success 'setup namespaced repo' ' + ( + git init -b main "$REPO" && + cd "$REPO" && + test_commit a && + test_commit b && + git checkout a && + test_commit c && + git checkout a && + test_commit d && + git update-ref refs/heads/ns-no b && + git update-ref refs/namespaces/ns/refs/heads/ns-yes c && + git update-ref refs/namespaces/ns/refs/heads/hidden d + ) && + git -C "$REPO" config uploadpack.allowRefInWant true +' + +test_expect_success 'with namespace: want-ref is considered relative to namespace' ' + wanted_ref=refs/heads/ns-yes && + + oid=$(git -C "$REPO" rev-parse "refs/namespaces/ns/$wanted_ref") && + cat >expected_refs <<-EOF && + $oid $wanted_ref + EOF + cat >expected_commits <<-EOF && + $oid + $(git -C "$REPO" rev-parse a) + EOF + + write_fetch_command >pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack in && + + GIT_NAMESPACE=ns test-tool -C "$REPO" serve-v2 --stateless-rpc >out pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack in && + + test_must_fail env GIT_NAMESPACE=ns \ + test-tool -C "$REPO" serve-v2 --stateless-rpc >out expected_refs <<-EOF && + $oid $wanted_ref + EOF + cat >expected_commits <<-EOF && + $oid + $(git -C "$REPO" rev-parse a) + EOF + + write_fetch_command >pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack in && + + test-tool -C "$REPO" serve-v2 --stateless-rpc >out pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack in && + + test_must_fail env GIT_NAMESPACE=ns \ + test-tool -C "$REPO" serve-v2 --stateless-rpc >out