summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README2
-rw-r--r--t/helper/test-chmtime.c2
-rw-r--r--t/helper/test-date.c2
-rw-r--r--t/helper/test-fast-rebase.c1
-rw-r--r--t/helper/test-lazy-init-name-hash.c1
-rw-r--r--t/helper/test-match-trees.c1
-rw-r--r--t/helper/test-mergesort.c1
-rw-r--r--t/helper/test-oidmap.c2
-rw-r--r--t/helper/test-path-utils.c1
-rw-r--r--t/helper/test-reach.c2
-rw-r--r--t/helper/test-submodule-config.c2
-rwxr-xr-xt/perf/p5312-pack-bitmaps-revs.sh3
-rwxr-xr-xt/t1300-config.sh30
-rwxr-xr-xt/t4115-apply-symlink.sh15
-rwxr-xr-xt/t5300-pack-object.sh135
-rwxr-xr-xt/t5304-prune.sh28
-rwxr-xr-xt/t5319-multi-pack-index.sh12
-rwxr-xr-xt/t5325-reverse-index.sh90
-rwxr-xr-xt/t5331-pack-objects-stdin.sh240
-rwxr-xr-xt/t5512-ls-remote.sh156
-rwxr-xr-xt/t6500-gc.sh133
-rwxr-xr-xt/t6501-freshen-objects.sh10
-rwxr-xr-xt/t7510-signed-commit.sh21
-rwxr-xr-xt/t7700-repack.sh17
-rwxr-xr-xt/t7703-repack-geometric.sh164
-rwxr-xr-xt/t9001-send-email.sh31
-rwxr-xr-xt/t9300-fast-import.sh13
27 files changed, 804 insertions, 311 deletions
diff --git a/t/README b/t/README
index 29576c3748..bdfac4cceb 100644
--- a/t/README
+++ b/t/README
@@ -475,7 +475,7 @@ GIT_TEST_DEFAULT_HASH=<hash-algo> specifies which hash algorithm to
use in the test scripts. Recognized values for <hash-algo> are "sha1"
and "sha256".
-GIT_TEST_WRITE_REV_INDEX=<boolean>, when true enables the
+GIT_TEST_NO_WRITE_REV_INDEX=<boolean>, when true disables the
'pack.writeReverseIndex' setting.
GIT_TEST_SPARSE_INDEX=<boolean>, when true enables index writes to use the
diff --git a/t/helper/test-chmtime.c b/t/helper/test-chmtime.c
index dc28890a18..0e5538833a 100644
--- a/t/helper/test-chmtime.c
+++ b/t/helper/test-chmtime.c
@@ -94,7 +94,7 @@ int cmd__chmtime(int argc, const char **argv)
if (timespec_arg(argv[i], &set_time, &set_eq)) {
++i;
} else {
- if (get == 0) {
+ if (get == 0 && verbose == 0) {
fprintf(stderr, "Not a base-10 integer: %s\n", argv[i] + 1);
goto usage;
}
diff --git a/t/helper/test-date.c b/t/helper/test-date.c
index 2d9232cc68..0683d46574 100644
--- a/t/helper/test-date.c
+++ b/t/helper/test-date.c
@@ -1,6 +1,6 @@
#include "test-tool.h"
-#include "cache.h"
#include "date.h"
+#include "trace.h"
static const char *usage_msg = "\n"
" test-tool date relative [time_t]...\n"
diff --git a/t/helper/test-fast-rebase.c b/t/helper/test-fast-rebase.c
index fd48e0ee2c..d1d63feaa9 100644
--- a/t/helper/test-fast-rebase.c
+++ b/t/helper/test-fast-rebase.c
@@ -20,6 +20,7 @@
#include "hex.h"
#include "lockfile.h"
#include "merge-ort.h"
+#include "object-name.h"
#include "refs.h"
#include "revision.h"
#include "sequencer.h"
diff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c
index 06ce3a47cc..f23d983c11 100644
--- a/t/helper/test-lazy-init-name-hash.c
+++ b/t/helper/test-lazy-init-name-hash.c
@@ -4,6 +4,7 @@
#include "environment.h"
#include "parse-options.h"
#include "setup.h"
+#include "trace.h"
static int single;
static int multi;
diff --git a/t/helper/test-match-trees.c b/t/helper/test-match-trees.c
index 508eb7066a..35a2b8005c 100644
--- a/t/helper/test-match-trees.c
+++ b/t/helper/test-match-trees.c
@@ -1,6 +1,7 @@
#include "test-tool.h"
#include "cache.h"
#include "hex.h"
+#include "object-name.h"
#include "setup.h"
#include "tree.h"
diff --git a/t/helper/test-mergesort.c b/t/helper/test-mergesort.c
index 335e5bb3a9..737e0c5235 100644
--- a/t/helper/test-mergesort.c
+++ b/t/helper/test-mergesort.c
@@ -1,5 +1,6 @@
#include "test-tool.h"
#include "cache.h"
+#include "mem-pool.h"
#include "mergesort.h"
static uint32_t minstd_rand(uint32_t *state)
diff --git a/t/helper/test-oidmap.c b/t/helper/test-oidmap.c
index a7b7b38df1..1b0e7eecb4 100644
--- a/t/helper/test-oidmap.c
+++ b/t/helper/test-oidmap.c
@@ -1,6 +1,6 @@
#include "test-tool.h"
-#include "cache.h"
#include "hex.h"
+#include "object-name.h"
#include "oidmap.h"
#include "setup.h"
#include "strbuf.h"
diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index 4f5ac2fadc..6355c9e4b6 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -4,6 +4,7 @@
#include "environment.h"
#include "setup.h"
#include "string-list.h"
+#include "trace.h"
#include "utf8.h"
/*
diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c
index b0deaa106a..5b6f217441 100644
--- a/t/helper/test-reach.c
+++ b/t/helper/test-reach.c
@@ -1,11 +1,11 @@
#include "test-tool.h"
-#include "cache.h"
#include "alloc.h"
#include "commit.h"
#include "commit-reach.h"
#include "config.h"
#include "gettext.h"
#include "hex.h"
+#include "object-name.h"
#include "parse-options.h"
#include "ref-filter.h"
#include "setup.h"
diff --git a/t/helper/test-submodule-config.c b/t/helper/test-submodule-config.c
index 40a6ee45af..5e462faa9d 100644
--- a/t/helper/test-submodule-config.c
+++ b/t/helper/test-submodule-config.c
@@ -1,6 +1,6 @@
#include "test-tool.h"
-#include "cache.h"
#include "config.h"
+#include "object-name.h"
#include "setup.h"
#include "submodule-config.h"
#include "submodule.h"
diff --git a/t/perf/p5312-pack-bitmaps-revs.sh b/t/perf/p5312-pack-bitmaps-revs.sh
index 0684b690af..ceec60656b 100755
--- a/t/perf/p5312-pack-bitmaps-revs.sh
+++ b/t/perf/p5312-pack-bitmaps-revs.sh
@@ -12,8 +12,7 @@ test_lookup_pack_bitmap () {
test_perf_large_repo
test_expect_success 'setup bitmap config' '
- git config pack.writebitmaps true &&
- git config pack.writeReverseIndex true
+ git config pack.writebitmaps true
'
# we need to create the tag up front such that it is covered by the repack and
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 2575279ab8..f1d42b62b0 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -617,6 +617,36 @@ test_expect_success 'renaming to bogus section is rejected' '
test_must_fail git config --rename-section branch.zwei "bogus name"
'
+test_expect_success 'renaming a section with a long line' '
+ {
+ printf "[b]\\n" &&
+ printf " c = d %1024s [a] e = f\\n" " " &&
+ printf "[a] g = h\\n"
+ } >y &&
+ git config -f y --rename-section a xyz &&
+ test_must_fail git config -f y b.e
+'
+
+test_expect_success 'renaming an embedded section with a long line' '
+ {
+ printf "[b]\\n" &&
+ printf " c = d %1024s [a] [foo] e = f\\n" " " &&
+ printf "[a] g = h\\n"
+ } >y &&
+ git config -f y --rename-section a xyz &&
+ test_must_fail git config -f y foo.e
+'
+
+test_expect_success 'renaming a section with an overly-long line' '
+ {
+ printf "[b]\\n" &&
+ printf " c = d %525000s e" " " &&
+ printf "[a] g = h\\n"
+ } >y &&
+ test_must_fail git config -f y --rename-section a xyz 2>err &&
+ grep "refusing to work with overly long line in .y. on line 2" err
+'
+
cat >> .git/config << EOF
[branch "zwei"] a = 1 [branch "vier"]
EOF
diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh
index 65ac7df2d7..e95e6d4e7d 100755
--- a/t/t4115-apply-symlink.sh
+++ b/t/t4115-apply-symlink.sh
@@ -126,4 +126,19 @@ test_expect_success SYMLINKS 'symlink escape when deleting file' '
test_path_is_file .git/delete-me
'
+test_expect_success SYMLINKS '--reject removes .rej symlink if it exists' '
+ test_when_finished "git reset --hard && git clean -dfx" &&
+
+ test_commit file &&
+ echo modified >file.t &&
+ git diff -- file.t >patch &&
+ echo modified-again >file.t &&
+
+ ln -s foo file.t.rej &&
+ test_must_fail git apply patch --reject 2>err &&
+ test_i18ngrep "Rejected hunk" err &&
+ test_path_is_missing foo &&
+ test_path_is_file file.t.rej
+'
+
test_done
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index f8a0f309e2..d2ce236d61 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -589,141 +589,6 @@ test_expect_success 'prefetch objects' '
test_line_count = 1 donelines
'
-test_expect_success 'setup for --stdin-packs tests' '
- git init stdin-packs &&
- (
- cd stdin-packs &&
-
- test_commit A &&
- test_commit B &&
- test_commit C &&
-
- for id in A B C
- do
- git pack-objects .git/objects/pack/pack-$id \
- --incremental --revs <<-EOF || exit 1
- refs/tags/$id
- EOF
- done &&
-
- ls -la .git/objects/pack
- )
-'
-
-test_expect_success '--stdin-packs with excluded packs' '
- (
- cd stdin-packs &&
-
- PACK_A="$(basename .git/objects/pack/pack-A-*.pack)" &&
- PACK_B="$(basename .git/objects/pack/pack-B-*.pack)" &&
- PACK_C="$(basename .git/objects/pack/pack-C-*.pack)" &&
-
- git pack-objects test --stdin-packs <<-EOF &&
- $PACK_A
- ^$PACK_B
- $PACK_C
- EOF
-
- (
- git show-index <$(ls .git/objects/pack/pack-A-*.idx) &&
- git show-index <$(ls .git/objects/pack/pack-C-*.idx)
- ) >expect.raw &&
- git show-index <$(ls test-*.idx) >actual.raw &&
-
- cut -d" " -f2 <expect.raw | sort >expect &&
- cut -d" " -f2 <actual.raw | sort >actual &&
- test_cmp expect actual
- )
-'
-
-test_expect_success '--stdin-packs is incompatible with --filter' '
- (
- cd stdin-packs &&
- test_must_fail git pack-objects --stdin-packs --stdout \
- --filter=blob:none </dev/null 2>err &&
- test_i18ngrep "cannot use --filter with --stdin-packs" err
- )
-'
-
-test_expect_success '--stdin-packs is incompatible with --revs' '
- (
- cd stdin-packs &&
- test_must_fail git pack-objects --stdin-packs --revs out \
- </dev/null 2>err &&
- test_i18ngrep "cannot use internal rev list with --stdin-packs" err
- )
-'
-
-test_expect_success '--stdin-packs with loose objects' '
- (
- cd stdin-packs &&
-
- PACK_A="$(basename .git/objects/pack/pack-A-*.pack)" &&
- PACK_B="$(basename .git/objects/pack/pack-B-*.pack)" &&
- PACK_C="$(basename .git/objects/pack/pack-C-*.pack)" &&
-
- test_commit D && # loose
-
- git pack-objects test2 --stdin-packs --unpacked <<-EOF &&
- $PACK_A
- ^$PACK_B
- $PACK_C
- EOF
-
- (
- git show-index <$(ls .git/objects/pack/pack-A-*.idx) &&
- git show-index <$(ls .git/objects/pack/pack-C-*.idx) &&
- git rev-list --objects --no-object-names \
- refs/tags/C..refs/tags/D
-
- ) >expect.raw &&
- ls -la . &&
- git show-index <$(ls test2-*.idx) >actual.raw &&
-
- cut -d" " -f2 <expect.raw | sort >expect &&
- cut -d" " -f2 <actual.raw | sort >actual &&
- test_cmp expect actual
- )
-'
-
-test_expect_success '--stdin-packs with broken links' '
- (
- cd stdin-packs &&
-
- # make an unreachable object with a bogus parent
- git cat-file -p HEAD >commit &&
- sed "s/$(git rev-parse HEAD^)/$(test_oid zero)/" <commit |
- git hash-object -w -t commit --stdin >in &&
-
- git pack-objects .git/objects/pack/pack-D <in &&
-
- PACK_A="$(basename .git/objects/pack/pack-A-*.pack)" &&
- PACK_B="$(basename .git/objects/pack/pack-B-*.pack)" &&
- PACK_C="$(basename .git/objects/pack/pack-C-*.pack)" &&
- PACK_D="$(basename .git/objects/pack/pack-D-*.pack)" &&
-
- git pack-objects test3 --stdin-packs --unpacked <<-EOF &&
- $PACK_A
- ^$PACK_B
- $PACK_C
- $PACK_D
- EOF
-
- (
- git show-index <$(ls .git/objects/pack/pack-A-*.idx) &&
- git show-index <$(ls .git/objects/pack/pack-C-*.idx) &&
- git show-index <$(ls .git/objects/pack/pack-D-*.idx) &&
- git rev-list --objects --no-object-names \
- refs/tags/C..refs/tags/D
- ) >expect.raw &&
- git show-index <$(ls test3-*.idx) >actual.raw &&
-
- cut -d" " -f2 <expect.raw | sort >expect &&
- cut -d" " -f2 <actual.raw | sort >actual &&
- test_cmp expect actual
- )
-'
-
test_expect_success 'negative window clamps to 0' '
git pack-objects --progress --window=-1 neg-window <obj-list 2>stderr &&
check_deltas stderr = 0
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
index 5500dd0842..662ae9b152 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -62,11 +62,11 @@ test_expect_success 'prune --expire' '
test_expect_success 'gc: implicit prune --expire' '
add_blob &&
test-tool chmtime =-$((2*$week-30)) $BLOB_FILE &&
- git gc &&
+ git gc --no-cruft &&
verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
test_path_is_file $BLOB_FILE &&
test-tool chmtime =-$((2*$week+1)) $BLOB_FILE &&
- git gc &&
+ git gc --no-cruft &&
verbose test $before = $(git count-objects | sed "s/ .*//") &&
test_path_is_missing $BLOB_FILE
'
@@ -86,7 +86,7 @@ test_expect_success 'gc: refuse to start with invalid gc.pruneExpire' '
test_expect_success 'gc: start with ok gc.pruneExpire' '
git config gc.pruneExpire 2.days.ago &&
- git gc
+ git gc --no-cruft
'
test_expect_success 'prune: prune nonsense parameters' '
@@ -137,44 +137,44 @@ test_expect_success 'gc --no-prune' '
add_blob &&
test-tool chmtime =-$((5001*$day)) $BLOB_FILE &&
git config gc.pruneExpire 2.days.ago &&
- git gc --no-prune &&
+ git gc --no-prune --no-cruft &&
verbose test 1 = $(git count-objects | sed "s/ .*//") &&
test_path_is_file $BLOB_FILE
'
test_expect_success 'gc respects gc.pruneExpire' '
git config gc.pruneExpire 5002.days.ago &&
- git gc &&
+ git gc --no-cruft &&
test_path_is_file $BLOB_FILE &&
git config gc.pruneExpire 5000.days.ago &&
- git gc &&
+ git gc --no-cruft &&
test_path_is_missing $BLOB_FILE
'
test_expect_success 'gc --prune=<date>' '
add_blob &&
test-tool chmtime =-$((5001*$day)) $BLOB_FILE &&
- git gc --prune=5002.days.ago &&
+ git gc --prune=5002.days.ago --no-cruft &&
test_path_is_file $BLOB_FILE &&
- git gc --prune=5000.days.ago &&
+ git gc --prune=5000.days.ago --no-cruft &&
test_path_is_missing $BLOB_FILE
'
test_expect_success 'gc --prune=never' '
add_blob &&
- git gc --prune=never &&
+ git gc --prune=never --no-cruft &&
test_path_is_file $BLOB_FILE &&
- git gc --prune=now &&
+ git gc --prune=now --no-cruft &&
test_path_is_missing $BLOB_FILE
'
test_expect_success 'gc respects gc.pruneExpire=never' '
git config gc.pruneExpire never &&
add_blob &&
- git gc &&
+ git gc --no-cruft &&
test_path_is_file $BLOB_FILE &&
git config gc.pruneExpire now &&
- git gc &&
+ git gc --no-cruft &&
test_path_is_missing $BLOB_FILE
'
@@ -194,7 +194,7 @@ test_expect_success 'gc: prune old objects after local clone' '
cd aclone &&
verbose test 1 = $(git count-objects | sed "s/ .*//") &&
test_path_is_file $BLOB_FILE &&
- git gc --prune &&
+ git gc --prune --no-cruft &&
verbose test 0 = $(git count-objects | sed "s/ .*//") &&
test_path_is_missing $BLOB_FILE
)
@@ -237,7 +237,7 @@ test_expect_success 'clean pack garbage with gc' '
>.git/objects/pack/fake2.keep &&
>.git/objects/pack/fake2.idx &&
>.git/objects/pack/fake3.keep &&
- git gc &&
+ git gc --no-cruft &&
git count-objects -v 2>stderr &&
grep "^warning:" stderr | sort >actual &&
cat >expected <<\EOF &&
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index 499d5d4c78..0883c7c6bd 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -183,6 +183,18 @@ test_expect_success 'write midx with --stdin-packs' '
compare_results_with_midx "mixed mode (one pack + extra)"
+test_expect_success 'write with no objects and preferred pack' '
+ test_when_finished "rm -rf empty" &&
+ git init empty &&
+ test_must_fail git -C empty multi-pack-index write \
+ --stdin-packs --preferred-pack=does-not-exist </dev/null 2>err &&
+ cat >expect <<-EOF &&
+ warning: unknown preferred pack: ${SQ}does-not-exist${SQ}
+ error: no pack files to index.
+ EOF
+ test_cmp expect err
+'
+
test_expect_success 'write progress off for redirected stderr' '
git multi-pack-index --object-dir=$objdir write 2>err &&
test_line_count = 0 err
diff --git a/t/t5325-reverse-index.sh b/t/t5325-reverse-index.sh
index d042d26f2b..431a603ca0 100755
--- a/t/t5325-reverse-index.sh
+++ b/t/t5325-reverse-index.sh
@@ -1,17 +1,20 @@
#!/bin/sh
test_description='on-disk reverse index'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# The below tests want control over the 'pack.writeReverseIndex' setting
# themselves to assert various combinations of it with other options.
-sane_unset GIT_TEST_WRITE_REV_INDEX
+sane_unset GIT_TEST_NO_WRITE_REV_INDEX
packdir=.git/objects/pack
test_expect_success 'setup' '
test_commit base &&
+ test_config pack.writeReverseIndex false &&
pack=$(git pack-objects --all $packdir/pack) &&
rev=$packdir/pack-$pack.rev &&
@@ -94,6 +97,17 @@ test_expect_success 'reverse index is not generated when available on disk' '
--batch-check="%(objectsize:disk)" <tip
'
+test_expect_success 'reverse index is ignored when pack.readReverseIndex is false' '
+ test_index_pack true &&
+ test_path_is_file $rev &&
+
+ test_config pack.readReverseIndex false &&
+
+ git rev-parse HEAD >tip &&
+ GIT_TEST_REV_INDEX_DIE_ON_DISK=1 git cat-file \
+ --batch-check="%(objectsize:disk)" <tip
+'
+
test_expect_success 'revindex in-memory vs on-disk' '
git init repo &&
test_when_finished "rm -fr repo" &&
@@ -117,4 +131,78 @@ test_expect_success 'revindex in-memory vs on-disk' '
test_cmp on-disk in-core
)
'
+
+test_expect_success 'fsck succeeds on good rev-index' '
+ test_when_finished rm -fr repo &&
+ git init repo &&
+ (
+ cd repo &&
+
+ test_commit commit &&
+ git -c pack.writeReverseIndex=true repack -ad &&
+ git fsck 2>err &&
+ test_must_be_empty err
+ )
+'
+
+test_expect_success 'set up rev-index corruption tests' '
+ git init corrupt &&
+ (
+ cd corrupt &&
+
+ test_commit commit &&
+ git -c pack.writeReverseIndex=true repack -ad &&
+
+ revfile=$(ls .git/objects/pack/pack-*.rev) &&
+ chmod a+w $revfile &&
+ cp $revfile $revfile.bak
+ )
+'
+
+corrupt_rev_and_verify () {
+ (
+ pos="$1" &&
+ value="$2" &&
+ error="$3" &&
+
+ cd corrupt &&
+ revfile=$(ls .git/objects/pack/pack-*.rev) &&
+
+ # Reset to original rev-file.
+ cp $revfile.bak $revfile &&
+
+ printf "$value" | dd of=$revfile bs=1 seek="$pos" conv=notrunc &&
+ test_must_fail git fsck 2>err &&
+ grep "$error" err
+ )
+}
+
+test_expect_success 'fsck catches invalid checksum' '
+ revfile=$(ls corrupt/.git/objects/pack/pack-*.rev) &&
+ orig_size=$(wc -c <$revfile) &&
+ hashpos=$((orig_size - 10)) &&
+ corrupt_rev_and_verify $hashpos bogus \
+ "invalid checksum"
+'
+
+test_expect_success 'fsck catches invalid row position' '
+ corrupt_rev_and_verify 14 "\07" \
+ "invalid rev-index position"
+'
+
+test_expect_success 'fsck catches invalid header: magic number' '
+ corrupt_rev_and_verify 1 "\07" \
+ "reverse-index file .* has unknown signature"
+'
+
+test_expect_success 'fsck catches invalid header: version' '
+ corrupt_rev_and_verify 7 "\02" \
+ "reverse-index file .* has unsupported version"
+'
+
+test_expect_success 'fsck catches invalid header: hash function' '
+ corrupt_rev_and_verify 11 "\03" \
+ "reverse-index file .* has unsupported hash id"
+'
+
test_done
diff --git a/t/t5331-pack-objects-stdin.sh b/t/t5331-pack-objects-stdin.sh
new file mode 100755
index 0000000000..acab31667a
--- /dev/null
+++ b/t/t5331-pack-objects-stdin.sh
@@ -0,0 +1,240 @@
+#!/bin/sh
+
+test_description='pack-objects --stdin'
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+
+TEST_PASSES_SANITIZE_LEAK=true
+. ./test-lib.sh
+
+packed_objects () {
+ git show-index <"$1" >tmp-object-list &&
+ cut -d' ' -f2 tmp-object-list | sort &&
+ rm tmp-object-list
+ }
+
+test_expect_success 'setup for --stdin-packs tests' '
+ git init stdin-packs &&
+ (
+ cd stdin-packs &&
+
+ test_commit A &&
+ test_commit B &&
+ test_commit C &&
+
+ for id in A B C
+ do
+ git pack-objects .git/objects/pack/pack-$id \
+ --incremental --revs <<-EOF || exit 1
+ refs/tags/$id
+ EOF
+ done &&
+
+ ls -la .git/objects/pack
+ )
+'
+
+test_expect_success '--stdin-packs with excluded packs' '
+ (
+ cd stdin-packs &&
+
+ PACK_A="$(basename .git/objects/pack/pack-A-*.pack)" &&
+ PACK_B="$(basename .git/objects/pack/pack-B-*.pack)" &&
+ PACK_C="$(basename .git/objects/pack/pack-C-*.pack)" &&
+
+ git pack-objects test --stdin-packs <<-EOF &&
+ $PACK_A
+ ^$PACK_B
+ $PACK_C
+ EOF
+
+ (
+ git show-index <$(ls .git/objects/pack/pack-A-*.idx) &&
+ git show-index <$(ls .git/objects/pack/pack-C-*.idx)
+ ) >expect.raw &&
+ git show-index <$(ls test-*.idx) >actual.raw &&
+
+ cut -d" " -f2 <expect.raw | sort >expect &&
+ cut -d" " -f2 <actual.raw | sort >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success '--stdin-packs is incompatible with --filter' '
+ (
+ cd stdin-packs &&
+ test_must_fail git pack-objects --stdin-packs --stdout \
+ --filter=blob:none </dev/null 2>err &&
+ test_i18ngrep "cannot use --filter with --stdin-packs" err
+ )
+'
+
+test_expect_success '--stdin-packs is incompatible with --revs' '
+ (
+ cd stdin-packs &&
+ test_must_fail git pack-objects --stdin-packs --revs out \
+ </dev/null 2>err &&
+ test_i18ngrep "cannot use internal rev list with --stdin-packs" err
+ )
+'
+
+test_expect_success '--stdin-packs with loose objects' '
+ (
+ cd stdin-packs &&
+
+ PACK_A="$(basename .git/objects/pack/pack-A-*.pack)" &&
+ PACK_B="$(basename .git/objects/pack/pack-B-*.pack)" &&
+ PACK_C="$(basename .git/objects/pack/pack-C-*.pack)" &&
+
+ test_commit D && # loose
+
+ git pack-objects test2 --stdin-packs --unpacked <<-EOF &&
+ $PACK_A
+ ^$PACK_B
+ $PACK_C
+ EOF
+
+ (
+ git show-index <$(ls .git/objects/pack/pack-A-*.idx) &&
+ git show-index <$(ls .git/objects/pack/pack-C-*.idx) &&
+ git rev-list --objects --no-object-names \
+ refs/tags/C..refs/tags/D
+
+ ) >expect.raw &&
+ ls -la . &&
+ git show-index <$(ls test2-*.idx) >actual.raw &&
+
+ cut -d" " -f2 <expect.raw | sort >expect &&
+ cut -d" " -f2 <actual.raw | sort >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success '--stdin-packs with broken links' '
+ (
+ cd stdin-packs &&
+
+ # make an unreachable object with a bogus parent
+ git cat-file -p HEAD >commit &&
+ sed "s/$(git rev-parse HEAD^)/$(test_oid zero)/" <commit |
+ git hash-object -w -t commit --stdin >in &&
+
+ git pack-objects .git/objects/pack/pack-D <in &&
+
+ PACK_A="$(basename .git/objects/pack/pack-A-*.pack)" &&
+ PACK_B="$(basename .git/objects/pack/pack-B-*.pack)" &&
+ PACK_C="$(basename .git/objects/pack/pack-C-*.pack)" &&
+ PACK_D="$(basename .git/objects/pack/pack-D-*.pack)" &&
+
+ git pack-objects test3 --stdin-packs --unpacked <<-EOF &&
+ $PACK_A
+ ^$PACK_B
+ $PACK_C
+ $PACK_D
+ EOF
+
+ (
+ git show-index <$(ls .git/objects/pack/pack-A-*.idx) &&
+ git show-index <$(ls .git/objects/pack/pack-C-*.idx) &&
+ git show-index <$(ls .git/objects/pack/pack-D-*.idx) &&
+ git rev-list --objects --no-object-names \
+ refs/tags/C..refs/tags/D
+ ) >expect.raw &&
+ git show-index <$(ls test3-*.idx) >actual.raw &&
+
+ cut -d" " -f2 <expect.raw | sort >expect &&
+ cut -d" " -f2 <actual.raw | sort >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'pack-objects --stdin with duplicate packfile' '
+ test_when_finished "rm -fr repo" &&
+
+ git init repo &&
+ (
+ cd repo &&
+ test_commit "commit" &&
+ git repack -ad &&
+
+ {
+ basename .git/objects/pack/pack-*.pack &&
+ basename .git/objects/pack/pack-*.pack
+ } >packfiles &&
+
+ git pack-objects --stdin-packs generated-pack <packfiles &&
+ packed_objects .git/objects/pack/pack-*.idx >expect &&
+ packed_objects generated-pack-*.idx >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'pack-objects --stdin with same packfile excluded and included' '
+ test_when_finished "rm -fr repo" &&
+
+ git init repo &&
+ (
+ cd repo &&
+ test_commit "commit" &&
+ git repack -ad &&
+
+ {
+ basename .git/objects/pack/pack-*.pack &&
+ printf "^%s\n" "$(basename .git/objects/pack/pack-*.pack)"
+ } >packfiles &&
+
+ git pack-objects --stdin-packs generated-pack <packfiles &&
+ packed_objects generated-pack-*.idx >packed-objects &&
+ test_must_be_empty packed-objects
+ )
+'
+
+test_expect_success 'pack-objects --stdin with packfiles from alternate object database' '
+ test_when_finished "rm -fr shared member" &&
+
+ # Set up a shared repository with a single packfile.
+ git init shared &&
+ test_commit -C shared "shared-objects" &&
+ git -C shared repack -ad &&
+ basename shared/.git/objects/pack/pack-*.pack >packfile &&
+
+ # Set up a repository that is connected to the shared repository. This
+ # repository has no objects on its own, but we still expect to be able
+ # to pack objects from its alternate.
+ git clone --shared shared member &&
+ git -C member pack-objects --stdin-packs generated-pack <packfile &&
+ test_cmp shared/.git/objects/pack/pack-*.pack member/generated-pack-*.pack
+'
+
+test_expect_success 'pack-objects --stdin with packfiles from main and alternate object database' '
+ test_when_finished "rm -fr shared member" &&
+
+ # Set up a shared repository with a single packfile.
+ git init shared &&
+ test_commit -C shared "shared-commit" &&
+ git -C shared repack -ad &&
+
+ # Set up a repository that is connected to the shared repository. This
+ # repository has a second packfile so that we can verify that it is
+ # possible to write packs that include packfiles from different object
+ # databases.
+ git clone --shared shared member &&
+ test_commit -C member "local-commit" &&
+ git -C member repack -dl &&
+
+ {
+ basename shared/.git/objects/pack/pack-*.pack &&
+ basename member/.git/objects/pack/pack-*.pack
+ } >packfiles &&
+
+ {
+ packed_objects shared/.git/objects/pack/pack-*.idx &&
+ packed_objects member/.git/objects/pack/pack-*.idx
+ } | sort >expected-objects &&
+
+ git -C member pack-objects --stdin-packs generated-pack <packfiles &&
+ packed_objects member/generated-pack-*.idx >actual-objects &&
+ test_cmp expected-objects actual-objects
+'
+
+test_done
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 20d063fb9a..151c76eb09 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -15,6 +15,19 @@ generate_references () {
done
}
+test_expect_success 'set up fake upload-pack' '
+ # This can be used to simulate an upload-pack that just shows the
+ # contents of the "input" file (prepared with the test-tool pkt-line
+ # helper), and does not do any negotiation (since ls-remote does not
+ # need it).
+ write_script cat-input <<-\EOF
+ # send our initial advertisement/response
+ cat input
+ # soak up the flush packet from the client
+ cat
+ EOF
+'
+
test_expect_success 'dies when no remote found' '
test_must_fail git ls-remote
'
@@ -231,22 +244,25 @@ test_expect_success 'protocol v2 supports hiderefs' '
test_expect_success 'ls-remote --symref' '
git fetch origin &&
- echo "ref: refs/heads/main HEAD" >expect &&
+ echo "ref: refs/heads/main HEAD" >expect.v2 &&
generate_references \
HEAD \
- refs/heads/main >>expect &&
+ refs/heads/main >>expect.v2 &&
+ echo "ref: refs/remotes/origin/main refs/remotes/origin/HEAD" >>expect.v2 &&
oid=$(git rev-parse HEAD) &&
- echo "$oid refs/remotes/origin/HEAD" >>expect &&
+ echo "$oid refs/remotes/origin/HEAD" >>expect.v2 &&
generate_references \
refs/remotes/origin/main \
refs/tags/mark \
refs/tags/mark1.1 \
refs/tags/mark1.10 \
- refs/tags/mark1.2 >>expect &&
- # Protocol v2 supports sending symrefs for refs other than HEAD, so use
- # protocol v0 here.
- GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref >actual &&
- test_cmp expect actual
+ refs/tags/mark1.2 >>expect.v2 &&
+ # v0 does not show non-HEAD symrefs
+ grep -v "ref: refs/remotes" <expect.v2 >expect.v0 &&
+ git -c protocol.version=0 ls-remote --symref >actual.v0 &&
+ test_cmp expect.v0 actual.v0 &&
+ git -c protocol.version=2 ls-remote --symref >actual.v2 &&
+ test_cmp expect.v2 actual.v2
'
test_expect_success 'ls-remote with filtered symref (refname)' '
@@ -255,76 +271,41 @@ test_expect_success 'ls-remote with filtered symref (refname)' '
ref: refs/heads/main HEAD
$rev HEAD
EOF
- # Protocol v2 supports sending symrefs for refs other than HEAD, so use
- # protocol v0 here.
- GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . HEAD >actual &&
+ git ls-remote --symref . HEAD >actual &&
test_cmp expect actual
'
-test_expect_failure 'ls-remote with filtered symref (--heads)' '
+test_expect_success 'ls-remote with filtered symref (--heads)' '
git symbolic-ref refs/heads/foo refs/tags/mark &&
- cat >expect <<-EOF &&
+ cat >expect.v2 <<-EOF &&
ref: refs/tags/mark refs/heads/foo
$rev refs/heads/foo
$rev refs/heads/main
EOF
- # Protocol v2 supports sending symrefs for refs other than HEAD, so use
- # protocol v0 here.
- GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
- test_cmp expect actual
+ grep -v "^ref: refs/tags/" <expect.v2 >expect.v0 &&
+ git -c protocol.version=0 ls-remote --symref --heads . >actual.v0 &&
+ test_cmp expect.v0 actual.v0 &&
+ git -c protocol.version=2 ls-remote --symref --heads . >actual.v2 &&
+ test_cmp expect.v2 actual.v2
'
-test_expect_success 'ls-remote --symref omits filtered-out matches' '
- cat >expect <<-EOF &&
- $rev refs/heads/foo
- $rev refs/heads/main
+test_expect_success 'indicate no refs in v0 standards-compliant empty remote' '
+ # Git does not produce an output like this, but it does match the
+ # standard and is produced by other implementations like JGit. So
+ # hard-code the case we care about.
+ #
+ # The actual capabilities do not matter; there are none that would
+ # change how ls-remote behaves.
+ oid=0000000000000000000000000000000000000000 &&
+ test-tool pkt-line pack >input.q <<-EOF &&
+ $oid capabilities^{}Qcaps-go-here
+ 0000
EOF
- # Protocol v2 supports sending symrefs for refs other than HEAD, so use
- # protocol v0 here.
- GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual &&
- test_cmp expect actual &&
- GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . "refs/heads/*" >actual &&
- test_cmp expect actual
-'
-
-test_lazy_prereq GIT_DAEMON '
- test_bool_env GIT_TEST_GIT_DAEMON true
-'
+ q_to_nul <input.q >input &&
-# This test spawns a daemon, so run it only if the user would be OK with
-# testing with git-daemon.
-test_expect_success PIPE,JGIT,GIT_DAEMON 'indicate no refs in standards-compliant empty remote' '
- test_set_port JGIT_DAEMON_PORT &&
- JGIT_DAEMON_PID= &&
- git init --bare empty.git &&
- >empty.git/git-daemon-export-ok &&
- mkfifo jgit_daemon_output &&
- {
- jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output &
- JGIT_DAEMON_PID=$!
- } &&
- test_when_finished kill "$JGIT_DAEMON_PID" &&
- {
- read line &&
- case $line in
- Exporting*)
- ;;
- *)
- echo "Expected: Exporting" &&
- false;;
- esac &&
- read line &&
- case $line in
- "Listening on"*)
- ;;
- *)
- echo "Expected: Listening on" &&
- false;;
- esac
- } <jgit_daemon_output &&
# --exit-code asks the command to exit with 2 when no
# matching refs are found.
- test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git
+ test_expect_code 2 git ls-remote --exit-code --upload-pack=./cat-input .
'
test_expect_success 'ls-remote works outside repository' '
@@ -345,8 +326,8 @@ test_expect_success 'ls-remote --sort fails gracefully outside repository' '
test_expect_success 'ls-remote patterns work with all protocol versions' '
git for-each-ref --format="%(objectname) %(refname)" \
refs/heads/main refs/remotes/origin/main >expect &&
- git -c protocol.version=1 ls-remote . main >actual.v1 &&
- test_cmp expect actual.v1 &&
+ git -c protocol.version=0 ls-remote . main >actual.v0 &&
+ test_cmp expect actual.v0 &&
git -c protocol.version=2 ls-remote . main >actual.v2 &&
test_cmp expect actual.v2
'
@@ -354,10 +335,49 @@ test_expect_success 'ls-remote patterns work with all protocol versions' '
test_expect_success 'ls-remote prefixes work with all protocol versions' '
git for-each-ref --format="%(objectname) %(refname)" \
refs/heads/ refs/tags/ >expect &&
- git -c protocol.version=1 ls-remote --heads --tags . >actual.v1 &&
- test_cmp expect actual.v1 &&
+ git -c protocol.version=0 ls-remote --heads --tags . >actual.v0 &&
+ test_cmp expect actual.v0 &&
git -c protocol.version=2 ls-remote --heads --tags . >actual.v2 &&
test_cmp expect actual.v2
'
+test_expect_success 'v0 clients can handle multiple symrefs' '
+ # Modern versions of Git will not return multiple symref capabilities
+ # for v0, so we have to hard-code the response. Note that we will
+ # always use both v0 and object-format=sha1 here, as the hard-coded
+ # response reflects a server that only supports those.
+ oid=1234567890123456789012345678901234567890 &&
+ symrefs="symref=refs/remotes/origin/HEAD:refs/remotes/origin/main" &&
+ symrefs="$symrefs symref=HEAD:refs/heads/main" &&
+
+ # Likewise we want to make sure our parser is not fooled by the string
+ # "symref" appearing as part of an earlier cap. But there is no way to
+ # do that via upload-pack, as arbitrary strings can appear only in a
+ # "symref" value itself (where we skip past the values as a whole)
+ # and "agent" (which always appears after "symref", so putting our
+ # parser in a confused state is less interesting).
+ caps="some other caps including a-fake-symref-cap" &&
+
+ test-tool pkt-line pack >input.q <<-EOF &&
+ $oid HEADQ$caps $symrefs
+ $oid refs/heads/main
+ $oid refs/remotes/origin/HEAD
+ $oid refs/remotes/origin/main
+ 0000
+ EOF
+ q_to_nul <input.q >input &&
+
+ cat >expect <<-EOF &&
+ ref: refs/heads/main HEAD
+ $oid HEAD
+ $oid refs/heads/main
+ ref: refs/remotes/origin/main refs/remotes/origin/HEAD
+ $oid refs/remotes/origin/HEAD
+ $oid refs/remotes/origin/main
+ EOF
+
+ git ls-remote --symref --upload-pack=./cat-input . >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index d9acb63951..69509d0c11 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -210,90 +210,95 @@ prepare_cruft_history () {
git reset HEAD^^
}
-assert_cruft_packs () {
- find .git/objects/pack -name "*.mtimes" >mtimes &&
- sed -e 's/\.mtimes$/\.pack/g' mtimes >packs &&
-
- test_file_not_empty packs &&
- while read pack
- do
- test_path_is_file "$pack" || return 1
- done <packs
-}
-
assert_no_cruft_packs () {
find .git/objects/pack -name "*.mtimes" >mtimes &&
test_must_be_empty mtimes
}
-test_expect_success 'gc --cruft generates a cruft pack' '
- test_when_finished "rm -fr crufts" &&
- git init crufts &&
+for argv in \
+ "gc" \
+ "-c gc.cruftPacks=true gc" \
+ "-c gc.cruftPacks=false gc --cruft"
+do
+ test_expect_success "git $argv generates a cruft pack" '
+ test_when_finished "rm -fr repo" &&
+ git init repo &&
+ (
+ cd repo &&
+
+ prepare_cruft_history &&
+ git $argv &&
+
+ find .git/objects/pack -name "*.mtimes" >mtimes &&
+ sed -e 's/\.mtimes$/\.pack/g' mtimes >packs &&
+
+ test_file_not_empty packs &&
+ while read pack
+ do
+ test_path_is_file "$pack" || return 1
+ done <packs
+ )
+ '
+done
+
+for argv in \
+ "gc --no-cruft" \
+ "-c gc.cruftPacks=false gc" \
+ "-c gc.cruftPacks=true gc --no-cruft"
+do
+ test_expect_success "git $argv does not generate a cruft pack" '
+ test_when_finished "rm -fr repo" &&
+ git init repo &&
+ (
+ cd repo &&
+
+ prepare_cruft_history &&
+ git $argv &&
+
+ assert_no_cruft_packs
+ )
+ '
+done
+
+test_expect_success '--keep-largest-pack ignores cruft packs' '
+ test_when_finished "rm -fr repo" &&
+ git init repo &&
(
- cd crufts &&
+ cd repo &&
+ # Generate a pack for reachable objects (of which there
+ # are 3), and one for unreachable objects (of which
+ # there are 6).
prepare_cruft_history &&
git gc --cruft &&
- assert_cruft_packs
- )
-'
-
-test_expect_success 'gc.cruftPacks=true generates a cruft pack' '
- test_when_finished "rm -fr crufts" &&
- git init crufts &&
- (
- cd crufts &&
-
- prepare_cruft_history &&
- git -c gc.cruftPacks=true gc &&
- assert_cruft_packs
- )
-'
-
-test_expect_success 'feature.experimental=true generates a cruft pack' '
- git init crufts &&
- test_when_finished "rm -fr crufts" &&
- (
- cd crufts &&
- prepare_cruft_history &&
- git -c feature.experimental=true gc &&
- assert_cruft_packs
- )
-'
+ mtimes="$(find .git/objects/pack -type f -name "pack-*.mtimes")" &&
+ sz="$(test_file_size "${mtimes%.mtimes}.pack")" &&
-test_expect_success 'feature.experimental=false allows explicit cruft packs' '
- git init crufts &&
- test_when_finished "rm -fr crufts" &&
- (
- cd crufts &&
+ # Ensure that the cruft pack gets removed (due to
+ # `--prune=now`) despite it being the largest pack.
+ git -c gc.bigPackThreshold=$sz gc --cruft --prune=now &&
- prepare_cruft_history &&
- git -c gc.cruftPacks=true -c feature.experimental=false gc &&
- assert_cruft_packs
+ assert_no_cruft_packs
)
'
-test_expect_success 'feature.experimental=true can be overridden' '
- git init crufts &&
- test_when_finished "rm -fr crufts" &&
+test_expect_success 'gc.bigPackThreshold ignores cruft packs' '
+ test_when_finished "rm -fr repo" &&
+ git init repo &&
(
- cd crufts &&
+ cd repo &&
+ # Generate a pack for reachable objects (of which there
+ # are 3), and one for unreachable objects (of which
+ # there are 6).
prepare_cruft_history &&
- git -c feature.expiremental=true -c gc.cruftPacks=false gc &&
- assert_no_cruft_packs
- )
-'
+ git gc --cruft &&
-test_expect_success 'feature.experimental=false avoids cruft packs by default' '
- git init crufts &&
- test_when_finished "rm -fr crufts" &&
- (
- cd crufts &&
+ # Ensure that the cruft pack gets removed (due to
+ # `--prune=now`) despite it being the largest pack.
+ git gc --cruft --prune=now --keep-largest-pack &&
- prepare_cruft_history &&
- git -c feature.experimental=false gc &&
assert_no_cruft_packs
)
'
diff --git a/t/t6501-freshen-objects.sh b/t/t6501-freshen-objects.sh
index 3968b47ed5..dbfa8a4d4c 100755
--- a/t/t6501-freshen-objects.sh
+++ b/t/t6501-freshen-objects.sh
@@ -101,7 +101,7 @@ do
'
test_expect_success "simultaneous gc ($title)" '
- git gc --prune=12.hours.ago
+ git gc --no-cruft --prune=12.hours.ago
'
test_expect_success "finish writing out commit ($title)" '
@@ -131,7 +131,7 @@ do
'
test_expect_success "simultaneous gc ($title)" '
- git gc --prune=12.hours.ago
+ git gc --no-cruft --prune=12.hours.ago
'
# tree should have been refreshed by write-tree
@@ -151,7 +151,7 @@ test_expect_success 'do not complain about existing broken links (commit)' '
some message
EOF
commit=$(git hash-object -t commit -w broken-commit) &&
- git gc -q 2>stderr &&
+ git gc --no-cruft -q 2>stderr &&
verbose git cat-file -e $commit &&
test_must_be_empty stderr
'
@@ -161,7 +161,7 @@ test_expect_success 'do not complain about existing broken links (tree)' '
100644 blob $(test_oid 003) foo
EOF
tree=$(git mktree --missing <broken-tree) &&
- git gc -q 2>stderr &&
+ git gc --no-cruft -q 2>stderr &&
git cat-file -e $tree &&
test_must_be_empty stderr
'
@@ -176,7 +176,7 @@ test_expect_success 'do not complain about existing broken links (tag)' '
this is a broken tag
EOF
tag=$(git hash-object -t tag -w broken-tag) &&
- git gc -q 2>stderr &&
+ git gc --no-cruft -q 2>stderr &&
git cat-file -e $tag &&
test_must_be_empty stderr
'
diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh
index 48f86cb367..ccbc416402 100755
--- a/t/t7510-signed-commit.sh
+++ b/t/t7510-signed-commit.sh
@@ -221,84 +221,91 @@ test_expect_success GPG 'amending already signed commit' '
test_expect_success GPG 'show good signature with custom format' '
cat >expect <<-\EOF &&
G
+ ultimate
13B6F51ECDDE430D
C O Mitter <committer@example.com>
73D758744BE721698EC54E8713B6F51ECDDE430D
73D758744BE721698EC54E8713B6F51ECDDE430D
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
+ git log -1 --format="%G?%n%GT%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
test_cmp expect actual
'
test_expect_success GPG 'show bad signature with custom format' '
cat >expect <<-\EOF &&
B
+ undefined
13B6F51ECDDE430D
C O Mitter <committer@example.com>
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat forged1.commit) >actual &&
+ git log -1 --format="%G?%n%GT%n%GK%n%GS%n%GF%n%GP" $(cat forged1.commit) >actual &&
test_cmp expect actual
'
test_expect_success GPG 'show untrusted signature with custom format' '
cat >expect <<-\EOF &&
U
+ undefined
65A0EEA02E30CAD7
Eris Discordia <discord@example.net>
F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7
D4BE22311AD3131E5EDA29A461092E85B7227189
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
+ git log -1 --format="%G?%n%GT%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
test_cmp expect actual
'
test_expect_success GPG 'show untrusted signature with undefined trust level' '
cat >expect <<-\EOF &&
+ U
undefined
65A0EEA02E30CAD7
Eris Discordia <discord@example.net>
F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7
D4BE22311AD3131E5EDA29A461092E85B7227189
EOF
- git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
+ git log -1 --format="%G?%n%GT%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
test_cmp expect actual
'
test_expect_success GPG 'show untrusted signature with ultimate trust level' '
cat >expect <<-\EOF &&
+ G
ultimate
13B6F51ECDDE430D
C O Mitter <committer@example.com>
73D758744BE721698EC54E8713B6F51ECDDE430D
73D758744BE721698EC54E8713B6F51ECDDE430D
EOF
- git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
+ git log -1 --format="%G?%n%GT%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
test_cmp expect actual
'
test_expect_success GPG 'show unknown signature with custom format' '
cat >expect <<-\EOF &&
E
+ undefined
65A0EEA02E30CAD7
EOF
- GNUPGHOME="$GNUPGHOME_NOT_USED" git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
+ GNUPGHOME="$GNUPGHOME_NOT_USED" git log -1 --format="%G?%n%GT%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
test_cmp expect actual
'
test_expect_success GPG 'show lack of signature with custom format' '
cat >expect <<-\EOF &&
N
+ undefined
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" seventh-unsigned >actual &&
+ git log -1 --format="%G?%n%GT%n%GK%n%GS%n%GF%n%GP" seventh-unsigned >actual &&
test_cmp expect actual
'
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index 4aabe98139..faa739eeb9 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -106,6 +106,23 @@ test_expect_success SYMLINKS '--local keeps packs when alternate is objectdir '
test_cmp expect actual
'
+test_expect_success '--local disables writing bitmaps when connected to alternate ODB' '
+ test_when_finished "rm -rf shared member" &&
+
+ git init shared &&
+ git clone --shared shared member &&
+ (
+ cd member &&
+ test_commit "object" &&
+ GIT_TEST_MULTI_PACK_INDEX=0 git repack -Adl --write-bitmap-index 2>err &&
+ cat >expect <<-EOF &&
+ warning: disabling bitmap writing, as some objects are not being packed
+ EOF
+ test_cmp expect err &&
+ test_path_is_missing .git/objects/pack-*.bitmap
+ )
+'
+
test_expect_success 'packed obs in alt ODB are repacked even when local repo is packless' '
mkdir alt_objects/pack &&
mv .git/objects/pack/* alt_objects/pack &&
diff --git a/t/t7703-repack-geometric.sh b/t/t7703-repack-geometric.sh
index 8821fbd2dd..00f28fb558 100755
--- a/t/t7703-repack-geometric.sh
+++ b/t/t7703-repack-geometric.sh
@@ -10,6 +10,12 @@ objdir=.git/objects
packdir=$objdir/pack
midx=$objdir/pack/multi-pack-index
+packed_objects () {
+ git show-index <"$1" >tmp-object-list &&
+ cut -d' ' -f2 tmp-object-list | sort &&
+ rm tmp-object-list
+ }
+
test_expect_success '--geometric with no packs' '
git init geometric &&
test_when_finished "rm -fr geometric" &&
@@ -281,4 +287,162 @@ test_expect_success '--geometric with pack.packSizeLimit' '
)
'
+test_expect_success '--geometric --write-midx with packfiles in main and alternate ODB' '
+ test_when_finished "rm -fr shared member" &&
+
+ # Create a shared repository that will serve as the alternate object
+ # database for the member linked to it. It has got some objects on its
+ # own that are packed into a single packfile.
+ git init shared &&
+ test_commit -C shared common-object &&
+ git -C shared repack -ad &&
+
+ # We create member so that its alternates file points to the shared
+ # repository. We then create a commit in it so that git-repack(1) has
+ # something to repack.
+ # of the shared object database.
+ git clone --shared shared member &&
+ test_commit -C member unique-object &&
+ git -C member repack --geometric=2 --write-midx 2>err &&
+ test_must_be_empty err &&
+
+ # We should see that a new packfile was generated.
+ find shared/.git/objects/pack -type f -name "*.pack" >packs &&
+ test_line_count = 1 packs &&
+
+ # We should also see a multi-pack-index. This multi-pack-index should
+ # never refer to any packfiles in the alternate object database.
+ test_path_is_file member/.git/objects/pack/multi-pack-index &&
+ test-tool read-midx member/.git/objects >packs.midx &&
+ grep "^pack-.*\.idx$" packs.midx | sort >actual &&
+ basename member/.git/objects/pack/pack-*.idx >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '--geometric --with-midx with no local objects' '
+ test_when_finished "rm -fr shared member" &&
+
+ # Create a repository with a single packfile that acts as alternate
+ # object database.
+ git init shared &&
+ test_commit -C shared "shared-objects" &&
+ git -C shared repack -ad &&
+
+ # Create a second repository linked to the first one and perform a
+ # geometric repack on it.
+ git clone --shared shared member &&
+ git -C member repack --geometric 2 --write-midx 2>err &&
+ test_must_be_empty err &&
+
+ # Assert that we wrote neither a new packfile nor a multi-pack-index.
+ # We should not have a packfile because the single packfile in the
+ # alternate object database does not invalidate the geometric sequence.
+ # And we should not have a multi-pack-index because these only index
+ # local packfiles, and there are none.
+ test_dir_is_empty member/$packdir
+'
+
+test_expect_success '--geometric with same pack in main and alternate ODB' '
+ test_when_finished "rm -fr shared member" &&
+
+ # Create a repository with a single packfile that acts as alternate
+ # object database.
+ git init shared &&
+ test_commit -C shared "shared-objects" &&
+ git -C shared repack -ad &&
+
+ # We create the member repository as an exact copy so that it has the
+ # same packfile.
+ cp -r shared member &&
+ test-tool path-utils real_path shared/.git/objects >member/.git/objects/info/alternates &&
+ find shared/.git/objects -type f >expected-files &&
+
+ # Verify that we can repack objects as expected without observing any
+ # error. Having the same packfile in both ODBs used to cause an error
+ # in git-pack-objects(1).
+ git -C member repack --geometric 2 2>err &&
+ test_must_be_empty err &&
+ # Nothing should have changed.
+ find shared/.git/objects -type f >actual-files &&
+ test_cmp expected-files actual-files
+'
+
+test_expect_success '--geometric -l with non-intact geometric sequence across ODBs' '
+ test_when_finished "rm -fr shared member" &&
+
+ git init shared &&
+ test_commit_bulk -C shared --start=1 1 &&
+
+ git clone --shared shared member &&
+ test_commit_bulk -C member --start=2 1 &&
+
+ # Verify that our assumptions actually hold: both generated packfiles
+ # should have three objects and should be non-equal.
+ packed_objects shared/.git/objects/pack/pack-*.idx >shared-objects &&
+ packed_objects member/.git/objects/pack/pack-*.idx >member-objects &&
+ test_line_count = 3 shared-objects &&
+ test_line_count = 3 member-objects &&
+ ! test_cmp shared-objects member-objects &&
+
+ # Perform the geometric repack. With `-l`, we should only see the local
+ # packfile and thus arrive at the conclusion that the geometric
+ # sequence is intact. We thus expect no changes.
+ #
+ # Note that we are tweaking mtimes of the packfiles so that we can
+ # verify they did not change. This is done in order to detect the case
+ # where we do repack objects, but the resulting packfile is the same.
+ test-tool chmtime --verbose =0 member/.git/objects/pack/* >expected-member-packs &&
+ git -C member repack --geometric=2 -l -d &&
+ test-tool chmtime --verbose member/.git/objects/pack/* >actual-member-packs &&
+ test_cmp expected-member-packs actual-member-packs &&
+
+ {
+ packed_objects shared/.git/objects/pack/pack-*.idx &&
+ packed_objects member/.git/objects/pack/pack-*.idx
+ } | sort >expected-objects &&
+
+ # On the other hand, when doing a non-local geometric repack we should
+ # see both packfiles and thus repack them. We expect that the shared
+ # object database was not changed.
+ test-tool chmtime --verbose =0 shared/.git/objects/pack/* >expected-shared-packs &&
+ git -C member repack --geometric=2 -d &&
+ test-tool chmtime --verbose shared/.git/objects/pack/* >actual-shared-packs &&
+ test_cmp expected-shared-packs actual-shared-packs &&
+
+ # Furthermore, we expect that the member repository now has a single
+ # packfile that contains the combined shared and non-shared objects.
+ ls member/.git/objects/pack/pack-*.idx >actual &&
+ test_line_count = 1 actual &&
+ packed_objects member/.git/objects/pack/pack-*.idx >actual-objects &&
+ test_line_count = 6 actual-objects &&
+ test_cmp expected-objects actual-objects
+'
+
+test_expect_success '--geometric -l disables writing bitmaps with non-local packfiles' '
+ test_when_finished "rm -fr shared member" &&
+
+ git init shared &&
+ test_commit_bulk -C shared --start=1 1 &&
+
+ git clone --shared shared member &&
+ test_commit_bulk -C member --start=2 1 &&
+
+ # When performing a geometric repack with `-l` while connected to an
+ # alternate object database that has a packfile we do not have full
+ # coverage of objects. As a result, we expect that writing the bitmap
+ # will be disabled.
+ git -C member repack -l --geometric=2 --write-midx --write-bitmap-index 2>err &&
+ cat >expect <<-EOF &&
+ warning: disabling bitmap writing, as some objects are not being packed
+ EOF
+ test_cmp expect err &&
+ test_path_is_missing member/.git/objects/pack/multi-pack-index-*.bitmap &&
+
+ # On the other hand, when we repack without `-l`, we should see that
+ # the bitmap gets created.
+ git -C member repack --geometric=2 --write-midx --write-bitmap-index 2>err &&
+ test_must_be_empty err &&
+ test_path_is_file member/.git/objects/pack/multi-pack-index-*.bitmap
+'
+
test_done
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 0de83b5d2b..6520346246 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -2326,6 +2326,37 @@ test_expect_success $PREREQ 'invoke hook' '
)
'
+expected_file_counter_output () {
+ total=$1
+ count=0
+ while test $count -ne $total
+ do
+ count=$((count + 1)) &&
+ echo "$count/$total" || return
+ done
+}
+
+test_expect_success $PREREQ '--validate hook allows counting of messages' '
+ test_when_finished "rm -rf my-hooks.log" &&
+ test_config core.hooksPath "my-hooks" &&
+ mkdir -p my-hooks &&
+
+ write_script my-hooks/sendemail-validate <<-\EOF &&
+ num=$GIT_SENDEMAIL_FILE_COUNTER &&
+ tot=$GIT_SENDEMAIL_FILE_TOTAL &&
+ echo "$num/$tot" >>my-hooks.log || exit 1
+ EOF
+
+ >my-hooks.log &&
+ expected_file_counter_output 4 >expect &&
+ git send-email \
+ --from="Example <from@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --validate -3 --cover-letter --force &&
+ test_cmp expect my-hooks.log
+'
+
test_expect_success $PREREQ 'test that send-email works outside a repo' '
nongit git send-email \
--from="Example <nobody@example.com>" \
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index aa55b41b9a..ac237a1f90 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -388,9 +388,7 @@ test_expect_success 'B: accept branch name "TEMP_TAG"' '
INPUT_END
- test_when_finished "rm -f .git/TEMP_TAG
- git gc
- git prune" &&
+ test_when_finished "rm -f .git/TEMP_TAG && git gc --prune=now" &&
git fast-import <input &&
test $(test-tool ref-store main resolve-ref TEMP_TAG 0 | cut -f1 -d " " ) != "$ZERO_OID" &&
test $(git rev-parse main) = $(git rev-parse TEMP_TAG^)
@@ -406,8 +404,7 @@ test_expect_success 'B: accept empty committer' '
INPUT_END
test_when_finished "git update-ref -d refs/heads/empty-committer-1
- git gc
- git prune" &&
+ git gc --prune=now" &&
git fast-import <input &&
out=$(git fsck) &&
echo "$out" &&
@@ -452,8 +449,7 @@ test_expect_success 'B: accept and fixup committer with no name' '
INPUT_END
test_when_finished "git update-ref -d refs/heads/empty-committer-2
- git gc
- git prune" &&
+ git gc --prune=now" &&
git fast-import <input &&
out=$(git fsck) &&
echo "$out" &&
@@ -1778,8 +1774,7 @@ test_expect_success 'P: verbatim SHA gitlinks' '
INPUT_END
git branch -D sub &&
- git gc &&
- git prune &&
+ git gc --prune=now &&
git fast-import <input &&
test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)
'