| #!/bin/sh |
| |
| test_description='git repack --drop-filtered enumerates filtered promisor blobs' |
| |
| . ./test-lib.sh |
| |
| # Delete a loose or packed object from "repo". |
| delete_object () { |
| local repo="$1" && |
| local obj="$2" && |
| local path="$repo/.git/objects/$(test_oid_to_path "$obj")" && |
| rm "$path" |
| } |
| |
| # Pack the objects into a promisor pack inside "repo". It is a pack |
| # accompanied by an empty ".promisor" marker file. Objects |
| # in such a pack are treated as recoverable from the promisor remote. |
| pack_as_from_promisor () { |
| HASH=$(git -C repo pack-objects .git/objects/pack/pack) && |
| >repo/.git/objects/pack/pack-$HASH.promisor && |
| echo $HASH |
| } |
| |
| # Write a blob of $1 bytes into "repo", record it as coming from the |
| # promisor remote, and remove the loose copy so the object is only |
| # present in the promisor pack. |
| promisor_blob () { |
| test-tool genrandom "$1" "$2" >blob_content && |
| OID=$(git -C repo hash-object -w --stdin <blob_content) && |
| printf "%s\n" "$OID" | pack_as_from_promisor >/dev/null && |
| delete_object repo "$OID" && |
| echo "$OID" |
| } |
| |
| # Check option validation before any promisor walk |
| test_expect_success 'setup plain repo for validation' ' |
| git init plain && |
| test_commit -C plain initial && |
| git clone --bare plain plain.git && |
| git -C plain.git repack -a -d |
| ' |
| |
| test_expect_success '--drop-filtered requires --filter' ' |
| test_must_fail git -C plain.git repack --drop-filtered --dry-run -a 2>err && |
| test_grep "drop-filtered requires --filter" err |
| ' |
| |
| test_expect_success '--drop-filtered cannot be used with --filter-to' ' |
| test_must_fail git -C plain.git repack --drop-filtered \ |
| --filter=blob:limit=1k --filter-to=./filter-out 2>err && |
| test_grep "options .--drop-filtered. and .--filter-to. cannot be used together" err |
| ' |
| |
| test_expect_success '--dry-run only takes effect with --drop-filtered' ' |
| test_must_fail git -C plain.git repack --dry-run 2>err && |
| test_grep "dry-run only takes effect with --drop-filtered" err |
| ' |
| |
| test_expect_success '--drop-filtered requires -a' ' |
| test_must_fail git -C plain.git repack --drop-filtered \ |
| --filter=blob:limit=1k --dry-run 2>err && |
| test_grep "drop-filtered requires -a" err |
| ' |
| |
| test_expect_success '--drop-filtered fails with --write-bitmap-index' ' |
| test_must_fail git -C plain.git repack --drop-filtered \ |
| --filter=blob:limit=1k --dry-run -a -b 2>err && |
| test_grep "options .--drop-filtered. and .--write-bitmap-index. cannot be used together" err |
| ' |
| |
| test_expect_success '--drop-filtered rejects explicit -b even when repack.writeBitmaps=true' ' |
| test_must_fail git -C plain.git -c repack.writeBitmaps=true \ |
| repack --drop-filtered --filter=blob:limit=1k --dry-run -a -b 2>err && |
| test_grep "options .--drop-filtered. and .--write-bitmap-index. cannot be used together" err |
| ' |
| |
| test_expect_success '--drop-filtered fails without a promisor remote' ' |
| test_must_fail git -C plain.git repack --drop-filtered \ |
| --filter=blob:limit=1k --dry-run -a 2>err && |
| test_grep "drop-filtered requires a promisor remote" err |
| ' |
| |
| # Enumeration tests using promisor pack |
| test_expect_success 'setup repo with a promisor remote' ' |
| rm -rf repo && |
| test_create_repo repo && |
| test_commit -C repo base && |
| |
| # Mark the repo as a partial clone with a promisor remote so the |
| # promisor walk and the safety guard are satisfied. |
| git -C repo config core.repositoryformatversion 1 && |
| git -C repo config extensions.partialclone origin && |
| git -C repo config remote.origin.promisor true && |
| git -C repo config remote.origin.url "." && |
| |
| BIG=$(promisor_blob big 3072) && |
| SMALL=$(promisor_blob small 512) && |
| echo "$BIG" >big_oid && |
| echo "$SMALL" >small_oid |
| ' |
| |
| test_expect_success 'promisor blob over the threshold is listed' ' |
| BIG=$(cat big_oid) && |
| SMALL=$(cat small_oid) && |
| |
| git -C repo -c repack.writeBitmaps=false \ |
| repack --drop-filtered --filter=blob:limit=1k --dry-run -a >out && |
| |
| test_grep "$BIG" out && |
| test_grep ! "$SMALL" out |
| ' |
| |
| test_expect_success 'locally created blob is never listed' ' |
| BIG=$(cat big_oid) && |
| |
| # Large blob that exists only locally must never be a drop candidate. |
| # Dropping it would be unrecoverable. |
| test-tool genrandom local 4096 >local_content && |
| LOCAL=$(git -C repo hash-object -w --stdin <local_content) && |
| |
| git -C repo -c repack.writeBitmaps=false \ |
| repack --drop-filtered --filter=blob:limit=1k --dry-run -a >out && |
| |
| test_grep "$BIG" out && |
| test_grep ! "$LOCAL" out |
| ' |
| |
| test_expect_success '--dry-run does not remove the filtered objects' ' |
| BIG=$(cat big_oid) && |
| |
| git -C repo -c repack.writeBitmaps=false \ |
| repack --drop-filtered --filter=blob:limit=1k --dry-run -a >out && |
| |
| # Candidate blob must still be present after a dry run. |
| git -C repo cat-file -e "$BIG" |
| ' |
| |
| test_expect_success '--drop-filtered removes the promisor blob locally' ' |
| BIG=$(cat big_oid) && |
| SMALL=$(cat small_oid) && |
| |
| git -C repo -c repack.writeBitmaps=false \ |
| repack --drop-filtered --filter=blob:limit=1k -a && |
| |
| git -C repo cat-file --batch-all-objects --batch-check="%(objectname)" >present && |
| test_grep ! "$BIG" present && |
| test_grep "$SMALL" present |
| ' |
| |
| test_expect_success '--drop-filtered refuses when a merge is in progress' ' |
| test_when_finished "git -C repo merge --abort || :" && |
| |
| # Create a conflicting merge so wt_status reports it. |
| git -C repo checkout -B mergebase base && |
| echo one >repo/conflict.txt && |
| git -C repo add conflict.txt && |
| git -C repo commit -m one && |
| |
| git -C repo checkout -B mergeother base && |
| echo two >repo/conflict.txt && |
| git -C repo add conflict.txt && |
| git -C repo commit -m two && |
| |
| test_must_fail git -C repo merge mergebase && |
| |
| test_must_fail git -C repo -c repack.writeBitmaps=false \ |
| repack --drop-filtered --filter=blob:limit=1k --dry-run -a 2>err && |
| test_grep "in progress" err |
| ' |
| |
| test_expect_success '--drop-filtered refuses to drop an index-referenced blob' ' |
| # Create a large blob, add it to the index and make it a promisor object |
| # so the index references it and enumeration picks it up. |
| test-tool genrandom idx 4096 >repo/tracked-big.bin && |
| git -C repo add tracked-big.bin && |
| OID=$(git -C repo rev-parse :tracked-big.bin) && |
| printf "%s\n" "$OID" | pack_as_from_promisor >/dev/null && |
| delete_object repo "$OID" && |
| |
| test_must_fail git -C repo -c repack.writeBitmaps=false \ |
| repack --drop-filtered --filter=blob:limit=1k --dry-run -a 2>err && |
| test_grep "referenced by the current index" err |
| ' |
| |
| test_done |