mirror of
https://github.com/git/git.git
synced 2024-12-12 11:24:02 +08:00
0efa3d74e7
Split-index fix. * nd/split-index-null-base-fix: read-cache.c: fix writing "link" index ext with null base oid
494 lines
14 KiB
Bash
Executable File
494 lines
14 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='split index mode tests'
|
|
|
|
. ./test-lib.sh
|
|
|
|
# We need total control of index splitting here
|
|
sane_unset GIT_TEST_SPLIT_INDEX
|
|
|
|
# Testing a hard coded SHA against an index with an extension
|
|
# that can vary from run to run is problematic so we disable
|
|
# those extensions.
|
|
sane_unset GIT_TEST_FSMONITOR
|
|
sane_unset GIT_TEST_INDEX_THREADS
|
|
|
|
# Create a file named as $1 with content read from stdin.
|
|
# Set the file's mtime to a few seconds in the past to avoid racy situations.
|
|
create_non_racy_file () {
|
|
cat >"$1" &&
|
|
test-tool chmtime =-5 "$1"
|
|
}
|
|
|
|
test_expect_success 'enable split index' '
|
|
git config splitIndex.maxPercentChange 100 &&
|
|
git update-index --split-index &&
|
|
test-tool dump-split-index .git/index >actual &&
|
|
indexversion=$(test-tool index-version <.git/index) &&
|
|
|
|
# NEEDSWORK: Stop hard-coding checksums.
|
|
if test "$indexversion" = "4"
|
|
then
|
|
own=432ef4b63f32193984f339431fd50ca796493569
|
|
base=508851a7f0dfa8691e9f69c7f055865389012491
|
|
else
|
|
own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
|
|
base=39d890139ee5356c7ef572216cebcd27aa41f9df
|
|
fi &&
|
|
|
|
cat >expect <<-EOF &&
|
|
own $own
|
|
base $base
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'add one file' '
|
|
create_non_racy_file one &&
|
|
git update-index --add one &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 $EMPTY_BLOB 0 one
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
base $base
|
|
100644 $EMPTY_BLOB 0 one
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'disable split index' '
|
|
git update-index --no-split-index &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 $EMPTY_BLOB 0 one
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
|
|
BASE=$(test-tool dump-split-index .git/index | sed -n "s/^own/base/p") &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
not a split index
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'enable split index again, "one" now belongs to base index"' '
|
|
git update-index --split-index &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 $EMPTY_BLOB 0 one
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'modify original file, base index untouched' '
|
|
echo modified | create_non_racy_file one &&
|
|
git update-index one &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
q_to_tab >expect <<-EOF &&
|
|
$BASE
|
|
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
|
|
replacements: 0
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'add another file, which stays index' '
|
|
create_non_racy_file two &&
|
|
git update-index --add two &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
|
|
100644 $EMPTY_BLOB 0 two
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
q_to_tab >expect <<-EOF &&
|
|
$BASE
|
|
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
|
|
100644 $EMPTY_BLOB 0 two
|
|
replacements: 0
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'remove file not in base index' '
|
|
git update-index --force-remove two &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
q_to_tab >expect <<-EOF &&
|
|
$BASE
|
|
100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
|
|
replacements: 0
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'remove file in base index' '
|
|
git update-index --force-remove one &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
test_must_be_empty ls-files.actual &&
|
|
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
replacements:
|
|
deletions: 0
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'add original file back' '
|
|
create_non_racy_file one &&
|
|
git update-index --add one &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 $EMPTY_BLOB 0 one
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
100644 $EMPTY_BLOB 0 one
|
|
replacements:
|
|
deletions: 0
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'add new file' '
|
|
create_non_racy_file two &&
|
|
git update-index --add two &&
|
|
git ls-files --stage >actual &&
|
|
cat >expect <<-EOF &&
|
|
100644 $EMPTY_BLOB 0 one
|
|
100644 $EMPTY_BLOB 0 two
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'unify index, two files remain' '
|
|
git update-index --no-split-index &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 $EMPTY_BLOB 0 one
|
|
100644 $EMPTY_BLOB 0 two
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
not a split index
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'rev-parse --shared-index-path' '
|
|
test_create_repo split-index &&
|
|
(
|
|
cd split-index &&
|
|
git update-index --split-index &&
|
|
echo .git/sharedindex* >expect &&
|
|
git rev-parse --shared-index-path >actual &&
|
|
test_cmp expect actual &&
|
|
mkdir subdirectory &&
|
|
cd subdirectory &&
|
|
echo ../.git/sharedindex* >expect &&
|
|
git rev-parse --shared-index-path >actual &&
|
|
test_cmp expect actual
|
|
)
|
|
'
|
|
|
|
test_expect_success 'set core.splitIndex config variable to true' '
|
|
git config core.splitIndex true &&
|
|
create_non_racy_file three &&
|
|
git update-index --add three &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one
|
|
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 three
|
|
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'set core.splitIndex config variable to false' '
|
|
git config core.splitIndex false &&
|
|
git update-index --force-remove three &&
|
|
git ls-files --stage >ls-files.actual &&
|
|
cat >ls-files.expect <<-EOF &&
|
|
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one
|
|
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two
|
|
EOF
|
|
test_cmp ls-files.expect ls-files.actual &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
not a split index
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'set core.splitIndex config variable back to true' '
|
|
git config core.splitIndex true &&
|
|
create_non_racy_file three &&
|
|
git update-index --add three &&
|
|
BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual &&
|
|
create_non_racy_file four &&
|
|
git update-index --add four &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 four
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
|
|
git config --unset splitIndex.maxPercentChange &&
|
|
create_non_racy_file five &&
|
|
git update-index --add five &&
|
|
BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual &&
|
|
create_non_racy_file six &&
|
|
git update-index --add six &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 six
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'check splitIndex.maxPercentChange set to 0' '
|
|
git config splitIndex.maxPercentChange 0 &&
|
|
create_non_racy_file seven &&
|
|
git update-index --add seven &&
|
|
BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual &&
|
|
create_non_racy_file eight &&
|
|
git update-index --add eight &&
|
|
BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
|
|
test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
|
|
cat >expect <<-EOF &&
|
|
$BASE
|
|
replacements:
|
|
deletions:
|
|
EOF
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'shared index files expire after 2 weeks by default' '
|
|
create_non_racy_file ten &&
|
|
git update-index --add ten &&
|
|
test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
|
|
just_under_2_weeks_ago=$((5-14*86400)) &&
|
|
test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
|
|
create_non_racy_file eleven &&
|
|
git update-index --add eleven &&
|
|
test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
|
|
just_over_2_weeks_ago=$((-1-14*86400)) &&
|
|
test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
|
|
create_non_racy_file twelve &&
|
|
git update-index --add twelve &&
|
|
test $(ls .git/sharedindex.* | wc -l) -le 2
|
|
'
|
|
|
|
test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
|
|
git config splitIndex.sharedIndexExpire "16.days.ago" &&
|
|
test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
|
|
create_non_racy_file thirteen &&
|
|
git update-index --add thirteen &&
|
|
test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
|
|
just_over_16_days_ago=$((-1-16*86400)) &&
|
|
test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
|
|
create_non_racy_file fourteen &&
|
|
git update-index --add fourteen &&
|
|
test $(ls .git/sharedindex.* | wc -l) -le 2
|
|
'
|
|
|
|
test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
|
|
git config splitIndex.sharedIndexExpire never &&
|
|
just_10_years_ago=$((-365*10*86400)) &&
|
|
test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
|
|
create_non_racy_file fifteen &&
|
|
git update-index --add fifteen &&
|
|
test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
|
|
git config splitIndex.sharedIndexExpire now &&
|
|
just_1_second_ago=-1 &&
|
|
test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
|
|
create_non_racy_file sixteen &&
|
|
git update-index --add sixteen &&
|
|
test $(ls .git/sharedindex.* | wc -l) -le 2
|
|
'
|
|
|
|
test_expect_success POSIXPERM 'same mode for index & split index' '
|
|
git init same-mode &&
|
|
(
|
|
cd same-mode &&
|
|
test_commit A &&
|
|
test_modebits .git/index >index_mode &&
|
|
test_must_fail git config core.sharedRepository &&
|
|
git -c core.splitIndex=true status &&
|
|
shared=$(ls .git/sharedindex.*) &&
|
|
case "$shared" in
|
|
*" "*)
|
|
# we have more than one???
|
|
false ;;
|
|
*)
|
|
test_modebits "$shared" >split_index_mode &&
|
|
test_cmp index_mode split_index_mode ;;
|
|
esac
|
|
)
|
|
'
|
|
|
|
while read -r mode modebits
|
|
do
|
|
test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
|
|
# Remove existing shared index files
|
|
git config core.splitIndex false &&
|
|
git update-index --force-remove one &&
|
|
rm -f .git/sharedindex.* &&
|
|
# Create one new shared index file
|
|
git config core.sharedrepository "$mode" &&
|
|
git config core.splitIndex true &&
|
|
create_non_racy_file one &&
|
|
git update-index --add one &&
|
|
echo "$modebits" >expect &&
|
|
test_modebits .git/index >actual &&
|
|
test_cmp expect actual &&
|
|
shared=$(ls .git/sharedindex.*) &&
|
|
case "$shared" in
|
|
*" "*)
|
|
# we have more than one???
|
|
false ;;
|
|
*)
|
|
test_modebits "$shared" >actual &&
|
|
test_cmp expect actual ;;
|
|
esac
|
|
'
|
|
done <<\EOF
|
|
0666 -rw-rw-rw-
|
|
0642 -rw-r---w-
|
|
EOF
|
|
|
|
test_expect_success POSIXPERM,SANITY 'graceful handling when splitting index is not allowed' '
|
|
test_create_repo ro &&
|
|
(
|
|
cd ro &&
|
|
test_commit initial &&
|
|
git update-index --split-index &&
|
|
test -f .git/sharedindex.*
|
|
) &&
|
|
cp ro/.git/index new-index &&
|
|
test_when_finished "chmod u+w ro/.git" &&
|
|
chmod u-w ro/.git &&
|
|
GIT_INDEX_FILE="$(pwd)/new-index" git -C ro update-index --split-index &&
|
|
chmod u+w ro/.git &&
|
|
rm ro/.git/sharedindex.* &&
|
|
GIT_INDEX_FILE=new-index git ls-files >actual &&
|
|
echo initial.t >expected &&
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 'writing split index with null sha1 does not write cache tree' '
|
|
git config core.splitIndex true &&
|
|
git config splitIndex.maxPercentChange 0 &&
|
|
git commit -m "commit" &&
|
|
{
|
|
git ls-tree HEAD &&
|
|
printf "160000 commit $ZERO_OID\\tbroken\\n"
|
|
} >broken-tree &&
|
|
echo "add broken entry" >msg &&
|
|
|
|
tree=$(git mktree <broken-tree) &&
|
|
test_tick &&
|
|
commit=$(git commit-tree $tree -p HEAD <msg) &&
|
|
git update-ref HEAD "$commit" &&
|
|
GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
|
|
test_might_fail test-tool dump-cache-tree >cache-tree.out &&
|
|
test_line_count = 0 cache-tree.out
|
|
'
|
|
|
|
test_expect_success 'do not refresh null base index' '
|
|
test_create_repo merge &&
|
|
(
|
|
cd merge &&
|
|
test_commit initial &&
|
|
git checkout -b side-branch &&
|
|
test_commit extra &&
|
|
git checkout master &&
|
|
git update-index --split-index &&
|
|
test_commit more &&
|
|
# must not write a new shareindex, or we wont catch the problem
|
|
git -c splitIndex.maxPercentChange=100 merge --no-edit side-branch 2>err &&
|
|
# i.e. do not expect warnings like
|
|
# could not freshen shared index .../shareindex.00000...
|
|
test_must_be_empty err
|
|
)
|
|
'
|
|
|
|
test_done
|