2011-10-01 01:33:15 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='checkout $tree -- $paths'
|
2020-11-19 07:44:22 +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
|
|
|
|
|
2021-11-17 02:27:38 +08:00
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
2011-10-01 01:33:15 +08:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success setup '
|
|
|
|
mkdir dir &&
|
2020-11-19 07:44:22 +08:00
|
|
|
>dir/main &&
|
2011-10-01 01:33:15 +08:00
|
|
|
echo common >dir/common &&
|
2020-11-19 07:44:22 +08:00
|
|
|
git add dir/main dir/common &&
|
|
|
|
test_tick && git commit -m "main has dir/main" &&
|
2011-10-01 01:33:15 +08:00
|
|
|
git checkout -b next &&
|
2020-11-19 07:44:22 +08:00
|
|
|
git mv dir/main dir/next0 &&
|
2011-10-01 01:33:15 +08:00
|
|
|
echo next >dir/next1 &&
|
|
|
|
git add dir &&
|
2020-11-19 07:44:22 +08:00
|
|
|
test_tick && git commit -m "next has dir/next but not dir/main"
|
2011-10-01 01:33:15 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'checking out paths out of a tree does not clobber unrelated paths' '
|
|
|
|
git checkout next &&
|
|
|
|
git reset --hard &&
|
|
|
|
rm dir/next0 &&
|
|
|
|
cat dir/common >expect.common &&
|
|
|
|
echo modified >expect.next1 &&
|
|
|
|
cat expect.next1 >dir/next1 &&
|
|
|
|
echo untracked >expect.next2 &&
|
|
|
|
cat expect.next2 >dir/next2 &&
|
|
|
|
|
2020-11-19 07:44:22 +08:00
|
|
|
git checkout main dir &&
|
2011-10-01 01:33:15 +08:00
|
|
|
|
|
|
|
test_cmp expect.common dir/common &&
|
2020-11-19 07:44:22 +08:00
|
|
|
test_path_is_file dir/main &&
|
|
|
|
git diff --exit-code main dir/main &&
|
2011-10-01 01:33:15 +08:00
|
|
|
|
|
|
|
test_path_is_missing dir/next0 &&
|
|
|
|
test_cmp expect.next1 dir/next1 &&
|
|
|
|
test_path_is_file dir/next2 &&
|
|
|
|
test_must_fail git ls-files --error-unmatch dir/next2 &&
|
|
|
|
test_cmp expect.next2 dir/next2
|
|
|
|
'
|
|
|
|
|
checkout: avoid unnecessary match_pathspec calls
In checkout_paths() we do this
- for all updated items, call match_pathspec
- for all items, call match_pathspec (inside unmerge_cache)
- for all items, call match_pathspec (for showing "path .. is unmerged)
- for updated items, call match_pathspec and update paths
That's a lot of duplicate match_pathspec(s) and the function is not
exactly cheap to be called so many times, especially on large indexes.
This patch makes it call match_pathspec once per updated index entry,
save the result in ce_flags and reuse the results in the following
loops.
The changes in 0a1283b (checkout $tree $path: do not clobber local
changes in $path not in $tree - 2011-09-30) limit the affected paths
to ones we read from $tree. We do not do anything to other modified
entries in this case, so the "for all items" above could be modified
to "for all updated items". But..
The command's behavior now is modified slightly: unmerged entries that
match $path, but not updated by $tree, are now NOT touched. Although
this should be considered a bug fix, not a regression. A new test is
added for this change.
And while at there, free ps_matched after use.
The following command is tested on webkit, 215k entries. The pattern
is chosen mainly to make match_pathspec sweat:
git checkout -- "*[a-zA-Z]*[a-zA-Z]*[a-zA-Z]*"
before after
real 0m3.493s 0m2.737s
user 0m2.239s 0m1.586s
sys 0m1.252s 0m1.151s
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-27 13:58:21 +08:00
|
|
|
test_expect_success 'do not touch unmerged entries matching $path but not in $tree' '
|
|
|
|
git checkout next &&
|
|
|
|
git reset --hard &&
|
|
|
|
|
|
|
|
cat dir/common >expect.common &&
|
|
|
|
EMPTY_SHA1=$(git hash-object -w --stdin </dev/null) &&
|
|
|
|
git rm dir/next0 &&
|
|
|
|
cat >expect.next0 <<-EOF &&
|
|
|
|
100644 $EMPTY_SHA1 1 dir/next0
|
|
|
|
100644 $EMPTY_SHA1 2 dir/next0
|
|
|
|
EOF
|
|
|
|
git update-index --index-info <expect.next0 &&
|
|
|
|
|
2020-11-19 07:44:22 +08:00
|
|
|
git checkout main dir &&
|
checkout: avoid unnecessary match_pathspec calls
In checkout_paths() we do this
- for all updated items, call match_pathspec
- for all items, call match_pathspec (inside unmerge_cache)
- for all items, call match_pathspec (for showing "path .. is unmerged)
- for updated items, call match_pathspec and update paths
That's a lot of duplicate match_pathspec(s) and the function is not
exactly cheap to be called so many times, especially on large indexes.
This patch makes it call match_pathspec once per updated index entry,
save the result in ce_flags and reuse the results in the following
loops.
The changes in 0a1283b (checkout $tree $path: do not clobber local
changes in $path not in $tree - 2011-09-30) limit the affected paths
to ones we read from $tree. We do not do anything to other modified
entries in this case, so the "for all items" above could be modified
to "for all updated items". But..
The command's behavior now is modified slightly: unmerged entries that
match $path, but not updated by $tree, are now NOT touched. Although
this should be considered a bug fix, not a regression. A new test is
added for this change.
And while at there, free ps_matched after use.
The following command is tested on webkit, 215k entries. The pattern
is chosen mainly to make match_pathspec sweat:
git checkout -- "*[a-zA-Z]*[a-zA-Z]*[a-zA-Z]*"
before after
real 0m3.493s 0m2.737s
user 0m2.239s 0m1.586s
sys 0m1.252s 0m1.151s
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-27 13:58:21 +08:00
|
|
|
|
|
|
|
test_cmp expect.common dir/common &&
|
2020-11-19 07:44:22 +08:00
|
|
|
test_path_is_file dir/main &&
|
|
|
|
git diff --exit-code main dir/main &&
|
checkout: avoid unnecessary match_pathspec calls
In checkout_paths() we do this
- for all updated items, call match_pathspec
- for all items, call match_pathspec (inside unmerge_cache)
- for all items, call match_pathspec (for showing "path .. is unmerged)
- for updated items, call match_pathspec and update paths
That's a lot of duplicate match_pathspec(s) and the function is not
exactly cheap to be called so many times, especially on large indexes.
This patch makes it call match_pathspec once per updated index entry,
save the result in ce_flags and reuse the results in the following
loops.
The changes in 0a1283b (checkout $tree $path: do not clobber local
changes in $path not in $tree - 2011-09-30) limit the affected paths
to ones we read from $tree. We do not do anything to other modified
entries in this case, so the "for all items" above could be modified
to "for all updated items". But..
The command's behavior now is modified slightly: unmerged entries that
match $path, but not updated by $tree, are now NOT touched. Although
this should be considered a bug fix, not a regression. A new test is
added for this change.
And while at there, free ps_matched after use.
The following command is tested on webkit, 215k entries. The pattern
is chosen mainly to make match_pathspec sweat:
git checkout -- "*[a-zA-Z]*[a-zA-Z]*[a-zA-Z]*"
before after
real 0m3.493s 0m2.737s
user 0m2.239s 0m1.586s
sys 0m1.252s 0m1.151s
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-27 13:58:21 +08:00
|
|
|
git ls-files -s dir/next0 >actual.next0 &&
|
|
|
|
test_cmp expect.next0 actual.next0
|
|
|
|
'
|
|
|
|
|
2014-11-14 02:30:34 +08:00
|
|
|
test_expect_success 'do not touch files that are already up-to-date' '
|
|
|
|
git reset --hard &&
|
|
|
|
echo one >file1 &&
|
|
|
|
echo two >file2 &&
|
|
|
|
git add file1 file2 &&
|
|
|
|
git commit -m base &&
|
|
|
|
echo modified >file1 &&
|
2018-03-24 15:44:31 +08:00
|
|
|
test-tool chmtime =1000000000 file2 &&
|
2014-11-14 02:30:34 +08:00
|
|
|
git update-index -q --refresh &&
|
|
|
|
git checkout HEAD -- file1 file2 &&
|
|
|
|
echo one >expect &&
|
|
|
|
test_cmp expect file1 &&
|
2018-04-07 06:19:47 +08:00
|
|
|
echo "1000000000" >expect &&
|
2018-04-25 12:29:00 +08:00
|
|
|
test-tool chmtime --get file2 >actual &&
|
2014-11-14 02:30:34 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
checkout.c: unstage empty deleted ita files
It is possible to delete a committed file from the index and then add it
as intent-to-add. After `git checkout HEAD <pathspec>`, the file should
be identical in the index and HEAD. The command already works correctly
if the file has contents in HEAD. This patch provides the desired
behavior even when the file is empty in HEAD.
`git checkout HEAD <pathspec>` calls tree.c:read_tree_1(), with fn
pointing to checkout.c:update_some(). update_some() creates a new cache
entry but discards it when its mode and oid match those of the old
entry. A cache entry for an ita file and a cache entry for an empty file
have the same oid. Therefore, an empty deleted ita file previously
passed both of these checks, and the new entry was discarded, so the
file remained unchanged in the index. After this fix, if the file is
marked as ita in the cache, then we avoid discarding the new entry and
add the new entry to the cache instead.
This change should not affect newly added ita files. For those, inside
tree.c:read_tree_1(), tree_entry_interesting() returns
entry_not_interesting, so fn is never called.
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Varun Naik <vcnaik94@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-03 00:28:52 +08:00
|
|
|
test_expect_success 'checkout HEAD adds deleted intent-to-add file back to index' '
|
|
|
|
echo "nonempty" >nonempty &&
|
|
|
|
>empty &&
|
|
|
|
git add nonempty empty &&
|
|
|
|
git commit -m "create files to be deleted" &&
|
|
|
|
git rm --cached nonempty empty &&
|
|
|
|
git add -N nonempty empty &&
|
|
|
|
git checkout HEAD nonempty empty &&
|
|
|
|
git diff --cached --exit-code
|
|
|
|
'
|
|
|
|
|
2011-10-01 01:33:15 +08:00
|
|
|
test_done
|