git/t/t2022-checkout-paths.sh
Jeff King c5326bd62b checkout $tree: do not throw away unchanged index entries
When we "git checkout $tree", we pull paths from $tree into
the index, and then check the resulting entries out to the
worktree. Our method for the first step is rather
heavy-handed, though; it clobbers the entire existing index
entry, even if the content is the same. This means we lose
our stat information, leading checkout_entry to later
rewrite the entire file with identical content.

Instead, let's see if we have the identical entry already in
the index, in which case we leave it in place. That lets
checkout_entry do the right thing. Our tests cover two
interesting cases:

  1. We make sure that a file which has no changes is not
     rewritten.

  2. We make sure that we do update a file that is unchanged
     in the index (versus $tree), but has working tree
     changes. We keep the old index entry, and
     checkout_entry is able to realize that our stat
     information is out of date.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-13 14:35:41 -08:00

82 lines
2.1 KiB
Bash
Executable File

#!/bin/sh
test_description='checkout $tree -- $paths'
. ./test-lib.sh
test_expect_success setup '
mkdir dir &&
>dir/master &&
echo common >dir/common &&
git add dir/master dir/common &&
test_tick && git commit -m "master has dir/master" &&
git checkout -b next &&
git mv dir/master dir/next0 &&
echo next >dir/next1 &&
git add dir &&
test_tick && git commit -m "next has dir/next but not dir/master"
'
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 &&
git checkout master dir &&
test_cmp expect.common dir/common &&
test_path_is_file dir/master &&
git diff --exit-code master dir/master &&
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
'
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 &&
git checkout master dir &&
test_cmp expect.common dir/common &&
test_path_is_file dir/master &&
git diff --exit-code master dir/master &&
git ls-files -s dir/next0 >actual.next0 &&
test_cmp expect.next0 actual.next0
'
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 &&
test-chmtime =1000000000 file2 &&
git update-index -q --refresh &&
git checkout HEAD -- file1 file2 &&
echo one >expect &&
test_cmp expect file1 &&
echo "1000000000 file2" >expect &&
test-chmtime -v +0 file2 >actual &&
test_cmp expect actual
'
test_done