552 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			552 lines
		
	
	
	
		
			13 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 (default tab width 8)
 | |
| 	#	=  indent-with-non-tab,tabwidth=16
 | |
| 	#   	%  tab-in-indent
 | |
| 	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 () {
 | |
| 	cmd_prefix= &&
 | |
| 	if test "x$1" = 'x!'
 | |
| 	then
 | |
| 		cmd_prefix=test_must_fail &&
 | |
| 		shift
 | |
| 	fi &&
 | |
| 	>target &&
 | |
| 	sed -e "s|\([ab]\)/file|\1/target|" <patch |
 | |
| 	$cmd_prefix 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 expected 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 &&
 | |
| 	test_cmp file target
 | |
| 
 | |
| '
 | |
| 
 | |
| test_expect_success 'whitespace=warn, default rule' '
 | |
| 
 | |
| 	apply_patch --whitespace=warn &&
 | |
| 	test_cmp file target
 | |
| 
 | |
| '
 | |
| 
 | |
| test_expect_success 'whitespace=error-all, default rule' '
 | |
| 
 | |
| 	apply_patch ! --whitespace=error-all &&
 | |
| 	test_must_be_empty target
 | |
| 
 | |
| '
 | |
| 
 | |
| test_expect_success 'whitespace=error-all, no rule' '
 | |
| 
 | |
| 	git config core.whitespace -trailing,-space-before,-indent &&
 | |
| 	apply_patch --whitespace=error-all &&
 | |
| 	test_cmp 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 &&
 | |
| 	test_cmp file target
 | |
| 
 | |
| '
 | |
| 
 | |
| test_expect_success 'spaces inserted by tab-in-indent' '
 | |
| 
 | |
| 	git config core.whitespace -trailing,-space,-indent,tab &&
 | |
| 	rm -f .gitattributes &&
 | |
| 	test_fix % &&
 | |
| 	sed -e "s/_/ /g" -e "s/>/	/" <<-\EOF >expect &&
 | |
| 		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
 | |
| 	test_cmp expect 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='#' ti16='=';; *) ti= ti16= ;; esac
 | |
| 			for h in - ''
 | |
| 			do
 | |
| 				[ -z "$h$i" ] && continue
 | |
| 				case "$h" in '') th='%' ;; *) th= ;; esac
 | |
| 				rule=${t}trailing,${s}space,${i}indent,${h}tab
 | |
| 
 | |
| 				rm -f .gitattributes
 | |
| 				test_expect_success "rule=$rule" '
 | |
| 					git config core.whitespace "$rule" &&
 | |
| 					test_fix "$tt$ts$ti$th"
 | |
| 				'
 | |
| 
 | |
| 				test_expect_success "rule=$rule,tabwidth=16" '
 | |
| 					git config core.whitespace "$rule,tabwidth=16" &&
 | |
| 					test_fix "$tt$ts$ti16$th"
 | |
| 				'
 | |
| 
 | |
| 				test_expect_success "rule=$rule (attributes)" '
 | |
| 					git config --unset core.whitespace &&
 | |
| 					echo "target whitespace=$rule" >.gitattributes &&
 | |
| 					test_fix "$tt$ts$ti$th"
 | |
| 				'
 | |
| 
 | |
| 				test_expect_success "rule=$rule,tabwidth=16 (attributes)" '
 | |
| 					echo "target whitespace=$rule,tabwidth=16" >.gitattributes &&
 | |
| 					test_fix "$tt$ts$ti16$th"
 | |
| 				'
 | |
| 
 | |
| 			done
 | |
| 		done
 | |
| 	done
 | |
| done
 | |
| 
 | |
| create_patch () {
 | |
| 	sed -e "s/_/ /" <<-\EOF
 | |
| 		diff --git a/target b/target
 | |
| 		index e69de29..8bd6648 100644
 | |
| 		--- a/target
 | |
| 		+++ b/target
 | |
| 		@@ -0,0 +1,3 @@
 | |
| 		+An empty line follows
 | |
| 		+
 | |
| 		+A line with trailing whitespace and no newline_
 | |
| 		\ No newline at end of file
 | |
| 	EOF
 | |
| }
 | |
| 
 | |
| test_expect_success 'trailing whitespace & no newline at the end of file' '
 | |
| 	>target &&
 | |
| 	create_patch >patch-file &&
 | |
| 	git apply --whitespace=fix patch-file &&
 | |
| 	grep "newline$" target &&
 | |
| 	grep "^$" target
 | |
| '
 | |
| 
 | |
| test_expect_success 'blank at EOF with --whitespace=fix (1)' '
 | |
| 	test_might_fail 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_expect_success 'blank but not empty at EOF' '
 | |
