t3404: use write_script
[git] / t / t9802-git-p4-filetype.sh
1 #!/bin/sh
2
3 test_description='git p4 filetype tests'
4
5 . ./lib-git-p4.sh
6
7 test_expect_success 'start p4d' '
8         start_p4d
9 '
10
11 #
12 # This series of tests checks newline handling  Both p4 and
13 # git store newlines as \n, and have options to choose how
14 # newlines appear in checked-out files.
15 #
16 test_expect_success 'p4 client newlines, unix' '
17         (
18                 cd "$cli" &&
19                 p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
20                 printf "unix\ncrlf\n" >f-unix &&
21                 printf "unix\r\ncrlf\r\n" >f-unix-as-crlf &&
22                 p4 add -t text f-unix &&
23                 p4 submit -d f-unix &&
24
25                 # LineEnd: unix; should be no change after sync
26                 cp f-unix f-unix-orig &&
27                 p4 sync -f &&
28                 test_cmp f-unix-orig f-unix &&
29
30                 # make sure stored in repo as unix newlines
31                 # use sed to eat python-appended newline
32                 p4 -G print //depot/f-unix | marshal_dump data 2 |\
33                     sed \$d >f-unix-p4-print &&
34                 test_cmp f-unix-orig f-unix-p4-print &&
35
36                 # switch to win, make sure lf -> crlf
37                 p4 client -o | sed "/LineEnd/s/:.*/:win/" | p4 client -i &&
38                 p4 sync -f &&
39                 test_cmp f-unix-as-crlf f-unix
40         )
41 '
42
43 test_expect_success 'p4 client newlines, win' '
44         (
45                 cd "$cli" &&
46                 p4 client -o | sed "/LineEnd/s/:.*/:win/" | p4 client -i &&
47                 printf "win\r\ncrlf\r\n" >f-win &&
48                 printf "win\ncrlf\n" >f-win-as-lf &&
49                 p4 add -t text f-win &&
50                 p4 submit -d f-win &&
51
52                 # LineEnd: win; should be no change after sync
53                 cp f-win f-win-orig &&
54                 p4 sync -f &&
55                 test_cmp f-win-orig f-win &&
56
57                 # make sure stored in repo as unix newlines
58                 # use sed to eat python-appened newline
59                 p4 -G print //depot/f-win | marshal_dump data 2 |\
60                     sed \$d >f-win-p4-print &&
61                 test_cmp f-win-as-lf f-win-p4-print &&
62
63                 # switch to unix, make sure lf -> crlf
64                 p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
65                 p4 sync -f &&
66                 test_cmp f-win-as-lf f-win
67         )
68 '
69
70 test_expect_success 'ensure blobs store only lf newlines' '
71         test_when_finished cleanup_git &&
72         (
73                 cd "$git" &&
74                 git init &&
75                 git p4 sync //depot@all &&
76
77                 # verify the files in .git are stored only with newlines
78                 o=$(git ls-tree p4/master -- f-unix | cut -f1 | cut -d\  -f3) &&
79                 git cat-file blob $o >f-unix-blob &&
80                 test_cmp "$cli"/f-unix-orig f-unix-blob &&
81
82                 o=$(git ls-tree p4/master -- f-win | cut -f1 | cut -d\  -f3) &&
83                 git cat-file blob $o >f-win-blob &&
84                 test_cmp "$cli"/f-win-as-lf f-win-blob &&
85
86                 rm f-unix-blob f-win-blob
87         )
88 '
89
90 test_expect_success 'gitattributes setting eol=lf produces lf newlines' '
91         test_when_finished cleanup_git &&
92         (
93                 # checkout the files and make sure core.eol works as planned
94                 cd "$git" &&
95                 git init &&
96                 echo "* eol=lf" >.gitattributes &&
97                 git p4 sync //depot@all &&
98                 git checkout -b master p4/master &&
99                 test_cmp "$cli"/f-unix-orig f-unix &&
100                 test_cmp "$cli"/f-win-as-lf f-win
101         )
102 '
103
104 test_expect_success 'gitattributes setting eol=crlf produces crlf newlines' '
105         test_when_finished cleanup_git &&
106         (
107                 # checkout the files and make sure core.eol works as planned
108                 cd "$git" &&
109                 git init &&
110                 echo "* eol=crlf" >.gitattributes &&
111                 git p4 sync //depot@all &&
112                 git checkout -b master p4/master &&
113                 test_cmp "$cli"/f-unix-as-crlf f-unix &&
114                 test_cmp "$cli"/f-win-orig f-win
115         )
116 '
117
118 test_expect_success 'crlf cleanup' '
119         (
120                 cd "$cli" &&
121                 rm f-unix-orig f-unix-as-crlf &&
122                 rm f-win-orig f-win-as-lf &&
123                 p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
124                 p4 sync -f
125         )
126 '
127
128 test_expect_success 'utf-16 file create' '
129         (
130                 cd "$cli" &&
131
132                 # p4 saves this verbatim
133                 printf "three\nline\ntext\n" >f-ascii &&
134                 p4 add -t text f-ascii &&
135
136                 # p4 adds \377\376 header
137                 cp f-ascii f-ascii-as-utf16 &&
138                 p4 add -t utf16 f-ascii-as-utf16 &&
139
140                 # p4 saves this exactly as iconv produced it
141                 printf "three\nline\ntext\n" | iconv -f ascii -t utf-16 >f-utf16 &&
142                 p4 add -t utf16 f-utf16 &&
143
144                 # this also is unchanged
145                 cp f-utf16 f-utf16-as-text &&
146                 p4 add -t text f-utf16-as-text &&
147
148                 p4 submit -d "f files" &&
149
150                 # force update of client files
151                 p4 sync -f
152         )
153 '
154
155 test_expect_success 'utf-16 file test' '
156         test_when_finished cleanup_git &&
157         git p4 clone --dest="$git" //depot@all &&
158         (
159                 cd "$git" &&
160
161                 test_cmp "$cli/f-ascii" f-ascii &&
162                 test_cmp "$cli/f-ascii-as-utf16" f-ascii-as-utf16 &&
163                 test_cmp "$cli/f-utf16" f-utf16 &&
164                 test_cmp "$cli/f-utf16-as-text" f-utf16-as-text
165         )
166 '
167
168 test_expect_success 'keyword file create' '
169         (
170                 cd "$cli" &&
171
172                 printf "id\n\$Id\$\n\$Author\$\ntext\n" >k-text-k &&
173                 p4 add -t text+k k-text-k &&
174
175                 cp k-text-k k-text-ko &&
176                 p4 add -t text+ko k-text-ko &&
177
178                 cat k-text-k | iconv -f ascii -t utf-16 >k-utf16-k &&
179                 p4 add -t utf16+k k-utf16-k &&
180
181                 cp k-utf16-k k-utf16-ko &&
182                 p4 add -t utf16+ko k-utf16-ko &&
183
184                 p4 submit -d "k files" &&
185                 p4 sync -f
186         )
187 '
188
189 build_smush() {
190         cat >k_smush.py <<-\EOF &&
191         import re, sys
192         sys.stdout.write(re.sub(r'(?i)\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$', r'$\1$', sys.stdin.read()))
193         EOF
194         cat >ko_smush.py <<-\EOF
195         import re, sys
196         sys.stdout.write(re.sub(r'(?i)\$(Id|Header):[^$]*\$', r'$\1$', sys.stdin.read()))
197         EOF
198 }
199
200 test_expect_success 'keyword file test' '
201         build_smush &&
202         test_when_finished rm -f k_smush.py ko_smush.py &&
203         test_when_finished cleanup_git &&
204         git p4 clone --dest="$git" //depot@all &&
205         (
206                 cd "$git" &&
207
208                 # text, ensure unexpanded
209                 "$PYTHON_PATH" "$TRASH_DIRECTORY/k_smush.py" <"$cli/k-text-k" >cli-k-text-k-smush &&
210                 test_cmp cli-k-text-k-smush k-text-k &&
211                 "$PYTHON_PATH" "$TRASH_DIRECTORY/ko_smush.py" <"$cli/k-text-ko" >cli-k-text-ko-smush &&
212                 test_cmp cli-k-text-ko-smush k-text-ko &&
213
214                 # utf16, even though p4 expands keywords, git p4 does not
215                 # try to undo that
216                 test_cmp "$cli/k-utf16-k" k-utf16-k &&
217                 test_cmp "$cli/k-utf16-ko" k-utf16-ko
218         )
219 '
220
221 build_gendouble() {
222         cat >gendouble.py <<-\EOF
223         import sys
224         import struct
225
226         s = struct.pack(">LL18s",
227                         0x00051607,  # AppleDouble
228                         0x00020000,  # version 2
229                         ""           # pad to 26 bytes
230         )
231         sys.stdout.write(s)
232         EOF
233 }
234
235 test_expect_success 'ignore apple' '
236         test_when_finished rm -f gendouble.py &&
237         build_gendouble &&
238         (
239                 cd "$cli" &&
240                 test-genrandom apple 1024 >double.png &&
241                 "$PYTHON_PATH" "$TRASH_DIRECTORY/gendouble.py" >%double.png &&
242                 p4 add -t apple double.png &&
243                 p4 submit -d appledouble
244         ) &&
245         test_when_finished cleanup_git &&
246         git p4 clone --dest="$git" //depot@all &&
247         (
248                 cd "$git" &&
249                 test ! -f double.png
250         )
251 '
252
253 test_expect_success SYMLINKS 'create p4 symlink' '
254         cd "$cli" &&
255         ln -s symlink-target symlink &&
256         p4 add symlink &&
257         p4 submit -d "add symlink"
258 '
259
260 test_expect_success SYMLINKS 'ensure p4 symlink parsed correctly' '
261         test_when_finished cleanup_git &&
262         git p4 clone --dest="$git" //depot@all &&
263         (
264                 cd "$git" &&
265                 test -L symlink &&
266                 test $(readlink symlink) = symlink-target
267         )
268 '
269
270 test_expect_success SYMLINKS 'empty symlink target' '
271         (
272                 # first create the file as a file
273                 cd "$cli" &&
274                 >empty-symlink &&
275                 p4 add empty-symlink &&
276                 p4 submit -d "add empty-symlink as a file"
277         ) &&
278         (
279                 # now change it to be a symlink to "target1"
280                 cd "$cli" &&
281                 p4 edit empty-symlink &&
282                 p4 reopen -t symlink empty-symlink &&
283                 rm empty-symlink &&
284                 ln -s target1 empty-symlink &&
285                 p4 add empty-symlink &&
286                 p4 submit -d "make empty-symlink point to target1"
287         ) &&
288         (
289                 # Hack the p4 depot to make the symlink point to nothing;
290                 # this should not happen in reality, but shows up
291                 # in p4 repos in the wild.
292                 #
293                 # The sed expression changes this:
294                 #     @@
295                 #     text
296                 #     @target1
297                 #     @
298                 # to this:
299                 #     @@
300                 #     text
301                 #     @@
302                 #
303                 cd "$db/depot" &&
304                 sed "/@target1/{; s/target1/@/; n; d; }" \
305                     empty-symlink,v >empty-symlink,v.tmp &&
306                 mv empty-symlink,v.tmp empty-symlink,v
307         ) &&
308         (
309                 # Make sure symlink really is empty.  Asking
310                 # p4 to sync here will make it generate errors.
311                 cd "$cli" &&
312                 p4 print -q //depot/empty-symlink#2 >out &&
313                 test ! -s out
314         ) &&
315         test_when_finished cleanup_git &&
316
317         # make sure git p4 handles it without error
318         git p4 clone --dest="$git" //depot@all &&
319
320         # fix the symlink, make it point to "target2"
321         (
322                 cd "$cli" &&
323                 p4 open empty-symlink &&
324                 rm empty-symlink &&
325                 ln -s target2 empty-symlink &&
326                 p4 submit -d "make empty-symlink point to target2"
327         ) &&
328         cleanup_git &&
329         git p4 clone --dest="$git" //depot@all &&
330         (
331                 cd "$git" &&
332                 test $(readlink empty-symlink) = target2
333         )
334 '
335
336 test_expect_success 'kill p4d' '
337         kill_p4d
338 '
339
340 test_done