Merge branch 'jk/git-dir-lookup'
[git] / t / t9809-git-p4-client-view.sh
1 #!/bin/sh
2
3 test_description='git-p4 client view'
4
5 . ./lib-git-p4.sh
6
7 test_expect_success 'start p4d' '
8         start_p4d
9 '
10
11 #
12 # Construct a client with this list of View lines
13 #
14 client_view() {
15         (
16                 cat <<-EOF &&
17                 Client: client
18                 Description: client
19                 Root: $cli
20                 View:
21                 EOF
22                 for arg ; do
23                         printf "\t$arg\n"
24                 done
25         ) | p4 client -i
26 }
27
28 #
29 # Verify these files exist, exactly.  Caller creates
30 # a list of files in file "files".
31 #
32 check_files_exist() {
33         ok=0 &&
34         num=${#@} &&
35         for arg ; do
36                 test_path_is_file "$arg" &&
37                 ok=$(($ok + 1))
38         done &&
39         test $ok -eq $num &&
40         test_line_count = $num files
41 }
42
43 #
44 # Sync up the p4 client, make sure the given files (and only
45 # those) exist.
46 #
47 client_verify() {
48         (
49                 cd "$cli" &&
50                 p4 sync &&
51                 find . -type f ! -name files >files &&
52                 check_files_exist "$@"
53         )
54 }
55
56 #
57 # Make sure the named files, exactly, exist.
58 #
59 git_verify() {
60         (
61                 cd "$git" &&
62                 git ls-files >files &&
63                 check_files_exist "$@"
64         )
65 }
66
67 # //depot
68 #   - dir1
69 #     - file11
70 #     - file12
71 #   - dir2
72 #     - file21
73 #     - file22
74 test_expect_success 'init depot' '
75         (
76                 cd "$cli" &&
77                 for d in 1 2 ; do
78                         mkdir -p dir$d &&
79                         for f in 1 2 ; do
80                                 echo dir$d/file$d$f >dir$d/file$d$f &&
81                                 p4 add dir$d/file$d$f &&
82                                 p4 submit -d "dir$d/file$d$f"
83                         done
84                 done &&
85                 find . -type f ! -name files >files &&
86                 check_files_exist dir1/file11 dir1/file12 \
87                                   dir2/file21 dir2/file22
88         )
89 '
90
91 # double % for printf
92 test_expect_success 'unsupported view wildcard %%n' '
93         client_view "//depot/%%%%1/sub/... //client/sub/%%%%1/..." &&
94         test_when_finished cleanup_git &&
95         test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
96 '
97
98 test_expect_success 'unsupported view wildcard *' '
99         client_view "//depot/*/bar/... //client/*/bar/..." &&
100         test_when_finished cleanup_git &&
101         test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
102 '
103
104 test_expect_success 'wildcard ... only supported at end of spec 1' '
105         client_view "//depot/.../file11 //client/.../file11" &&
106         test_when_finished cleanup_git &&
107         test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
108 '
109
110 test_expect_success 'wildcard ... only supported at end of spec 2' '
111         client_view "//depot/.../a/... //client/.../a/..." &&
112         test_when_finished cleanup_git &&
113         test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
114 '
115
116 test_expect_success 'basic map' '
117         client_view "//depot/dir1/... //client/cli1/..." &&
118         files="cli1/file11 cli1/file12" &&
119         client_verify $files &&
120         test_when_finished cleanup_git &&
121         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
122         git_verify $files
123 '
124
125 test_expect_success 'client view with no mappings' '
126         client_view &&
127         client_verify &&
128         test_when_finished cleanup_git &&
129         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
130         git_verify
131 '
132
133 test_expect_success 'single file map' '
134         client_view "//depot/dir1/file11 //client/file11" &&
135         files="file11" &&
136         client_verify $files &&
137         test_when_finished cleanup_git &&
138         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
139         git_verify $files
140 '
141
142 test_expect_success 'later mapping takes precedence (entire repo)' '
143         client_view "//depot/dir1/... //client/cli1/..." \
144                     "//depot/... //client/cli2/..." &&
145         files="cli2/dir1/file11 cli2/dir1/file12
146                cli2/dir2/file21 cli2/dir2/file22" &&
147         client_verify $files &&
148         test_when_finished cleanup_git &&
149         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
150         git_verify $files
151 '
152
153 test_expect_success 'later mapping takes precedence (partial repo)' '
154         client_view "//depot/dir1/... //client/..." \
155                     "//depot/dir2/... //client/..." &&
156         files="file21 file22" &&
157         client_verify $files &&
158         test_when_finished cleanup_git &&
159         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
160         git_verify $files
161 '
162
163 # Reading the view backwards,
164 #   dir2 goes to cli12
165 #   dir1 cannot go to cli12 since it was filled by dir2
166 #   dir1 also does not go to cli3, since the second rule
167 #     noticed that it matched, but was already filled
168 test_expect_success 'depot path matching rejected client path' '
169         client_view "//depot/dir1/... //client/cli3/..." \
170                     "//depot/dir1/... //client/cli12/..." \
171                     "//depot/dir2/... //client/cli12/..." &&
172         files="cli12/file21 cli12/file22" &&
173         client_verify $files &&
174         test_when_finished cleanup_git &&
175         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
176         git_verify $files
177 '
178
179 # since both have the same //client/..., the exclusion
180 # rule keeps everything out
181 test_expect_success 'exclusion wildcard, client rhs same (odd)' '
182         client_view "//depot/... //client/..." \
183                     "-//depot/dir2/... //client/..." &&
184         client_verify &&
185         test_when_finished cleanup_git &&
186         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
187         git_verify
188 '
189
190 test_expect_success 'exclusion wildcard, client rhs different (normal)' '
191         client_view "//depot/... //client/..." \
192                     "-//depot/dir2/... //client/dir2/..." &&
193         files="dir1/file11 dir1/file12" &&
194         client_verify $files &&
195         test_when_finished cleanup_git &&
196         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
197         git_verify $files
198 '
199
200 test_expect_success 'exclusion single file' '
201         client_view "//depot/... //client/..." \
202                     "-//depot/dir2/file22 //client/file22" &&
203         files="dir1/file11 dir1/file12 dir2/file21" &&
204         client_verify $files &&
205         test_when_finished cleanup_git &&
206         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
207         git_verify $files
208 '
209
210 test_expect_success 'overlay wildcard' '
211         client_view "//depot/dir1/... //client/cli/..." \
212                     "+//depot/dir2/... //client/cli/...\n" &&
213         files="cli/file11 cli/file12 cli/file21 cli/file22" &&
214         client_verify $files &&
215         test_when_finished cleanup_git &&
216         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
217         git_verify $files
218 '
219
220 test_expect_success 'overlay single file' '
221         client_view "//depot/dir1/... //client/cli/..." \
222                     "+//depot/dir2/file21 //client/cli/file21" &&
223         files="cli/file11 cli/file12 cli/file21" &&
224         client_verify $files &&
225         test_when_finished cleanup_git &&
226         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
227         git_verify $files
228 '
229
230 test_expect_success 'exclusion with later inclusion' '
231         client_view "//depot/... //client/..." \
232                     "-//depot/dir2/... //client/dir2/..." \
233                     "//depot/dir2/... //client/dir2incl/..." &&
234         files="dir1/file11 dir1/file12 dir2incl/file21 dir2incl/file22" &&
235         client_verify $files &&
236         test_when_finished cleanup_git &&
237         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
238         git_verify $files
239 '
240
241 test_expect_success 'quotes on rhs only' '
242         client_view "//depot/dir1/... \"//client/cdir 1/...\"" &&
243         client_verify "cdir 1/file11" "cdir 1/file12" &&
244         test_when_finished cleanup_git &&
245         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
246         git_verify "cdir 1/file11" "cdir 1/file12"
247 '
248
249 #
250 # What happens when two files of the same name are overlayed together?
251 # The last-listed file should take preference.
252 #
253 # //depot
254 #   - dir1
255 #     - file11
256 #     - file12
257 #     - filecollide
258 #   - dir2
259 #     - file21
260 #     - file22
261 #     - filecollide
262 #
263 test_expect_success 'overlay collision setup' '
264         client_view "//depot/... //client/..." &&
265         (
266                 cd "$cli" &&
267                 p4 sync &&
268                 echo dir1/filecollide >dir1/filecollide &&
269                 p4 add dir1/filecollide &&
270                 p4 submit -d dir1/filecollide &&
271                 echo dir2/filecollide >dir2/filecollide &&
272                 p4 add dir2/filecollide &&
273                 p4 submit -d dir2/filecollide
274         )
275 '
276
277 test_expect_success 'overlay collision 1 to 2' '
278         client_view "//depot/dir1/... //client/..." \
279                     "+//depot/dir2/... //client/..." &&
280         files="file11 file12 file21 file22 filecollide" &&
281         echo dir2/filecollide >actual &&
282         client_verify $files &&
283         test_cmp actual "$cli"/filecollide &&
284         test_when_finished cleanup_git &&
285         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
286         git_verify $files &&
287         test_cmp actual "$git"/filecollide
288 '
289
290 test_expect_failure 'overlay collision 2 to 1' '
291         client_view "//depot/dir2/... //client/..." \
292                     "+//depot/dir1/... //client/..." &&
293         files="file11 file12 file21 file22 filecollide" &&
294         echo dir1/filecollide >actual &&
295         client_verify $files &&
296         test_cmp actual "$cli"/filecollide &&
297         test_when_finished cleanup_git &&
298         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
299         git_verify $files &&
300         test_cmp actual "$git"/filecollide
301 '
302
303 test_expect_success 'overlay collision delete 2' '
304         client_view "//depot/... //client/..." &&
305         (
306                 cd "$cli" &&
307                 p4 sync &&
308                 p4 delete dir2/filecollide &&
309                 p4 submit -d "remove dir2/filecollide"
310         )
311 '
312
313 # no filecollide, got deleted with dir2
314 test_expect_failure 'overlay collision 1 to 2, but 2 deleted' '
315         client_view "//depot/dir1/... //client/..." \
316                     "+//depot/dir2/... //client/..." &&
317         files="file11 file12 file21 file22" &&
318         client_verify $files &&
319         test_when_finished cleanup_git &&
320         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
321         git_verify $files
322 '
323
324 test_expect_success 'overlay collision update 1' '
325         client_view "//depot/dir1/... //client/dir1/..." &&
326         (
327                 cd "$cli" &&
328                 p4 sync &&
329                 p4 open dir1/filecollide &&
330                 echo dir1/filecollide update >dir1/filecollide &&
331                 p4 submit -d "update dir1/filecollide"
332         )
333 '
334
335 # still no filecollide, dir2 still wins with the deletion even though the
336 # change to dir1 is more recent
337 test_expect_failure 'overlay collision 1 to 2, but 2 deleted, then 1 updated' '
338         client_view "//depot/dir1/... //client/..." \
339                     "+//depot/dir2/... //client/..." &&
340         files="file11 file12 file21 file22" &&
341         client_verify $files &&
342         test_when_finished cleanup_git &&
343         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
344         git_verify $files
345 '
346
347 test_expect_success 'overlay collision delete filecollides' '
348         client_view "//depot/... //client/..." &&
349         (
350                 cd "$cli" &&
351                 p4 sync &&
352                 p4 delete dir1/filecollide dir2/filecollide &&
353                 p4 submit -d "remove filecollides"
354         )
355 '
356
357 #
358 # Overlays as part of sync, rather than initial checkout:
359 #   1.  add a file in dir1
360 #   2.  sync to include it
361 #   3.  add same file in dir2
362 #   4.  sync, make sure content switches as dir2 has priority
363 #   5.  add another file in dir1
364 #   6.  sync
365 #   7.  add/delete same file in dir2
366 #   8.  sync, make sure it disappears, again dir2 wins
367 #   9.  cleanup
368 #
369 # //depot
370 #   - dir1
371 #     - file11
372 #     - file12
373 #     - colA
374 #     - colB
375 #   - dir2
376 #     - file21
377 #     - file22
378 #     - colA
379 #     - colB
380 #
381 test_expect_success 'overlay sync: add colA in dir1' '
382         client_view "//depot/dir1/... //client/dir1/..." &&
383         (
384                 cd "$cli" &&
385                 p4 sync &&
386                 echo dir1/colA >dir1/colA &&
387                 p4 add dir1/colA &&
388                 p4 submit -d dir1/colA
389         )
390 '
391
392 test_expect_success 'overlay sync: initial git checkout' '
393         client_view "//depot/dir1/... //client/..." \
394                     "+//depot/dir2/... //client/..." &&
395         files="file11 file12 file21 file22 colA" &&
396         echo dir1/colA >actual &&
397         client_verify $files &&
398         test_cmp actual "$cli"/colA &&
399         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
400         git_verify $files &&
401         test_cmp actual "$git"/colA
402 '
403
404 test_expect_success 'overlay sync: add colA in dir2' '
405         client_view "//depot/dir2/... //client/dir2/..." &&
406         (
407                 cd "$cli" &&
408                 p4 sync &&
409                 echo dir2/colA >dir2/colA &&
410                 p4 add dir2/colA &&
411                 p4 submit -d dir2/colA
412         )
413 '
414
415 test_expect_success 'overlay sync: colA content switch' '
416         client_view "//depot/dir1/... //client/..." \
417                     "+//depot/dir2/... //client/..." &&
418         files="file11 file12 file21 file22 colA" &&
419         echo dir2/colA >actual &&
420         client_verify $files &&
421         test_cmp actual "$cli"/colA &&
422         (
423                 cd "$git" &&
424                 "$GITP4" sync --use-client-spec &&
425                 git merge --ff-only p4/master
426         ) &&
427         git_verify $files &&
428         test_cmp actual "$git"/colA
429 '
430
431 test_expect_success 'overlay sync: add colB in dir1' '
432         client_view "//depot/dir1/... //client/dir1/..." &&
433         (
434                 cd "$cli" &&
435                 p4 sync &&
436                 echo dir1/colB >dir1/colB &&
437                 p4 add dir1/colB &&
438                 p4 submit -d dir1/colB
439         )
440 '
441
442 test_expect_success 'overlay sync: colB appears' '
443         client_view "//depot/dir1/... //client/..." \
444                     "+//depot/dir2/... //client/..." &&
445         files="file11 file12 file21 file22 colA colB" &&
446         echo dir1/colB >actual &&
447         client_verify $files &&
448         test_cmp actual "$cli"/colB &&
449         (
450                 cd "$git" &&
451                 "$GITP4" sync --use-client-spec &&
452                 git merge --ff-only p4/master
453         ) &&
454         git_verify $files &&
455         test_cmp actual "$git"/colB
456 '
457
458 test_expect_success 'overlay sync: add/delete colB in dir2' '
459         client_view "//depot/dir2/... //client/dir2/..." &&
460         (
461                 cd "$cli" &&
462                 p4 sync &&
463                 echo dir2/colB >dir2/colB &&
464                 p4 add dir2/colB &&
465                 p4 submit -d dir2/colB &&
466                 p4 delete dir2/colB &&
467                 p4 submit -d "delete dir2/colB"
468         )
469 '
470
471 test_expect_success 'overlay sync: colB disappears' '
472         client_view "//depot/dir1/... //client/..." \
473                     "+//depot/dir2/... //client/..." &&
474         files="file11 file12 file21 file22 colA" &&
475         client_verify $files &&
476         test_when_finished cleanup_git &&
477         (
478                 cd "$git" &&
479                 "$GITP4" sync --use-client-spec &&
480                 git merge --ff-only p4/master
481         ) &&
482         git_verify $files
483 '
484
485 test_expect_success 'overlay sync: cleanup' '
486         client_view "//depot/... //client/..." &&
487         (
488                 cd "$cli" &&
489                 p4 sync &&
490                 p4 delete dir1/colA dir2/colA dir1/colB &&
491                 p4 submit -d "remove overlay sync files"
492         )
493 '
494
495 #
496 # Overlay tests again, but swapped so dir1 has priority.
497 #   1.  add a file in dir1
498 #   2.  sync to include it
499 #   3.  add same file in dir2
500 #   4.  sync, make sure content does not switch
501 #   5.  add another file in dir1
502 #   6.  sync
503 #   7.  add/delete same file in dir2
504 #   8.  sync, make sure it is still there
505 #   9.  cleanup
506 #
507 # //depot
508 #   - dir1
509 #     - file11
510 #     - file12
511 #     - colA
512 #     - colB
513 #   - dir2
514 #     - file21
515 #     - file22
516 #     - colA
517 #     - colB
518 #
519 test_expect_success 'overlay sync swap: add colA in dir1' '
520         client_view "//depot/dir1/... //client/dir1/..." &&
521         (
522                 cd "$cli" &&
523                 p4 sync &&
524                 echo dir1/colA >dir1/colA &&
525                 p4 add dir1/colA &&
526                 p4 submit -d dir1/colA
527         )
528 '
529
530 test_expect_success 'overlay sync swap: initial git checkout' '
531         client_view "//depot/dir2/... //client/..." \
532                     "+//depot/dir1/... //client/..." &&
533         files="file11 file12 file21 file22 colA" &&
534         echo dir1/colA >actual &&
535         client_verify $files &&
536         test_cmp actual "$cli"/colA &&
537         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
538         git_verify $files &&
539         test_cmp actual "$git"/colA
540 '
541
542 test_expect_success 'overlay sync swap: add colA in dir2' '
543         client_view "//depot/dir2/... //client/dir2/..." &&
544         (
545                 cd "$cli" &&
546                 p4 sync &&
547                 echo dir2/colA >dir2/colA &&
548                 p4 add dir2/colA &&
549                 p4 submit -d dir2/colA
550         )
551 '
552
553 test_expect_failure 'overlay sync swap: colA no content switch' '
554         client_view "//depot/dir2/... //client/..." \
555                     "+//depot/dir1/... //client/..." &&
556         files="file11 file12 file21 file22 colA" &&
557         echo dir1/colA >actual &&
558         client_verify $files &&
559         test_cmp actual "$cli"/colA &&
560         (
561                 cd "$git" &&
562                 "$GITP4" sync --use-client-spec &&
563                 git merge --ff-only p4/master
564         ) &&
565         git_verify $files &&
566         test_cmp actual "$git"/colA
567 '
568
569 test_expect_success 'overlay sync swap: add colB in dir1' '
570         client_view "//depot/dir1/... //client/dir1/..." &&
571         (
572                 cd "$cli" &&
573                 p4 sync &&
574                 echo dir1/colB >dir1/colB &&
575                 p4 add dir1/colB &&
576                 p4 submit -d dir1/colB
577         )
578 '
579
580 test_expect_success 'overlay sync swap: colB appears' '
581         client_view "//depot/dir2/... //client/..." \
582                     "+//depot/dir1/... //client/..." &&
583         files="file11 file12 file21 file22 colA colB" &&
584         echo dir1/colB >actual &&
585         client_verify $files &&
586         test_cmp actual "$cli"/colB &&
587         (
588                 cd "$git" &&
589                 "$GITP4" sync --use-client-spec &&
590                 git merge --ff-only p4/master
591         ) &&
592         git_verify $files &&
593         test_cmp actual "$git"/colB
594 '
595
596 test_expect_success 'overlay sync swap: add/delete colB in dir2' '
597         client_view "//depot/dir2/... //client/dir2/..." &&
598         (
599                 cd "$cli" &&
600                 p4 sync &&
601                 echo dir2/colB >dir2/colB &&
602                 p4 add dir2/colB &&
603                 p4 submit -d dir2/colB &&
604                 p4 delete dir2/colB &&
605                 p4 submit -d "delete dir2/colB"
606         )
607 '
608
609 test_expect_failure 'overlay sync swap: colB no change' '
610         client_view "//depot/dir2/... //client/..." \
611                     "+//depot/dir1/... //client/..." &&
612         files="file11 file12 file21 file22 colA colB" &&
613         echo dir1/colB >actual &&
614         client_verify $files &&
615         test_cmp actual "$cli"/colB &&
616         test_when_finished cleanup_git &&
617         (
618                 cd "$git" &&
619                 "$GITP4" sync --use-client-spec &&
620                 git merge --ff-only p4/master
621         ) &&
622         git_verify $files &&
623         test_cmp actual "$cli"/colB
624 '
625
626 test_expect_success 'overlay sync swap: cleanup' '
627         client_view "//depot/... //client/..." &&
628         (
629                 cd "$cli" &&
630                 p4 sync &&
631                 p4 delete dir1/colA dir2/colA dir1/colB &&
632                 p4 submit -d "remove overlay sync files"
633         )
634 '
635
636 #
637 # Rename directories to test quoting in depot-side mappings
638 # //depot
639 #    - "dir 1"
640 #       - file11
641 #       - file12
642 #    - "dir 2"
643 #       - file21
644 #       - file22
645 #
646 test_expect_success 'rename files to introduce spaces' '
647         client_view "//depot/... //client/..." &&
648         client_verify dir1/file11 dir1/file12 \
649                       dir2/file21 dir2/file22 &&
650         (
651                 cd "$cli" &&
652                 p4 open dir1/... &&
653                 p4 move dir1/... "dir 1"/... &&
654                 p4 open dir2/... &&
655                 p4 move dir2/... "dir 2"/... &&
656                 p4 submit -d "rename with spaces"
657         ) &&
658         client_verify "dir 1/file11" "dir 1/file12" \
659                       "dir 2/file21" "dir 2/file22"
660 '
661
662 test_expect_success 'quotes on lhs only' '
663         client_view "\"//depot/dir 1/...\" //client/cdir1/..." &&
664         files="cdir1/file11 cdir1/file12" &&
665         client_verify $files &&
666         test_when_finished cleanup_git &&
667         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
668         client_verify $files
669 '
670
671 test_expect_success 'quotes on both sides' '
672         client_view "\"//depot/dir 1/...\" \"//client/cdir 1/...\"" &&
673         client_verify "cdir 1/file11" "cdir 1/file12" &&
674         test_when_finished cleanup_git &&
675         "$GITP4" clone --use-client-spec --dest="$git" //depot &&
676         git_verify "cdir 1/file11" "cdir 1/file12"
677 '
678
679 test_expect_success 'kill p4d' '
680         kill_p4d
681 '
682
683 test_done