| 	{ 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 'applying beyond EOF requires one non-blank context line' '
 | |
| 	{ echo; echo; echo; echo; } >one &&
 | |
| 	git add one &&
 | |
| 	{ echo b; } >>one &&
 | |
| 	git diff -- one >patch &&
 | |
| 
 | |
| 	git checkout one &&
 | |
| 	{ echo a; echo; } >one &&
 | |
| 	cp one expect &&
 | |
| 	test_must_fail git apply --whitespace=fix patch &&
 | |
| 	test_cmp expect one &&
 | |
| 	test_must_fail git apply --ignore-space-change --whitespace=fix patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'tons of blanks at EOF should not apply' '
 | |
| 	for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
 | |
| 		echo; echo; echo; echo;
 | |
| 	done >one &&
 | |
| 	git add one &&
 | |
| 	echo a >>one &&
 | |
| 	git diff -- one >patch &&
 | |
| 
 | |
| 	>one &&
 | |
| 	test_must_fail git apply --whitespace=fix patch &&
 | |
| 	test_must_fail git apply --ignore-space-change --whitespace=fix patch
 | |
| '
 | |
| 
 | |
| test_expect_success 'missing blank line at end with --whitespace=fix' '
 | |
| 	echo a >one &&
 | |
| 	echo >>one &&
 | |
| 	git add one &&
 | |
| 	echo b >>one &&
 | |
| 	cp one expect &&
 | |
| 	git diff -- one >patch &&
 | |
| 	echo a >one &&
 | |
| 	cp one saved-one &&
 | |
| 	test_must_fail git apply patch &&
 | |
| 	git apply --whitespace=fix patch &&
 | |
| 	test_cmp expect one &&
 | |
| 	mv saved-one one &&
 | |
| 	git apply --ignore-space-change --whitespace=fix patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'two missing blank lines at end with --whitespace=fix' '
 | |
| 	{ echo a; echo; echo b; echo c; } >one &&
 | |
| 	cp one no-blank-lines &&
 | |
| 	{ echo; echo; } >>one &&
 | |
| 	git add one &&
 | |
| 	echo d >>one &&
 | |
| 	cp one expect &&
 | |
| 	echo >>one &&
 | |
| 	git diff -- one >patch &&
 | |
| 	cp no-blank-lines one &&
 | |
| 	test_must_fail git apply patch &&
 | |
| 	git apply --whitespace=fix patch &&
 | |
| 	test_cmp expect one &&
 | |
| 	mv no-blank-lines one &&
 | |
| 	test_must_fail git apply patch &&
 | |
| 	git apply --ignore-space-change --whitespace=fix patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'missing blank line at end, insert before end, --whitespace=fix' '
 | |
| 	{ echo a; echo; } >one &&
 | |
| 	git add one &&
 | |
| 	{ echo b; echo a; echo; } >one &&
 | |
| 	cp one expect &&
 | |
| 	git diff -- one >patch &&
 | |
| 	echo a >one &&
 | |
| 	test_must_fail git apply patch &&
 | |
| 	git apply --whitespace=fix patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'shrink file with tons of missing blanks at end of file' '
 | |
| 	{ echo a; echo b; echo c; } >one &&
 | |
| 	cp one no-blank-lines &&
 | |
| 	for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
 | |
| 		echo; echo; echo; echo;
 | |
| 	done >>one &&
 | |
| 	git add one &&
 | |
| 	echo a >one &&
 | |
| 	cp one expect &&
 | |
| 	git diff -- one >patch &&
 | |
| 	cp no-blank-lines one &&
 | |
| 	test_must_fail git apply patch &&
 | |
| 	git apply --whitespace=fix patch &&
 | |
| 	test_cmp expect one &&
 | |
| 	mv no-blank-lines one &&
 | |
| 	git apply --ignore-space-change --whitespace=fix patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'missing blanks at EOF must only match blank lines' '
 | |
| 	{ echo a; echo b; } >one &&
 | |
| 	git add one &&
 | |
| 	{ echo c; echo d; } >>one &&
 | |
| 	git diff -- one >patch &&
 | |
| 
 | |
| 	echo a >one &&
 | |
| 	test_must_fail git apply patch &&
 | |
| 	test_must_fail git apply --whitespace=fix patch &&
 | |
| 	test_must_fail git apply --ignore-space-change --whitespace=fix patch
 | |
| '
 | |
| 
 | |
| sed -e's/Z//' >one <<EOF
 | |
| a
 | |
| b
 | |
| c
 | |
| 		      Z
 | |
| EOF
 | |
| 
 | |
| test_expect_success 'missing blank line should match context line with spaces' '
 | |
| 	git add one &&
 | |
| 	echo d >>one &&
 | |
| 	git diff -- one >patch &&
 | |
| 	{ echo a; echo b; echo c; } >one &&
 | |
| 	cp one expect &&
 | |
| 	{ echo; echo d; } >>expect &&
 | |
| 	git add one &&
 | |
| 
 | |
| 	git apply --whitespace=fix patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| sed -e's/Z//' >one <<EOF
 | |
| a
 | |
| b
 | |
| c
 | |
| 		      Z
 | |
| EOF
 | |
| 
 | |
| test_expect_success 'same, but with the --ignore-space-option' '
 | |
| 	git add one &&
 | |
| 	echo d >>one &&
 | |
| 	cp one expect &&
 | |
| 	git diff -- one >patch &&
 | |
| 	{ echo a; echo b; echo c; } >one &&
 | |
| 	git add one &&
 | |
| 
 | |
| 	git checkout-index -f one &&
 | |
| 	git apply --ignore-space-change --whitespace=fix patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' '
 | |
| 	git config core.whitespace cr-at-eol &&
 | |
| 	printf "a\r\n" >one &&
 | |
| 	printf "b\r\n" >>one &&
 | |
| 	printf "c\r\n" >>one &&
 | |
| 	cp one save-one &&
 | |
| 	printf "                 \r\n" >>one &&
 | |
| 	git add one &&
 | |
| 	printf "d\r\n" >>one &&
 | |
| 	cp one expect &&
 | |
| 	git diff -- one >patch &&
 | |
| 	mv save-one one &&
 | |
| 
 | |
| 	git apply --ignore-space-change --whitespace=fix patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'CR-LF line endings && add line && text=auto' '
 | |
| 	git config --unset core.whitespace &&
 | |
| 	printf "a\r\n" >one &&
 | |
| 	cp one save-one &&
 | |
| 	git add one &&
 | |
| 	printf "b\r\n" >>one &&
 | |
| 	cp one expect &&
 | |
| 	git diff -- one >patch &&
 | |
| 	mv save-one one &&
 | |
| 	echo "one text=auto" >.gitattributes &&
 | |
| 	git apply patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'CR-LF line endings && change line && text=auto' '
 | |
| 	printf "a\r\n" >one &&
 | |
| 	cp one save-one &&
 | |
| 	git add one &&
 | |
| 	printf "b\r\n" >one &&
 | |
| 	cp one expect &&
 | |
| 	git diff -- one >patch &&
 | |
| 	mv save-one one &&
 | |
| 	echo "one text=auto" >.gitattributes &&
 | |
| 	git apply patch &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'LF in repo, CRLF in worktree && change line && text=auto' '
 | |
| 	printf "a\n" >one &&
 | |
| 	git add one &&
 | |
| 	printf "b\r\n" >one &&
 | |
| 	git diff -- one >patch &&
 | |
| 	printf "a\r\n" >one &&
 | |
| 	echo "one text=auto" >.gitattributes &&
 | |
| 	git -c core.eol=CRLF apply patch &&
 | |
| 	printf "b\r\n" >expect &&
 | |
| 	test_cmp expect one
 | |
| '
 | |
| 
 | |
| test_expect_success 'whitespace=fix to expand' '
 | |
| 	qz_to_tab_space >preimage <<-\EOF &&
 | |
| 	QQa
 | |
| 	QQb
 | |
| 	QQc
 | |
| 	ZZZZZZZZZZZZZZZZd
 | |
| 	QQe
 | |
| 	QQf
 | |
| 	QQg
 | |
| 	EOF
 | |
| 	qz_to_tab_space >patch <<-\EOF &&
 | |
| 	diff --git a/preimage b/preimage
 | |
| 	--- a/preimage
 | |
| 	+++ b/preimage
 | |
| 	@@ -1,7 +1,6 @@
 | |
| 	 QQa
 | |
| 	 QQb
 | |
| 	 QQc
 | |
| 	-QQd
 | |
| 	 QQe
 | |
| 	 QQf
 | |
| 	 QQg
 | |
| 	EOF
 | |
| 	git -c core.whitespace=tab-in-indent apply --whitespace=fix patch
 | |
| '
 | |
| 
 | |
| test_expect_success 'whitespace check skipped for excluded paths' '
 | |
| 	git config core.whitespace blank-at-eol &&
 | |
| 	>used &&
 | |
| 	>unused &&
 | |
| 	git add used unused &&
 | |
| 	echo "used" >used &&
 | |
| 	echo "unused " >unused &&
 | |
| 	git diff-files -p used unused >patch &&
 | |
| 	git apply --include=used --stat --whitespace=error <patch
 | |
| '
 | |
| 
 | |
| test_done
 |