mirror of
https://github.com/git/git
synced 2024-10-28 19:25:47 +00:00
efa574438f
The command tries to strip blank lines at the end of the file added by a patch. It is done by first detecting if a hunk in patch has additional blank lines at the end of itself, and if so checking if such a hunk applies at the end of file. This patch addresses a bug in the logic to implement the former (the previous one addressed a bug in the latter). If the original ends with blank lines, often the patch hunk ends like this: @@ -l,5 +m,7 @@$ _context$ _context$ -deleted$ +$ +$ +$ _$ _$ where _ stands for SP and $ shows a end-of-line. This example patch adds three trailing blank lines, but the code fails to notice it, because it only pays attention to added blank lines at the very end of the hunk. In this example, the three added blank lines do not appear textually at the end in the patch, even though you can see that they are indeed added at the end, if you rearrange the diff like this: @@ -l,5 +m,7 @@$ _context$ _context$ -deleted$ _$ _$ +$ +$ +$ The fix is not to reset the number of (candidate) added blank lines at the end when the loop sees a context line that is empty. Signed-off-by: Junio C Hamano <gitster@pobox.com>
204 lines
4.4 KiB
Bash
Executable file
204 lines
4.4 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
test_description='core.whitespace rules and git apply'
|
|
|
|
. ./test-lib.sh
|
|
|
|
prepare_test_file () {
|
|
|
|
# A line that has character X is touched iff RULE is in effect:
|
|
# X RULE
|
|
# ! trailing-space
|
|
# @ space-before-tab
|
|
# # indent-with-non-tab
|
|
sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF
|
|
An_SP in an ordinary line>and a HT.
|
|
>A HT.
|
|
_>A SP and a HT (@).
|
|
_>_A SP, a HT and a SP (@).
|
|
_______Seven SP.
|
|
________Eight SP (#).
|
|
_______>Seven SP and a HT (@).
|
|
________>Eight SP and a HT (@#).
|
|
_______>_Seven SP, a HT and a SP (@).
|
|
________>_Eight SP, a HT and a SP (@#).
|
|
_______________Fifteen SP (#).
|
|
_______________>Fifteen SP and a HT (@#).
|
|
________________Sixteen SP (#).
|
|
________________>Sixteen SP and a HT (@#).
|
|
_____a__Five SP, a non WS, two SP.
|
|
A line with a (!) trailing SP_
|
|
A line with a (!) trailing HT>
|
|
EOF
|
|
}
|
|
|
|
apply_patch () {
|
|
>target &&
|
|
sed -e "s|\([ab]\)/file|\1/target|" <patch |
|
|
git apply "$@"
|
|
}
|
|
|
|
test_fix () {
|
|
|
|
# fix should not barf
|
|
apply_patch --whitespace=fix || return 1
|
|
|
|
# find touched lines
|
|
diff file target | sed -n -e "s/^> //p" >fixed
|
|
|
|
# the changed lines are all expeced to change
|
|
fixed_cnt=$(wc -l <fixed)
|
|
case "$1" in
|
|
'') expect_cnt=$fixed_cnt ;;
|
|
?*) expect_cnt=$(grep "[$1]" <fixed | wc -l) ;;
|
|
esac
|
|
test $fixed_cnt -eq $expect_cnt || return 1
|
|
|
|
# and we are not missing anything
|
|
case "$1" in
|
|
'') expect_cnt=0 ;;
|
|
?*) expect_cnt=$(grep "[$1]" <file | wc -l) ;;
|
|
esac
|
|
test $fixed_cnt -eq $expect_cnt || return 1
|
|
|
|
# Get the patch actually applied
|
|
git diff-files -p target >fixed-patch
|
|
test -s fixed-patch && return 0
|
|
|
|
# Make sure it is complaint-free
|
|
>target
|
|
git apply --whitespace=error-all <fixed-patch
|
|
|
|
}
|
|
|
|
test_expect_success setup '
|
|
|
|
>file &&
|
|
git add file &&
|
|
prepare_test_file >file &&
|
|
git diff-files -p >patch &&
|
|
>target &&
|
|
git add target
|
|
|
|
'
|
|
|
|
test_expect_success 'whitespace=nowarn, default rule' '
|
|
|
|
apply_patch --whitespace=nowarn &&
|
|
diff file target
|
|
|
|
'
|
|
|
|
test_expect_success 'whitespace=warn, default rule' '
|
|
|
|
apply_patch --whitespace=warn &&
|
|
diff file target
|
|
|
|
'
|
|
|
|
test_expect_success 'whitespace=error-all, default rule' '
|
|
|
|
apply_patch --whitespace=error-all && return 1
|
|
test -s target && return 1
|
|
: happy
|
|
|
|
'
|
|
|
|
test_expect_success 'whitespace=error-all, no rule' '
|
|
|
|
git config core.whitespace -trailing,-space-before,-indent &&
|
|
apply_patch --whitespace=error-all &&
|
|
diff file target
|
|
|
|
'
|
|
|
|
test_expect_success 'whitespace=error-all, no rule (attribute)' '
|
|
|
|
git config --unset core.whitespace &&
|
|
echo "target -whitespace" >.gitattributes &&
|
|
apply_patch --whitespace=error-all &&
|
|
diff file target
|
|
|
|
'
|
|
|
|
for t in - ''
|
|
do
|
|
case "$t" in '') tt='!' ;; *) tt= ;; esac
|
|
for s in - ''
|
|
do
|
|
case "$s" in '') ts='@' ;; *) ts= ;; esac
|
|
for i in - ''
|
|
do
|
|
case "$i" in '') ti='#' ;; *) ti= ;; esac
|
|
rule=${t}trailing,${s}space,${i}indent
|
|
|
|
rm -f .gitattributes
|
|
test_expect_success "rule=$rule" '
|
|
git config core.whitespace "$rule" &&
|
|
test_fix "$tt$ts$ti"
|
|
'
|
|
|
|
test_expect_success "rule=$rule (attributes)" '
|
|
git config --unset core.whitespace &&
|
|
echo "target whitespace=$rule" >.gitattributes &&
|
|
test_fix "$tt$ts$ti"
|
|
'
|
|
|
|
done
|
|
done
|
|
done
|
|
|
|
|
|
test_expect_success 'blank at EOF with --whitespace=fix (1)' '
|
|
: these can fail depending on what we did before
|
|
git config --unset core.whitespace
|
|
rm -f .gitattributes
|
|
|
|
{ echo a; echo b; echo c; } >one &&
|
|
git add one &&
|
|
{ echo a; echo b; echo c; } >expect &&
|
|
{ cat expect; echo; } >one &&
|
|
git diff -- one >patch &&
|
|
|
|
git checkout one &&
|
|
git apply --whitespace=fix patch &&
|
|
test_cmp expect one
|
|
'
|
|
|
|
test_expect_success 'blank at EOF with --whitespace=fix (2)' '
|
|
{ echo a; echo b; echo c; } >one &&
|
|
git add one &&
|
|
{ echo a; echo c; } >expect &&
|
|
{ cat expect; echo; echo; } >one &&
|
|
git diff -- one >patch &&
|
|
|
|
git checkout one &&
|
|
git apply --whitespace=fix patch &&
|
|
test_cmp expect one
|
|
'
|
|
|
|
test_expect_success 'blank at EOF with --whitespace=fix (3)' '
|
|
{ echo a; echo b; echo; } >one &&
|
|
git add one &&
|
|
{ echo a; echo c; echo; } >expect &&
|
|
{ cat expect; echo; echo; } >one &&
|
|
git diff -- one >patch &&
|
|
|
|
git checkout one &&
|
|
git apply --whitespace=fix patch &&
|
|
test_cmp expect one
|
|
'
|
|
|
|
test_expect_success 'blank at end of hunk, not at EOF with --whitespace=fix' '
|
|
{ echo a; echo b; echo; echo; echo; echo; echo; echo d; } >one &&
|
|
git add one &&
|
|
{ echo a; echo c; echo; echo; echo; echo; echo; echo; echo d; } >expect &&
|
|
cp expect one &&
|
|
git diff -- one >patch &&
|
|
|
|
git checkout one &&
|
|
git apply --whitespace=fix patch &&
|
|
test_cmp expect one
|
|
'
|
|
|
|
test_done
|