summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2023-05-15 13:59:07 -0700
committerJunio C Hamano <gitster@pobox.com>2023-05-15 13:59:07 -0700
commit15ba44f1b4c307d8b2a7810232d902720f039892 (patch)
treee5d47ce69704aefa0d07a14ca1e652a391e47429 /t
parentef06676c3646271e505c255372b667568faf88f8 (diff)
parentdd781e3856bccd3793122f7f4e604e5a89ae517d (diff)
downloadgit-15ba44f1b4c307d8b2a7810232d902720f039892.tar.gz
Merge branch 'ps/fetch-output-format'
"git fetch" learned the "--porcelain" option that emits what it did in a machine-parseable format. * ps/fetch-output-format: fetch: introduce machine-parseable "porcelain" output format fetch: move option related variables into main function fetch: lift up parsing of "fetch.output" config variable fetch: introduce `display_format` enum fetch: refactor calculation of the display table width fetch: print left-hand side when fetching HEAD:foo fetch: add a test to exercise invalid output formats fetch: split out tests for output format fetch: fix `--no-recurse-submodules` with multi-remote fetches
Diffstat (limited to 't')
-rwxr-xr-xt/t5510-fetch.sh53
-rwxr-xr-xt/t5526-fetch-submodules.sh13
-rwxr-xr-xt/t5574-fetch-output.sh293
3 files changed, 306 insertions, 53 deletions
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index dc44da9c79..4f289063ce 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -1118,59 +1118,6 @@ test_expect_success 'fetching with auto-gc does not lock up' '
)
'
-test_expect_success 'fetch aligned output' '
- git clone . full-output &&
- test_commit looooooooooooong-tag &&
- (
- cd full-output &&
- git -c fetch.output=full fetch origin >actual 2>&1 &&
- grep -e "->" actual | cut -c 22- >../actual
- ) &&
- cat >expect <<-\EOF &&
- main -> origin/main
- looooooooooooong-tag -> looooooooooooong-tag
- EOF
- test_cmp expect actual
-'
-
-test_expect_success 'fetch compact output' '
- git clone . compact &&
- test_commit extraaa &&
- (
- cd compact &&
- git -c fetch.output=compact fetch origin >actual 2>&1 &&
- grep -e "->" actual | cut -c 22- >../actual
- ) &&
- cat >expect <<-\EOF &&
- main -> origin/*
- extraaa -> *
- EOF
- test_cmp expect actual
-'
-
-test_expect_success '--no-show-forced-updates' '
- mkdir forced-updates &&
- (
- cd forced-updates &&
- git init &&
- test_commit 1 &&
- test_commit 2
- ) &&
- git clone forced-updates forced-update-clone &&
- git clone forced-updates no-forced-update-clone &&
- git -C forced-updates reset --hard HEAD~1 &&
- (
- cd forced-update-clone &&
- git fetch --show-forced-updates origin 2>output &&
- test_i18ngrep "(forced update)" output
- ) &&
- (
- cd no-forced-update-clone &&
- git fetch --no-show-forced-updates origin 2>output &&
- test_i18ngrep ! "(forced update)" output
- )
-'
-
for section in fetch transfer
do
test_expect_success "$section.hideRefs affects connectivity check" '
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index dcdbe26a08..26e933f93a 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -1180,4 +1180,17 @@ test_expect_success 'fetch --all with --recurse-submodules with multiple' '
test_line_count = 2 fetch-subs
'
+test_expect_success "fetch --all with --no-recurse-submodules only fetches superproject" '
+ test_when_finished "rm -rf src_clone" &&
+
+ git clone --recurse-submodules src src_clone &&
+ (
+ cd src_clone &&
+ git remote add secondary ../src &&
+ git config submodule.recurse true &&
+ git fetch --all --no-recurse-submodules 2>../fetch-log
+ ) &&
+ ! grep "Fetching submodule" fetch-log
+'
+
test_done
diff --git a/t/t5574-fetch-output.sh b/t/t5574-fetch-output.sh
new file mode 100755
index 0000000000..90e6dcb9a7
--- /dev/null
+++ b/t/t5574-fetch-output.sh
@@ -0,0 +1,293 @@
+#!/bin/sh
+
+test_description='git fetch output format'
+
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+
+. ./test-lib.sh
+
+test_expect_success 'fetch with invalid output format configuration' '
+ test_when_finished "rm -rf clone" &&
+ git clone . clone &&
+
+ test_must_fail git -C clone -c fetch.output fetch origin 2>actual.err &&
+ cat >expect <<-EOF &&
+ error: missing value for ${SQ}fetch.output${SQ}
+ fatal: unable to parse ${SQ}fetch.output${SQ} from command-line config
+ EOF
+ test_cmp expect actual.err &&
+
+ test_must_fail git -C clone -c fetch.output= fetch origin 2>actual.err &&
+ cat >expect <<-EOF &&
+ fatal: invalid value for ${SQ}fetch.output${SQ}: ${SQ}${SQ}
+ EOF
+ test_cmp expect actual.err &&
+
+ test_must_fail git -C clone -c fetch.output=garbage fetch origin 2>actual.err &&
+ cat >expect <<-EOF &&
+ fatal: invalid value for ${SQ}fetch.output${SQ}: ${SQ}garbage${SQ}
+ EOF
+ test_cmp expect actual.err
+'
+
+test_expect_success 'fetch aligned output' '
+ git clone . full-output &&
+ test_commit looooooooooooong-tag &&
+ (
+ cd full-output &&
+ git -c fetch.output=full fetch origin >actual 2>&1 &&
+ grep -e "->" actual | cut -c 22- >../actual
+ ) &&
+ cat >expect <<-\EOF &&
+ main -> origin/main
+ looooooooooooong-tag -> looooooooooooong-tag
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'fetch compact output' '
+ git clone . compact &&
+ test_commit extraaa &&
+ (
+ cd compact &&
+ git -c fetch.output=compact fetch origin >actual 2>&1 &&
+ grep -e "->" actual | cut -c 22- >../actual
+ ) &&
+ cat >expect <<-\EOF &&
+ main -> origin/*
+ extraaa -> *
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'fetch porcelain output' '
+ test_when_finished "rm -rf porcelain" &&
+
+ # Set up a bunch of references that we can use to demonstrate different
+ # kinds of flag symbols in the output format.
+ MAIN_OLD=$(git rev-parse HEAD) &&
+ git branch "fast-forward" &&
+ git branch "deleted-branch" &&
+ git checkout -b force-updated &&
+ test_commit --no-tag force-update-old &&
+ FORCE_UPDATED_OLD=$(git rev-parse HEAD) &&
+ git checkout main &&
+
+ # Clone and pre-seed the repositories. We fetch references into two
+ # namespaces so that we can test that rejected and force-updated
+ # references are reported properly.
+ refspecs="refs/heads/*:refs/unforced/* +refs/heads/*:refs/forced/*" &&
+ git clone . porcelain &&
+ git -C porcelain fetch origin $refspecs &&
+
+ # Now that we have set up the client repositories we can change our
+ # local references.
+ git branch new-branch &&
+ git branch -d deleted-branch &&
+ git checkout fast-forward &&
+ test_commit --no-tag fast-forward-new &&
+ FAST_FORWARD_NEW=$(git rev-parse HEAD) &&
+ git checkout force-updated &&
+ git reset --hard HEAD~ &&
+ test_commit --no-tag force-update-new &&
+ FORCE_UPDATED_NEW=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ - $MAIN_OLD $ZERO_OID refs/forced/deleted-branch
+ - $MAIN_OLD $ZERO_OID refs/unforced/deleted-branch
+ $MAIN_OLD $FAST_FORWARD_NEW refs/unforced/fast-forward
+ ! $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/unforced/force-updated
+ * $ZERO_OID $MAIN_OLD refs/unforced/new-branch
+ $MAIN_OLD $FAST_FORWARD_NEW refs/forced/fast-forward
+ + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/forced/force-updated
+ * $ZERO_OID $MAIN_OLD refs/forced/new-branch
+ $MAIN_OLD $FAST_FORWARD_NEW refs/remotes/origin/fast-forward
+ + $FORCE_UPDATED_OLD $FORCE_UPDATED_NEW refs/remotes/origin/force-updated
+ * $ZERO_OID $MAIN_OLD refs/remotes/origin/new-branch
+ EOF
+
+ # Execute a dry-run fetch first. We do this to assert that the dry-run
+ # and non-dry-run fetches produces the same output. Execution of the
+ # fetch is expected to fail as we have a rejected reference update.
+ test_must_fail git -C porcelain fetch \
+ --porcelain --dry-run --prune origin $refspecs >actual &&
+ test_cmp expect actual &&
+
+ # And now we perform a non-dry-run fetch.
+ test_must_fail git -C porcelain fetch \
+ --porcelain --prune origin $refspecs >actual 2>stderr &&
+ test_cmp expect actual &&
+ test_must_be_empty stderr
+'
+
+test_expect_success 'fetch porcelain with multiple remotes' '
+ test_when_finished "rm -rf porcelain" &&
+
+ git switch --create multiple-remotes &&
+ git clone . porcelain &&
+ git -C porcelain remote add second-remote "$PWD" &&
+ git -C porcelain fetch second-remote &&
+
+ test_commit --no-tag multi-commit &&
+ old_commit=$(git rev-parse HEAD~) &&
+ new_commit=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ $old_commit $new_commit refs/remotes/origin/multiple-remotes
+ $old_commit $new_commit refs/remotes/second-remote/multiple-remotes
+ EOF
+
+ git -C porcelain fetch --porcelain --all >actual 2>stderr &&
+ test_cmp expect actual &&
+ test_must_be_empty stderr
+'
+
+test_expect_success 'fetch porcelain refuses to work with submodules' '
+ test_when_finished "rm -rf porcelain" &&
+
+ cat >expect <<-EOF &&
+ fatal: options ${SQ}--porcelain${SQ} and ${SQ}--recurse-submodules${SQ} cannot be used together
+ EOF
+
+ git init porcelain &&
+ test_must_fail git -C porcelain fetch --porcelain --recurse-submodules=yes 2>stderr &&
+ test_cmp expect stderr &&
+
+ test_must_fail git -C porcelain fetch --porcelain --recurse-submodules=on-demand 2>stderr &&
+ test_cmp expect stderr
+'
+
+test_expect_success 'fetch porcelain overrides fetch.output config' '
+ test_when_finished "rm -rf porcelain" &&
+
+ git switch --create config-override &&
+ git clone . porcelain &&
+ test_commit new-commit &&
+ old_commit=$(git rev-parse HEAD~) &&
+ new_commit=$(git rev-parse HEAD) &&
+
+ cat >expect <<-EOF &&
+ $old_commit $new_commit refs/remotes/origin/config-override
+ * $ZERO_OID $new_commit refs/tags/new-commit
+ EOF
+
+ git -C porcelain -c fetch.output=compact fetch --porcelain >stdout 2>stderr &&
+ test_must_be_empty stderr &&
+ test_cmp expect stdout
+'
+
+test_expect_success 'fetch --no-porcelain overrides previous --porcelain' '
+ test_when_finished "rm -rf no-porcelain" &&
+
+ git switch --create no-porcelain &&
+ git clone . no-porcelain &&
+ test_commit --no-tag no-porcelain &&
+ old_commit=$(git rev-parse --short HEAD~) &&
+ new_commit=$(git rev-parse --short HEAD) &&
+
+ cat >expect <<-EOF &&
+ From $(test-tool path-utils real_path .)/.
+ $old_commit..$new_commit no-porcelain -> origin/no-porcelain
+ EOF
+
+ git -C no-porcelain fetch --porcelain --no-porcelain >stdout 2>stderr &&
+ test_cmp expect stderr &&
+ test_must_be_empty stdout
+'
+
+test_expect_success 'fetch output with HEAD' '
+ test_when_finished "rm -rf head" &&
+ git clone . head &&
+
+ git -C head fetch --dry-run origin HEAD >actual.out 2>actual.err &&
+ cat >expect <<-EOF &&
+ From $(test-tool path-utils real_path .)/.
+ * branch HEAD -> FETCH_HEAD
+ EOF
+ test_must_be_empty actual.out &&
+ test_cmp expect actual.err &&
+
+ git -C head fetch origin HEAD >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_cmp expect actual.err &&
+
+ git -C head fetch --dry-run origin HEAD:foo >actual.out 2>actual.err &&
+ cat >expect <<-EOF &&
+ From $(test-tool path-utils real_path .)/.
+ * [new ref] HEAD -> foo
+ EOF
+ test_must_be_empty actual.out &&
+ test_cmp expect actual.err &&
+
+ git -C head fetch origin HEAD:foo >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_cmp expect actual.err
+'
+
+test_expect_success 'fetch porcelain output with HEAD' '
+ test_when_finished "rm -rf head" &&
+ git clone . head &&
+ COMMIT_ID=$(git rev-parse HEAD) &&
+
+ git -C head fetch --porcelain --dry-run origin HEAD >actual &&
+ cat >expect <<-EOF &&
+ * $ZERO_OID $COMMIT_ID FETCH_HEAD
+ EOF
+ test_cmp expect actual &&
+
+ git -C head fetch --porcelain origin HEAD >actual &&
+ test_cmp expect actual &&
+
+ git -C head fetch --porcelain --dry-run origin HEAD:foo >actual &&
+ cat >expect <<-EOF &&
+ * $ZERO_OID $COMMIT_ID refs/heads/foo
+ EOF
+ test_cmp expect actual &&
+
+ git -C head fetch --porcelain origin HEAD:foo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'fetch output with object ID' '
+ test_when_finished "rm -rf object-id" &&
+ git clone . object-id &&
+ commit=$(git rev-parse HEAD) &&
+
+ git -C object-id fetch --dry-run origin $commit:object-id >actual.out 2>actual.err &&
+ cat >expect <<-EOF &&
+ From $(test-tool path-utils real_path .)/.
+ * [new ref] $commit -> object-id
+ EOF
+ test_must_be_empty actual.out &&
+ test_cmp expect actual.err &&
+
+ git -C object-id fetch origin $commit:object-id >actual.out 2>actual.err &&
+ test_must_be_empty actual.out &&
+ test_cmp expect actual.err
+'
+
+test_expect_success '--no-show-forced-updates' '
+ mkdir forced-updates &&
+ (
+ cd forced-updates &&
+ git init &&
+ test_commit 1 &&
+ test_commit 2
+ ) &&
+ git clone forced-updates forced-update-clone &&
+ git clone forced-updates no-forced-update-clone &&
+ git -C forced-updates reset --hard HEAD~1 &&
+ (
+ cd forced-update-clone &&
+ git fetch --show-forced-updates origin 2>output &&
+ test_i18ngrep "(forced update)" output
+ ) &&
+ (
+ cd no-forced-update-clone &&
+ git fetch --no-show-forced-updates origin 2>output &&
+ test_i18ngrep ! "(forced update)" output
+ )
+'
+
+test_done