mirror of
https://github.com/git/git
synced 2024-08-27 19:49:21 +00:00
![Ævar Arnfjörð Bjarmason](/assets/img/avatar_default.png)
The "checkout" command is one of the main sources of leaks in the test
suite, let's fix the common ones by not leaking from the "struct
branch_info".
Doing this is rather straightforward, albeit verbose, we need to
xstrdup() constant strings going into the struct, and free() the ones
we clobber as we go along.
This also means that we can delete previous partial leak fixes in this
area, i.e. the "path_to_free" accounting added by 96ec7b1e70
(Convert
resolve_ref+xstrdup to new resolve_refdup function, 2011-12-13).
There was some discussion about whether "we should retain the "const
char *" here and cast at free() time, or have it be a "char *". Since
this is not a public API with any sort of API boundary let's use
"char *", as is already being done for the "refname" member of the
same struct.
The tests to mark as passing were found with:
rm .prove; GIT_SKIP_TESTS=t0027 prove -j8 --state=save t[0-9]*.sh :: --immediate
# apply & compile this change
prove -j8 --state=failed :: --immediate
I.e. the ones that were newly passing when the --state=failed command
was run. I left out "t3040-subprojects-basic.sh" and
"t4131-apply-fake-ancestor.sh" to to optimization-level related
differences similar to the ones noted in[1], except that these would
be something the current 'linux-leaks' job would run into.
1. https://lore.kernel.org/git/cover-v3-0.6-00000000000-20211022T175227Z-avarab@gmail.com/
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
149 lines
4.7 KiB
Bash
Executable file
149 lines
4.7 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
test_description='post index change hook'
|
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
|
. ./test-lib.sh
|
|
|
|
test_expect_success 'setup' '
|
|
mkdir -p dir1 &&
|
|
touch dir1/file1.txt &&
|
|
echo testing >dir1/file2.txt &&
|
|
git add . &&
|
|
git commit -m "initial"
|
|
'
|
|
|
|
test_expect_success 'test status, add, commit, others trigger hook without flags set' '
|
|
mkdir -p .git/hooks &&
|
|
write_script .git/hooks/post-index-change <<-\EOF &&
|
|
if test "$1" -eq 1; then
|
|
echo "Invalid combination of flags passed to hook; updated_workdir is set." >testfailure
|
|
exit 1
|
|
fi
|
|
if test "$2" -eq 1; then
|
|
echo "Invalid combination of flags passed to hook; updated_skipworktree is set." >testfailure
|
|
exit 1
|
|
fi
|
|
if test -f ".git/index.lock"; then
|
|
echo ".git/index.lock exists" >testfailure
|
|
exit 3
|
|
fi
|
|
if ! test -f ".git/index"; then
|
|
echo ".git/index does not exist" >testfailure
|
|
exit 3
|
|
fi
|
|
echo "success" >testsuccess
|
|
EOF
|
|
mkdir -p dir2 &&
|
|
touch dir2/file1.txt &&
|
|
touch dir2/file2.txt &&
|
|
: force index to be dirty &&
|
|
test-tool chmtime +60 dir1/file1.txt &&
|
|
git status &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
git add . &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
git commit -m "second" &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
git checkout -- dir1/file1.txt &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
git update-index &&
|
|
test_path_is_missing testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
git reset --soft &&
|
|
test_path_is_missing testsuccess &&
|
|
test_path_is_missing testfailure
|
|
'
|
|
|
|
test_expect_success 'test checkout and reset trigger the hook' '
|
|
write_script .git/hooks/post-index-change <<-\EOF &&
|
|
if test "$1" -eq 1 && test "$2" -eq 1; then
|
|
echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
|
|
exit 1
|
|
fi
|
|
if test "$1" -eq 0 && test "$2" -eq 0; then
|
|
echo "Invalid combination of flags passed to hook; neither updated_workdir or updated_skipworktree are set." >testfailure
|
|
exit 2
|
|
fi
|
|
if test "$1" -eq 1; then
|
|
if test -f ".git/index.lock"; then
|
|
echo "updated_workdir set but .git/index.lock exists" >testfailure
|
|
exit 3
|
|
fi
|
|
if ! test -f ".git/index"; then
|
|
echo "updated_workdir set but .git/index does not exist" >testfailure
|
|
exit 3
|
|
fi
|
|
else
|
|
echo "update_workdir should be set for checkout" >testfailure
|
|
exit 4
|
|
fi
|
|
echo "success" >testsuccess
|
|
EOF
|
|
: force index to be dirty &&
|
|
test-tool chmtime +60 dir1/file1.txt &&
|
|
git checkout main &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
test-tool chmtime +60 dir1/file1.txt &&
|
|
git checkout HEAD &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
test-tool chmtime +60 dir1/file1.txt &&
|
|
git reset --hard &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
git checkout -B test &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure
|
|
'
|
|
|
|
test_expect_success 'test reset --mixed and update-index triggers the hook' '
|
|
write_script .git/hooks/post-index-change <<-\EOF &&
|
|
if test "$1" -eq 1 && test "$2" -eq 1; then
|
|
echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
|
|
exit 1
|
|
fi
|
|
if test "$1" -eq 0 && test "$2" -eq 0; then
|
|
echo "Invalid combination of flags passed to hook; neither updated_workdir or updated_skipworktree are set." >testfailure
|
|
exit 2
|
|
fi
|
|
if test "$2" -eq 1; then
|
|
if test -f ".git/index.lock"; then
|
|
echo "updated_skipworktree set but .git/index.lock exists" >testfailure
|
|
exit 3
|
|
fi
|
|
if ! test -f ".git/index"; then
|
|
echo "updated_skipworktree set but .git/index does not exist" >testfailure
|
|
exit 3
|
|
fi
|
|
else
|
|
echo "updated_skipworktree should be set for reset --mixed and update-index" >testfailure
|
|
exit 4
|
|
fi
|
|
echo "success" >testsuccess
|
|
EOF
|
|
: force index to be dirty &&
|
|
test-tool chmtime +60 dir1/file1.txt &&
|
|
git reset --mixed --quiet HEAD~1 &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
git hash-object -w --stdin <dir1/file2.txt >expect &&
|
|
git update-index --cacheinfo 100644 "$(cat expect)" dir1/file1.txt &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure &&
|
|
git update-index --skip-worktree dir1/file2.txt &&
|
|
git update-index --remove dir1/file2.txt &&
|
|
test_path_is_file testsuccess && rm -f testsuccess &&
|
|
test_path_is_missing testfailure
|
|
'
|
|
|
|
test_done
|