Skip to content

Commit 343151d

Browse files
tboegigitster
authored andcommitted
t0027: combinations of core.autocrlf, core.eol and text
Historically there are 3 different parameters controlling how line endings are handled by Git: - core.autocrlf - core.eol - the "text" attribute in .gitattributes There are different types of content: - (1) Files with only LF - (2) Files with only CRLF - (3) Files with mixed LF and CRLF - (4) Files with LF and/or CRLF with CR not followed by LF - (5) Files which are binary (e.g. have NUL bytes) Recently the question came up, how files with mixed EOLs are handled by Git (and libgit2) when they are checked out and core.autocrlf=true. See http://git.661346.n2.nabble.com/The-different-EOL-behavior-between-libgit2-based-software-and-official-Git-td7613670.html#a7613801 Add the EXPENSIVE t0027-auto-crlf.sh to test all combination of files and parameters for both "git add/commit" and "git checkout". Signed-off-by: Torsten Bögershausen <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b0cdb4d commit 343151d

File tree

1 file changed

+265
-0
lines changed

1 file changed

+265
-0
lines changed

t/t0027-auto-crlf.sh

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
#!/bin/sh
2+
3+
test_description='CRLF conversion all combinations'
4+
5+
. ./test-lib.sh
6+
7+
if ! test_have_prereq EXPENSIVE
8+
then
9+
skip_all="EXPENSIVE not set"
10+
test_done
11+
fi
12+
13+
14+
compare_files()
15+
{
16+
od -c <"$1" >"$1".expect &&
17+
od -c <"$2" >"$2".actual &&
18+
test_cmp "$1".expect "$2".actual &&
19+
rm "$1".expect "$2".actual
20+
}
21+
22+
compare_ws_file()
23+
{
24+
pfx=$1
25+
exp=$2.expect
26+
act=$pfx.actual.$3
27+
od -c <"$2" >"$exp" &&
28+
od -c <"$3" >"$act" &&
29+
test_cmp $exp $act &&
30+
rm $exp $act
31+
}
32+
33+
create_gitattributes()
34+
{
35+
txtbin=$1
36+
case "$txtbin" in
37+
auto)
38+
echo "*.txt text=auto" >.gitattributes
39+
;;
40+
text)
41+
echo "*.txt text" >.gitattributes
42+
;;
43+
-text)
44+
echo "*.txt -text" >.gitattributes
45+
;;
46+
*)
47+
echo >.gitattributes
48+
;;
49+
esac
50+
}
51+
52+
create_file_in_repo()
53+
{
54+
crlf=$1
55+
txtbin=$2
56+
create_gitattributes "$txtbin" &&
57+
for f in LF CRLF LF_mix_CR CRLF_mix_LF CRLF_nul
58+
do
59+
pfx=crlf_${crlf}_attr_${txtbin}_$f.txt &&
60+
cp $f $pfx && git -c core.autocrlf=$crlf add $pfx
61+
done &&
62+
git commit -m "core.autocrlf $crlf"
63+
}
64+
65+
check_files_in_repo()
66+
{
67+
crlf=$1
68+
txtbin=$2
69+
lfname=$3
70+
crlfname=$4
71+
lfmixcrlf=$5
72+
lfmixcr=$6
73+
crlfnul=$7
74+
pfx=crlf_${crlf}_attr_${txtbin}_ &&
75+
compare_files $lfname ${pfx}LF.txt &&
76+
compare_files $crlfname ${pfx}CRLF.txt &&
77+
compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt &&
78+
compare_files $lfmixcr ${pfx}LF_mix_CR.txt &&
79+
compare_files $crlfnul ${pfx}CRLF_nul.txt
80+
}
81+
82+
83+
check_files_in_ws()
84+
{
85+
eol=$1
86+
crlf=$2
87+
txtbin=$3
88+
lfname=$4
89+
crlfname=$5
90+
lfmixcrlf=$6
91+
lfmixcr=$7
92+
crlfnul=$8
93+
create_gitattributes $txtbin &&
94+
git config core.autocrlf $crlf &&
95+
pfx=eol_${eol}_crlf_${crlf}_attr_${txtbin}_ &&
96+
src=crlf_false_attr__ &&
97+
for f in LF CRLF LF_mix_CR CRLF_mix_LF CRLF_nul
98+
do
99+
rm $src$f.txt &&
100+
if test -z "$eol"; then
101+
git checkout $src$f.txt
102+
else
103+
git -c core.eol=$eol checkout $src$f.txt
104+
fi
105+
done
106+
107+
108+
test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$txtbin file=LF" "
109+
compare_ws_file $pfx $lfname ${src}LF.txt
110+
"
111+
test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$txtbin file=CRLF" "
112+
compare_ws_file $pfx $crlfname ${src}CRLF.txt
113+
"
114+
test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$txtbin file=CRLF_mix_LF" "
115+
compare_ws_file $pfx $lfmixcrlf ${src}CRLF_mix_LF.txt
116+
"
117+
test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$txtbin file=LF_mix_CR" "
118+
compare_ws_file $pfx $lfmixcr ${src}LF_mix_CR.txt
119+
"
120+
test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$txtbin file=CRLF_nul" "
121+
compare_ws_file $pfx $crlfnul ${src}CRLF_nul.txt
122+
"
123+
}
124+
125+
#######
126+
(
127+
type od >/dev/null &&
128+
printf "line1Q\r\nline2\r\nline3" | q_to_nul >CRLF_nul &&
129+
cat >expect <<-EOF &&
130+
0000000 l i n e 1 \0 \r \n l i n e 2 \r \n l
131+
0000020 i n e 3
132+
0000024
133+
EOF
134+
od -c CRLF_nul | sed -e "s/[ ][ ]*/ /g" -e "s/ *$//" >actual
135+
test_cmp expect actual &&
136+
rm expect actual
137+
) || {
138+
skip_all="od not found or od -c not usable"
139+
exit 0
140+
test_done
141+
}
142+
143+
test_expect_success 'setup master' '
144+
echo >.gitattributes &&
145+
git checkout -b master &&
146+
git add .gitattributes &&
147+
git commit -m "add .gitattributes" "" &&
148+
printf "line1\nline2\nline3" >LF &&
149+
printf "line1\r\nline2\r\nline3" >CRLF &&
150+
printf "line1\r\nline2\nline3" >CRLF_mix_LF &&
151+
printf "line1\nline2\rline3" >LF_mix_CR &&
152+
printf "line1\r\nline2\rline3" >CRLF_mix_CR &&
153+
printf "line1Q\nline2\nline3" | q_to_nul >LF_nul
154+
'
155+
# CRLF_nul had been created above
156+
157+
test_expect_success 'create files' '
158+
create_file_in_repo false "" &&
159+
create_file_in_repo true "" &&
160+
create_file_in_repo input "" &&
161+
162+
create_file_in_repo false "auto" &&
163+
create_file_in_repo true "auto" &&
164+
create_file_in_repo input "auto" &&
165+
166+
create_file_in_repo false "text" &&
167+
create_file_in_repo true "text" &&
168+
create_file_in_repo input "text" &&
169+
170+
create_file_in_repo false "-text" &&
171+
create_file_in_repo true "-text" &&
172+
create_file_in_repo input "-text" &&
173+
rm -f *.txt &&
174+
git reset --hard
175+
'
176+
177+
test_expect_success 'commit empty gitattribues' '
178+
check_files_in_repo false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
179+
check_files_in_repo true "" LF LF LF LF_mix_CR CRLF_nul &&
180+
check_files_in_repo input "" LF LF LF LF_mix_CR CRLF_nul
181+
'
182+
183+
test_expect_success 'commit text=auto' '
184+
check_files_in_repo false "auto" LF LF LF LF_mix_CR CRLF_nul &&
185+
check_files_in_repo true "auto" LF LF LF LF_mix_CR CRLF_nul &&
186+
check_files_in_repo input "auto" LF LF LF LF_mix_CR CRLF_nul
187+
'
188+
189+
test_expect_success 'commit text' '
190+
check_files_in_repo false "text" LF LF LF LF_mix_CR LF_nul &&
191+
check_files_in_repo true "text" LF LF LF LF_mix_CR LF_nul &&
192+
check_files_in_repo input "text" LF LF LF LF_mix_CR LF_nul
193+
'
194+
195+
test_expect_success 'commit -text' '
196+
check_files_in_repo false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
197+
check_files_in_repo true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul &&
198+
check_files_in_repo input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
199+
'
200+
201+
################################################################################
202+
# Check how files in the repo are changed when they are checked out
203+
# How to read the table below:
204+
# - check_files_in_ws will check multiple files, see below
205+
# - parameter $1 : core.eol lf | crlf
206+
# - parameter $2 : core.autocrlf false | true | input
207+
# - parameter $3 : text in .gitattributs "" (empty) | auto | text | -text
208+
# - parameter $4 : reference for a file with only LF in the repo
209+
# - parameter $5 : reference for a file with only CRLF in the repo
210+
# - parameter $6 : reference for a file with mixed LF and CRLF in the repo
211+
# - parameter $7 : reference for a file with LF and CR in the repo (does somebody uses this ?)
212+
# - parameter $8 : reference for a file with CRLF and a NUL (should be handled as binary when auto)
213+
214+
check_files_in_ws lf false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
215+
check_files_in_ws lf true "" CRLF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
216+
check_files_in_ws lf input "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
217+
218+
check_files_in_ws lf false "auto" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
219+
check_files_in_ws lf true "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul
220+
check_files_in_ws lf input "auto" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
221+
222+
check_files_in_ws lf false "text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
223+
check_files_in_ws lf true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
224+
check_files_in_ws lf input "text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
225+
226+
check_files_in_ws lf false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
227+
check_files_in_ws lf true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
228+
check_files_in_ws lf input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
229+
230+
###########
231+
#core.autocrlf=input is forbidden with core.eol=crlf
232+
check_files_in_ws crlf false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
233+
check_files_in_ws crlf true "" CRLF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
234+
235+
check_files_in_ws crlf false "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul
236+
check_files_in_ws crlf true "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul
237+
238+
check_files_in_ws crlf false "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
239+
check_files_in_ws crlf true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
240+
241+
check_files_in_ws crlf false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
242+
check_files_in_ws crlf true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
243+
244+
if test_have_prereq MINGW
245+
then
246+
check_files_in_ws "" false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
247+
check_files_in_ws "" true "" CRLF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
248+
check_files_in_ws "" false "auto" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
249+
check_files_in_ws "" true "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul
250+
check_files_in_ws "" false "text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
251+
check_files_in_ws "" true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
252+
check_files_in_ws "" false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
253+
check_files_in_ws "" true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
254+
255+
check_files_in_ws native false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
256+
check_files_in_ws native true "" CRLF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
257+
check_files_in_ws native false "auto" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
258+
check_files_in_ws native true "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul
259+
check_files_in_ws native false "text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
260+
check_files_in_ws native true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
261+
check_files_in_ws native false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
262+
check_files_in_ws native true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
263+
fi
264+
265+
test_done

0 commit comments

Comments
 (0)