2015-07-18 05:19:27 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='sparse checkout scope tests'
|
|
|
|
|
2020-11-19 07:44:21 +08:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-19 07:44:19 +08:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2015-07-18 05:19:27 +08:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success 'setup' '
|
|
|
|
echo "initial" >a &&
|
|
|
|
echo "initial" >b &&
|
|
|
|
echo "initial" >c &&
|
|
|
|
git add a b c &&
|
|
|
|
git commit -m "initial commit"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'create feature branch' '
|
|
|
|
git checkout -b feature &&
|
|
|
|
echo "modified" >b &&
|
|
|
|
echo "modified" >c &&
|
|
|
|
git add b c &&
|
|
|
|
git commit -m "modification"
|
|
|
|
'
|
|
|
|
|
2020-11-19 07:44:21 +08:00
|
|
|
test_expect_success 'perform sparse checkout of main' '
|
2015-07-18 05:19:27 +08:00
|
|
|
git config --local --bool core.sparsecheckout true &&
|
|
|
|
echo "!/*" >.git/info/sparse-checkout &&
|
|
|
|
echo "/a" >>.git/info/sparse-checkout &&
|
|
|
|
echo "/c" >>.git/info/sparse-checkout &&
|
2020-11-19 07:44:21 +08:00
|
|
|
git checkout main &&
|
2015-07-18 05:19:27 +08:00
|
|
|
test_path_is_file a &&
|
|
|
|
test_path_is_missing b &&
|
|
|
|
test_path_is_file c
|
|
|
|
'
|
|
|
|
|
2020-11-19 07:44:21 +08:00
|
|
|
test_expect_success 'merge feature branch into sparse checkout of main' '
|
2015-07-18 05:19:27 +08:00
|
|
|
git merge feature &&
|
|
|
|
test_path_is_file a &&
|
|
|
|
test_path_is_missing b &&
|
|
|
|
test_path_is_file c &&
|
|
|
|
test "$(cat c)" = "modified"
|
|
|
|
'
|
|
|
|
|
2020-11-19 07:44:21 +08:00
|
|
|
test_expect_success 'return to full checkout of main' '
|
2015-07-18 05:19:27 +08:00
|
|
|
git checkout feature &&
|
|
|
|
echo "/*" >.git/info/sparse-checkout &&
|
2020-11-19 07:44:21 +08:00
|
|
|
git checkout main &&
|
2015-07-18 05:19:27 +08:00
|
|
|
test_path_is_file a &&
|
|
|
|
test_path_is_file b &&
|
|
|
|
test_path_is_file c &&
|
|
|
|
test "$(cat b)" = "modified"
|
|
|
|
'
|
|
|
|
|
repo_read_index: add config to expect files outside sparse patterns
Typically with sparse checkouts, we expect files outside the sparsity
patterns to be marked as SKIP_WORKTREE and be missing from the working
tree. Sometimes this expectation would be violated however; including
in cases such as:
* users grabbing files from elsewhere and writing them to the worktree
(perhaps by editing a cached copy in an editor, copying/renaming, or
even untarring)
* various git commands having incomplete or no support for the
SKIP_WORKTREE bit[1,2]
* users attempting to "abort" a sparse-checkout operation with a
not-so-early Ctrl+C (updating $GIT_DIR/info/sparse-checkout and the
working tree is not atomic)[3].
When the SKIP_WORKTREE bit in the index did not reflect the presence of
the file in the working tree, it traditionally caused confusion and was
difficult to detect and recover from. So, in a sparse checkout, since
af6a51875a (repo_read_index: clear SKIP_WORKTREE bit from files present
in worktree, 2022-01-14), Git automatically clears the SKIP_WORKTREE
bit at index read time for entries corresponding to files that are
present in the working tree.
There is another workflow, however, where it is expected that paths
outside the sparsity patterns appear to exist in the working tree and
that they do not lose the SKIP_WORKTREE bit, at least until they get
modified. A Git-aware virtual file system[4] takes advantage of its
position as a file system driver to expose all files in the working
tree, fetch them on demand using partial clone on access, and tell Git
to pay attention to them on demand by updating the sparse checkout
pattern on writes. This means that commands like "git status" only have
to examine files that have potentially been modified, whereas commands
like "ls" are able to show the entire codebase without requiring manual
updates to the sparse checkout pattern.
Thus since af6a51875a, Git with such Git-aware virtual file systems
unsets the SKIP_WORKTREE bit for all files and commands like "git
status" have to fetch and examine them all.
Introduce a configuration setting sparse.expectFilesOutsideOfPatterns to
allow limiting the tracked set of files to a small set once again. A
Git-aware virtual file system or other application that wants to
maintain files outside of the sparse checkout can set this in a
repository to instruct Git not to check for the presence of
SKIP_WORKTREE files. The setting defaults to false, so most users of
sparse checkout will still get the benefit of an automatically updating
index to recover from the variety of difficult issues detailed in
af6a51875a for paths with SKIP_WORKTREE set despite the path being
present.
[1] https://lore.kernel.org/git/xmqqbmb1a7ga.fsf@gitster-ct.c.googlers.com/
[2] The three long paragraphs in the middle of
https://lore.kernel.org/git/CABPp-BH9tju7WVm=QZDOvaMDdZbpNXrVWQdN-jmfN8wC6YVhmw@mail.gmail.com/
[3] https://lore.kernel.org/git/CABPp-BFnFpzwGC11TLoLs8YK5yiisA5D5-fFjXnJsbESVDwZsA@mail.gmail.com/
[4] such as the vfsd described in
https://lore.kernel.org/git/20220207190320.2960362-1-jonathantanmy@google.com/
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-02-26 14:12:22 +08:00
|
|
|
test_expect_success 'skip-worktree on files outside sparse patterns' '
|
|
|
|
git sparse-checkout disable &&
|
|
|
|
git sparse-checkout set --no-cone "a*" &&
|
|
|
|
git checkout-index --all --ignore-skip-worktree-bits &&
|
|
|
|
|
|
|
|
git ls-files -t >output &&
|
|
|
|
! grep ^S output >actual &&
|
|
|
|
test_must_be_empty actual &&
|
|
|
|
|
|
|
|
test_config sparse.expectFilesOutsideOfPatterns true &&
|
|
|
|
cat <<-\EOF >expect &&
|
|
|
|
S b
|
|
|
|
S c
|
|
|
|
EOF
|
|
|
|
git ls-files -t >output &&
|
|
|
|
grep ^S output >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2018-10-10 02:40:37 +08:00
|
|
|
test_expect_success 'in partial clone, sparse checkout only fetches needed blobs' '
|
|
|
|
test_create_repo server &&
|
|
|
|
git clone "file://$(pwd)/server" client &&
|
|
|
|
|
|
|
|
test_config -C server uploadpack.allowfilter 1 &&
|
|
|
|
test_config -C server uploadpack.allowanysha1inwant 1 &&
|
|
|
|
echo a >server/a &&
|
|
|
|
echo bb >server/b &&
|
|
|
|
mkdir server/c &&
|
|
|
|
echo ccc >server/c/c &&
|
|
|
|
git -C server add a b c/c &&
|
|
|
|
git -C server commit -m message &&
|
|
|
|
|
|
|
|
test_config -C client core.sparsecheckout 1 &&
|
|
|
|
echo "!/*" >client/.git/info/sparse-checkout &&
|
|
|
|
echo "/a" >>client/.git/info/sparse-checkout &&
|
|
|
|
git -C client fetch --filter=blob:none origin &&
|
|
|
|
git -C client checkout FETCH_HEAD &&
|
|
|
|
|
|
|
|
git -C client rev-list HEAD \
|
|
|
|
--quiet --objects --missing=print >unsorted_actual &&
|
|
|
|
(
|
|
|
|
printf "?" &&
|
|
|
|
git hash-object server/b &&
|
|
|
|
printf "?" &&
|
|
|
|
git hash-object server/c/c
|
|
|
|
) >unsorted_expect &&
|
|
|
|
sort unsorted_actual >actual &&
|
|
|
|
sort unsorted_expect >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2015-07-18 05:19:27 +08:00
|
|
|
test_done
|