t: add tests for restore

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2019-04-25 16:45:55 +07:00 committed by Junio C Hamano
parent 2f0896ec3a
commit 4df3ec6324
3 changed files with 221 additions and 0 deletions

View File

@ -2,28 +2,40 @@
. ./test-lib.sh
# set_state <path> <worktree-content> <index-content>
#
# Prepare the content for path in worktree and the index as specified.
set_state () {
echo "$3" > "$1" &&
git add "$1" &&
echo "$2" > "$1"
}
# save_state <path>
#
# Save index/worktree content of <path> in the files _worktree_<path>
# and _index_<path>
save_state () {
noslash="$(echo "$1" | tr / _)" &&
cat "$1" > _worktree_"$noslash" &&
git show :"$1" > _index_"$noslash"
}
# set_and_save_state <path> <worktree-content> <index-content>
set_and_save_state () {
set_state "$@" &&
save_state "$1"
}
# verify_state <path> <expected-worktree-content> <expected-index-content>
verify_state () {
test "$(cat "$1")" = "$2" &&
test "$(git show :"$1")" = "$3"
}
# verify_saved_state <path>
#
# Call verify_state with expected contents from the last save_state
verify_saved_state () {
noslash="$(echo "$1" | tr / _)" &&
verify_state "$1" "$(cat _worktree_"$noslash")" "$(cat _index_"$noslash")"

99
t/t2070-restore.sh Executable file
View File

@ -0,0 +1,99 @@
#!/bin/sh
test_description='restore basic functionality'
. ./test-lib.sh
test_expect_success 'setup' '
test_commit first &&
echo first-and-a-half >>first.t &&
git add first.t &&
test_commit second &&
echo one >one &&
echo two >two &&
echo untracked >untracked &&
echo ignored >ignored &&
echo /ignored >.gitignore &&
git add one two .gitignore &&
git update-ref refs/heads/one master
'
test_expect_success 'restore without pathspec is not ok' '
test_must_fail git restore &&
test_must_fail git restore --source=first
'
test_expect_success 'restore a file, ignoring branch of same name' '
cat one >expected &&
echo dirty >>one &&
git restore one &&
test_cmp expected one
'
test_expect_success 'restore a file on worktree from another ref' '
test_when_finished git reset --hard &&
git cat-file blob first:./first.t >expected &&
git restore --source=first first.t &&
test_cmp expected first.t &&
git cat-file blob HEAD:./first.t >expected &&
git show :first.t >actual &&
test_cmp expected actual
'
test_expect_success 'restore a file in the index from another ref' '
test_when_finished git reset --hard &&
git cat-file blob first:./first.t >expected &&
git restore --source=first --staged first.t &&
git show :first.t >actual &&
test_cmp expected actual &&
git cat-file blob HEAD:./first.t >expected &&
test_cmp expected first.t
'
test_expect_success 'restore a file in both the index and worktree from another ref' '
test_when_finished git reset --hard &&
git cat-file blob first:./first.t >expected &&
git restore --source=first --staged --worktree first.t &&
git show :first.t >actual &&
test_cmp expected actual &&
test_cmp expected first.t
'
test_expect_success 'restore --staged uses HEAD as source' '
test_when_finished git reset --hard &&
git cat-file blob :./first.t >expected &&
echo index-dirty >>first.t &&
git add first.t &&
git restore --staged first.t &&
git cat-file blob :./first.t >actual &&
test_cmp expected actual
'
test_expect_success 'restore --ignore-unmerged ignores unmerged entries' '
git init unmerged &&
(
cd unmerged &&
echo one >unmerged &&
echo one >common &&
git add unmerged common &&
git commit -m common &&
git switch -c first &&
echo first >unmerged &&
git commit -am first &&
git switch -c second master &&
echo second >unmerged &&
git commit -am second &&
test_must_fail git merge first &&
echo dirty >>common &&
test_must_fail git restore . &&
git restore --ignore-unmerged --quiet . >output 2>&1 &&
git diff common >diff-output &&
: >empty &&
test_cmp empty output &&
test_cmp empty diff-output
)
'
test_done

110
t/t2071-restore-patch.sh Executable file
View File

@ -0,0 +1,110 @@
#!/bin/sh
test_description='git restore --patch'
. ./lib-patch-mode.sh
test_expect_success PERL 'setup' '
mkdir dir &&
echo parent >dir/foo &&
echo dummy >bar &&
git add bar dir/foo &&
git commit -m initial &&
test_tick &&
test_commit second dir/foo head &&
set_and_save_state bar bar_work bar_index &&
save_head
'
test_expect_success PERL 'restore -p without pathspec is fine' '
echo q >cmd &&
git restore -p <cmd
'
# note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar'
test_expect_success PERL 'saying "n" does nothing' '
set_and_save_state dir/foo work head &&
test_write_lines n n | git restore -p &&
verify_saved_state bar &&
verify_saved_state dir/foo
'
test_expect_success PERL 'git restore -p' '
set_and_save_state dir/foo work head &&
test_write_lines n y | git restore -p &&
verify_saved_state bar &&
verify_state dir/foo head head
'
test_expect_success PERL 'git restore -p with staged changes' '
set_state dir/foo work index &&
test_write_lines n y | git restore -p &&
verify_saved_state bar &&
verify_state dir/foo index index
'
test_expect_success PERL 'git restore -p --source=HEAD' '
set_state dir/foo work index &&
# the third n is to get out in case it mistakenly does not apply
test_write_lines n y n | git restore -p --source=HEAD &&
verify_saved_state bar &&
verify_state dir/foo head index
'
test_expect_success PERL 'git restore -p --source=HEAD^' '
set_state dir/foo work index &&
# the third n is to get out in case it mistakenly does not apply
test_write_lines n y n | git restore -p --source=HEAD^ &&
verify_saved_state bar &&
verify_state dir/foo parent index
'
test_expect_success PERL 'git restore -p handles deletion' '
set_state dir/foo work index &&
rm dir/foo &&
test_write_lines n y | git restore -p &&
verify_saved_state bar &&
verify_state dir/foo index index
'
# The idea in the rest is that bar sorts first, so we always say 'y'
# first and if the path limiter fails it'll apply to bar instead of
# dir/foo. There's always an extra 'n' to reject edits to dir/foo in
# the failure case (and thus get out of the loop).
test_expect_success PERL 'path limiting works: dir' '
set_state dir/foo work head &&
test_write_lines y n | git restore -p dir &&
verify_saved_state bar &&
verify_state dir/foo head head
'
test_expect_success PERL 'path limiting works: -- dir' '
set_state dir/foo work head &&
test_write_lines y n | git restore -p -- dir &&
verify_saved_state bar &&
verify_state dir/foo head head
'
test_expect_success PERL 'path limiting works: HEAD^ -- dir' '
set_state dir/foo work head &&
# the third n is to get out in case it mistakenly does not apply
test_write_lines y n n | git restore -p --source=HEAD^ -- dir &&
verify_saved_state bar &&
verify_state dir/foo parent head
'
test_expect_success PERL 'path limiting works: foo inside dir' '
set_state dir/foo work head &&
# the third n is to get out in case it mistakenly does not apply
test_write_lines y n n | (cd dir && git restore -p foo) &&
verify_saved_state bar &&
verify_state dir/foo head head
'
test_expect_success PERL 'none of this moved HEAD' '
verify_saved_head
'
test_done