mirror of
https://github.com/git/git
synced 2024-10-28 19:25:47 +00:00
77b15bbd88
"git apply" strips new blank lines at EOF under --whitespace=fix option, but neigher --whitespace=warn nor --whitespace=error paid any attention to these errors. Introduce a new whitespace error class, blank-at-eof, to make the whitespace error handling more consistent. The patch adds a new "linenr" field to the struct fragment in order to record which line the hunk started in the input file, but this is needed solely for reporting purposes. The detection of this class of whitespace errors cannot be done while parsing a patch like we do for all the other classes of whitespace errors. It instead has to wait until we find where to apply the hunk, but at that point, we do not have an access to the original line number in the input file anymore, hence the new field. Depending on your point of view, this may be a bugfix that makes warn and error in line with fix. Or you could call it a new feature. The line between them is somewhat fuzzy in this case. Strictly speaking, triggering more errors than before is a change in behaviour that is not backward compatible, even though the reason for the change is because the code was not checking for an error that it should have. People who do not want added blank lines at EOF to trigger an error can disable the new error class. Signed-off-by: Junio C Hamano <gitster@pobox.com>
230 lines
5.1 KiB
Bash
Executable file
230 lines
5.1 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_expect_success 'blank at EOF with --whitespace=warn' '
|
|
{ echo a; echo b; echo c; } >one &&
|
|
git add one &&
|
|
echo >>one &&
|
|
cat one >expect &&
|
|
git diff -- one >patch &&
|
|
|
|
git checkout one &&
|
|
git apply --whitespace=warn patch 2>error &&
|
|
test_cmp expect one &&
|
|
grep "new blank line at EOF" error
|
|
'
|
|
|
|
test_expect_success 'blank at EOF with --whitespace=error' '
|
|
{ echo a; echo b; echo c; } >one &&
|
|
git add one &&
|
|
cat one >expect &&
|
|
echo >>one &&
|
|
git diff -- one >patch &&
|
|
|
|
git checkout one &&
|
|
test_must_fail git apply --whitespace=error patch 2>error &&
|
|
test_cmp expect one &&
|
|
grep "new blank line at EOF" error
|
|
'
|
|
|
|
test_done
|