Sync with 2.28.1
* maint-2.28: Git 2.28.1 Git 2.27.1 Git 2.26.3 Git 2.25.5 Git 2.24.4 Git 2.23.4 Git 2.22.5 Git 2.21.4 Git 2.20.5 Git 2.19.6 Git 2.18.5 Git 2.17.6 unpack_trees(): start with a fresh lstat cache run-command: invalidate lstat cache after a command finished checkout: fix bug that makes checkout follow symlinks in leading path
This commit is contained in:
@ -957,4 +957,85 @@ test_expect_success PERL 'invalid file in delayed checkout' '
|
||||
grep "error: external filter .* signaled that .unfiltered. is now available although it has not been delayed earlier" git-stderr.log
|
||||
'
|
||||
|
||||
for mode in 'case' 'utf-8'
|
||||
do
|
||||
case "$mode" in
|
||||
case) dir='A' symlink='a' mode_prereq='CASE_INSENSITIVE_FS' ;;
|
||||
utf-8)
|
||||
dir=$(printf "\141\314\210") symlink=$(printf "\303\244")
|
||||
mode_prereq='UTF8_NFD_TO_NFC' ;;
|
||||
esac
|
||||
|
||||
test_expect_success PERL,SYMLINKS,$mode_prereq \
|
||||
"delayed checkout with $mode-collision don't write to the wrong place" '
|
||||
test_config_global filter.delay.process \
|
||||
"\"$TEST_ROOT/rot13-filter.pl\" --always-delay delayed.log clean smudge delay" &&
|
||||
test_config_global filter.delay.required true &&
|
||||
|
||||
git init $mode-collision &&
|
||||
(
|
||||
cd $mode-collision &&
|
||||
mkdir target-dir &&
|
||||
|
||||
empty_oid=$(printf "" | git hash-object -w --stdin) &&
|
||||
symlink_oid=$(printf "%s" "$PWD/target-dir" | git hash-object -w --stdin) &&
|
||||
attr_oid=$(echo "$dir/z filter=delay" | git hash-object -w --stdin) &&
|
||||
|
||||
cat >objs <<-EOF &&
|
||||
100644 blob $empty_oid $dir/x
|
||||
100644 blob $empty_oid $dir/y
|
||||
100644 blob $empty_oid $dir/z
|
||||
120000 blob $symlink_oid $symlink
|
||||
100644 blob $attr_oid .gitattributes
|
||||
EOF
|
||||
|
||||
git update-index --index-info <objs &&
|
||||
git commit -m "test commit"
|
||||
) &&
|
||||
|
||||
git clone $mode-collision $mode-collision-cloned &&
|
||||
# Make sure z was really delayed
|
||||
grep "IN: smudge $dir/z .* \\[DELAYED\\]" $mode-collision-cloned/delayed.log &&
|
||||
|
||||
# Should not create $dir/z at $symlink/z
|
||||
test_path_is_missing $mode-collision/target-dir/z
|
||||
'
|
||||
done
|
||||
|
||||
test_expect_success PERL,SYMLINKS,CASE_INSENSITIVE_FS \
|
||||
"delayed checkout with submodule collision don't write to the wrong place" '
|
||||
git init collision-with-submodule &&
|
||||
(
|
||||
cd collision-with-submodule &&
|
||||
git config filter.delay.process "\"$TEST_ROOT/rot13-filter.pl\" --always-delay delayed.log clean smudge delay" &&
|
||||
git config filter.delay.required true &&
|
||||
|
||||
# We need Git to treat the submodule "a" and the
|
||||
# leading dir "A" as different paths in the index.
|
||||
git config --local core.ignoreCase false &&
|
||||
|
||||
empty_oid=$(printf "" | git hash-object -w --stdin) &&
|
||||
attr_oid=$(echo "A/B/y filter=delay" | git hash-object -w --stdin) &&
|
||||
cat >objs <<-EOF &&
|
||||
100644 blob $empty_oid A/B/x
|
||||
100644 blob $empty_oid A/B/y
|
||||
100644 blob $attr_oid .gitattributes
|
||||
EOF
|
||||
git update-index --index-info <objs &&
|
||||
|
||||
git init a &&
|
||||
mkdir target-dir &&
|
||||
symlink_oid=$(printf "%s" "$PWD/target-dir" | git -C a hash-object -w --stdin) &&
|
||||
echo "120000 blob $symlink_oid b" >objs &&
|
||||
git -C a update-index --index-info <objs &&
|
||||
git -C a commit -m sub &&
|
||||
git submodule add ./a &&
|
||||
git commit -m super &&
|
||||
|
||||
git checkout --recurse-submodules . &&
|
||||
grep "IN: smudge A/B/y .* \\[DELAYED\\]" delayed.log &&
|
||||
test_path_is_missing target-dir/y
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -2,9 +2,15 @@
|
||||
# Example implementation for the Git filter protocol version 2
|
||||
# See Documentation/gitattributes.txt, section "Filter Protocol"
|
||||
#
|
||||
# The first argument defines a debug log file that the script write to.
|
||||
# All remaining arguments define a list of supported protocol
|
||||
# capabilities ("clean", "smudge", etc).
|
||||
# Usage: rot13-filter.pl [--always-delay] <log path> <capabilities>
|
||||
#
|
||||
# Log path defines a debug log file that the script writes to. The
|
||||
# subsequent arguments define a list of supported protocol capabilities
|
||||
# ("clean", "smudge", etc).
|
||||
#
|
||||
# When --always-delay is given all pathnames with the "can-delay" flag
|
||||
# that don't appear on the list bellow are delayed with a count of 1
|
||||
# (see more below).
|
||||
#
|
||||
# This implementation supports special test cases:
|
||||
# (1) If data with the pathname "clean-write-fail.r" is processed with
|
||||
@ -53,6 +59,13 @@ use IO::File;
|
||||
use Git::Packet;
|
||||
|
||||
my $MAX_PACKET_CONTENT_SIZE = 65516;
|
||||
|
||||
my $always_delay = 0;
|
||||
if ( $ARGV[0] eq '--always-delay' ) {
|
||||
$always_delay = 1;
|
||||
shift @ARGV;
|
||||
}
|
||||
|
||||
my $log_file = shift @ARGV;
|
||||
my @capabilities = @ARGV;
|
||||
|
||||
@ -134,6 +147,8 @@ while (1) {
|
||||
if ( $buffer eq "can-delay=1" ) {
|
||||
if ( exists $DELAY{$pathname} and $DELAY{$pathname}{"requested"} == 0 ) {
|
||||
$DELAY{$pathname}{"requested"} = 1;
|
||||
} elsif ( !exists $DELAY{$pathname} and $always_delay ) {
|
||||
$DELAY{$pathname} = { "requested" => 1, "count" => 1 };
|
||||
}
|
||||
} elsif ($buffer =~ /^(ref|treeish|blob)=/) {
|
||||
print $debug " $buffer";
|
||||
|
@ -21,4 +21,50 @@ test_expect_success 'checkout-index -h in broken repository' '
|
||||
test_i18ngrep "[Uu]sage" broken/usage
|
||||
'
|
||||
|
||||
for mode in 'case' 'utf-8'
|
||||
do
|
||||
case "$mode" in
|
||||
case) dir='A' symlink='a' mode_prereq='CASE_INSENSITIVE_FS' ;;
|
||||
utf-8)
|
||||
dir=$(printf "\141\314\210") symlink=$(printf "\303\244")
|
||||
mode_prereq='UTF8_NFD_TO_NFC' ;;
|
||||
esac
|
||||
|
||||
test_expect_success SYMLINKS,$mode_prereq \
|
||||
"checkout-index with $mode-collision don't write to the wrong place" '
|
||||
git init $mode-collision &&
|
||||
(
|
||||
cd $mode-collision &&
|
||||
mkdir target-dir &&
|
||||
|
||||
empty_obj_hex=$(git hash-object -w --stdin </dev/null) &&
|
||||
symlink_hex=$(printf "%s" "$PWD/target-dir" | git hash-object -w --stdin) &&
|
||||
|
||||
cat >objs <<-EOF &&
|
||||
100644 blob ${empty_obj_hex} ${dir}/x
|
||||
100644 blob ${empty_obj_hex} ${dir}/y
|
||||
100644 blob ${empty_obj_hex} ${dir}/z
|
||||
120000 blob ${symlink_hex} ${symlink}
|
||||
EOF
|
||||
|
||||
git update-index --index-info <objs &&
|
||||
|
||||
# Note: the order is important here to exercise the
|
||||
# case where the file at ${dir} has its type changed by
|
||||
# the time Git tries to check out ${dir}/z.
|
||||
#
|
||||
# Also, we use core.precomposeUnicode=false because we
|
||||
# want Git to treat the UTF-8 paths transparently on
|
||||
# Mac OS, matching what is in the index.
|
||||
#
|
||||
git -c core.precomposeUnicode=false checkout-index -f \
|
||||
${dir}/x ${dir}/y ${symlink} ${dir}/z &&
|
||||
|
||||
# Should not create ${dir}/z at ${symlink}/z
|
||||
test_path_is_missing target-dir/z
|
||||
|
||||
)
|
||||
'
|
||||
done
|
||||
|
||||
test_done
|
||||
|
Reference in New Issue
Block a user