1#!/bin/sh
2
3test_description='git-cvsserver and git refspecs
4
5tests ability for git-cvsserver to switch between and compare
6tags, branches and other git refspecs'
7
8. ./test-lib.sh
9
10#########
11
12check_start_tree() {
13 rm -f "$WORKDIR/list.expected"
14 echo "start $1" >>"${WORKDIR}/check.log"
15}
16
17check_file() {
18 sandbox="$1"
19 file="$2"
20 ver="$3"
21 GIT_DIR=$SERVERDIR git show "${ver}:${file}" \
22 >"$WORKDIR/check.got" 2>"$WORKDIR/check.stderr"
23 test_cmp "$WORKDIR/check.got" "$sandbox/$file"
24 stat=$?
25 echo "check_file $sandbox $file $ver : $stat" >>"$WORKDIR/check.log"
26 echo "$file" >>"$WORKDIR/list.expected"
27 return $stat
28}
29
30check_end_tree() {
31 sandbox="$1" &&
32 find "$sandbox" -name CVS -prune -o -type f -print >"$WORKDIR/list.actual" &&
33 sort <"$WORKDIR/list.expected" >expected &&
34 sort <"$WORKDIR/list.actual" | sed -e "s%cvswork/%%" >actual &&
35 test_cmp expected actual &&
36 rm expected actual
37}
38
39check_end_full_tree() {
40 sandbox="$1" &&
41 sort <"$WORKDIR/list.expected" >expected &&
42 find "$sandbox" -name CVS -prune -o -type f -print |
43 sed -e "s%$sandbox/%%" | sort >act1 &&
44 test_cmp expected act1 &&
45 git ls-tree --name-only -r "$2" | sort >act2 &&
46 test_cmp expected act2 &&
47 rm expected act1 act2
48}
49
50#########
51
52check_diff() {
53 diffFile="$1"
54 vOld="$2"
55 vNew="$3"
56 rm -rf diffSandbox
57 git clone -q -n . diffSandbox &&
58 (
59 cd diffSandbox &&
60 git checkout "$vOld" &&
61 git apply -p0 --index <"../$diffFile" &&
62 git diff --exit-code "$vNew"
63 ) >check_diff_apply.out 2>&1
64}
65
66#########
67
68cvs >/dev/null 2>&1
69if test $? -ne 1
70then
71 skip_all='skipping git-cvsserver tests, cvs not found'
72 test_done
73fi
74if ! test_have_prereq PERL
75then
76 skip_all='skipping git-cvsserver tests, perl not available'
77 test_done
78fi
79perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || {
80 skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable'
81 test_done
82}
83
84unset GIT_DIR GIT_CONFIG
85WORKDIR=$(pwd)
86SERVERDIR=$(pwd)/gitcvs.git
87git_config="$SERVERDIR/config"
88CVSROOT=":fork:$SERVERDIR"
89CVSWORK="$(pwd)/cvswork"
90CVS_SERVER=git-cvsserver
91export CVSROOT CVS_SERVER
92
93rm -rf "$CVSWORK" "$SERVERDIR"
94test_expect_success 'setup v1, b1' '
95 echo "Simple text file" >textfile.c &&
96 echo "t2" >t2 &&
97 mkdir adir &&
98 echo "adir/afile line1" >adir/afile &&
99 echo "adir/afile line2" >>adir/afile &&
100 echo "adir/afile line3" >>adir/afile &&
101 echo "adir/afile line4" >>adir/afile &&
102 echo "adir/a2file" >>adir/a2file &&
103 mkdir adir/bdir &&
104 echo "adir/bdir/bfile line 1" >adir/bdir/bfile &&
105 echo "adir/bdir/bfile line 2" >>adir/bdir/bfile &&
106 echo "adir/bdir/b2file" >adir/bdir/b2file &&
107 git add textfile.c t2 adir &&
108 git commit -q -m "First Commit (v1)" &&
109 git tag v1 &&
110 git branch b1 &&
111 git clone -q --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
112 GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
113 GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log"
114'
115
116rm -rf cvswork
117test_expect_success 'cvs co v1' '
118 cvs -f -Q co -r v1 -d cvswork master >cvs.log 2>&1 &&
119 check_start_tree cvswork &&
120 check_file cvswork textfile.c v1 &&
121 check_file cvswork t2 v1 &&
122 check_file cvswork adir/afile v1 &&
123 check_file cvswork adir/a2file v1 &&
124 check_file cvswork adir/bdir/bfile v1 &&
125 check_file cvswork adir/bdir/b2file v1 &&
126 check_end_tree cvswork
127'
128
129rm -rf cvswork
130test_expect_success 'cvs co b1' '
131 cvs -f co -r b1 -d cvswork master >cvs.log 2>&1 &&
132 check_start_tree cvswork &&
133 check_file cvswork textfile.c v1 &&
134 check_file cvswork t2 v1 &&
135 check_file cvswork adir/afile v1 &&
136 check_file cvswork adir/a2file v1 &&
137 check_file cvswork adir/bdir/bfile v1 &&
138 check_file cvswork adir/bdir/b2file v1 &&
139 check_end_tree cvswork
140'
141
142test_expect_success 'cvs co b1 [cvswork3]' '
143 cvs -f co -r b1 -d cvswork3 master >cvs.log 2>&1 &&
144 check_start_tree cvswork3 &&
145 check_file cvswork3 textfile.c v1 &&
146 check_file cvswork3 t2 v1 &&
147 check_file cvswork3 adir/afile v1 &&
148 check_file cvswork3 adir/a2file v1 &&
149 check_file cvswork3 adir/bdir/bfile v1 &&
150 check_file cvswork3 adir/bdir/b2file v1 &&
151 check_end_full_tree cvswork3 v1
152'
153
154test_expect_success 'edit cvswork3 and save diff' '
155 (
156 cd cvswork3 &&
157 sed -e "s/line1/line1 - data/" adir/afile >adir/afileNEW &&
158 mv -f adir/afileNEW adir/afile &&
159 echo "afile5" >adir/afile5 &&
160 rm t2 &&
161 cvs -f add adir/afile5 &&
162 cvs -f rm t2 &&
163 ! cvs -f diff -N -u >"$WORKDIR/cvswork3edit.diff"
164 )
165'
166
167test_expect_success 'setup v1.2 on b1' '
168 git checkout b1 &&
169 echo "new v1.2" >t3 &&
170 rm t2 &&
171 sed -e "s/line3/line3 - more data/" adir/afile >adir/afileNEW &&
172 mv -f adir/afileNEW adir/afile &&
173 rm adir/a2file &&
174 echo "a3file" >>adir/a3file &&
175 echo "bfile line 3" >>adir/bdir/bfile &&
176 rm adir/bdir/b2file &&
177 echo "b3file" >adir/bdir/b3file &&
178 mkdir cdir &&
179 echo "cdir/cfile" >cdir/cfile &&
180 git add -A cdir adir t3 t2 &&
181 git commit -q -m 'v1.2' &&
182 git tag v1.2 &&
183 git push --tags gitcvs.git b1:b1
184'
185
186test_expect_success 'cvs -f up (on b1 adir)' '
187 ( cd cvswork/adir && cvs -f up -d ) >cvs.log 2>&1 &&
188 check_start_tree cvswork &&
189 check_file cvswork textfile.c v1 &&
190 check_file cvswork t2 v1 &&
191 check_file cvswork adir/afile v1.2 &&
192 check_file cvswork adir/a3file v1.2 &&
193 check_file cvswork adir/bdir/bfile v1.2 &&
194 check_file cvswork adir/bdir/b3file v1.2 &&
195 check_end_tree cvswork
196'
197
198test_expect_success 'cvs up (on b1 /)' '
199 ( cd cvswork && cvs -f up -d ) >cvs.log 2>&1 &&
200 check_start_tree cvswork &&
201 check_file cvswork textfile.c v1.2 &&
202 check_file cvswork t3 v1.2 &&
203 check_file cvswork adir/afile v1.2 &&
204 check_file cvswork adir/a3file v1.2 &&
205 check_file cvswork adir/bdir/bfile v1.2 &&
206 check_file cvswork adir/bdir/b3file v1.2 &&
207 check_file cvswork cdir/cfile v1.2 &&
208 check_end_tree cvswork
209'
210
211# Make sure "CVS/Tag" files didn't get messed up:
212test_expect_success 'cvs up (on b1 /) (again; check CVS/Tag files)' '
213 ( cd cvswork && cvs -f up -d ) >cvs.log 2>&1 &&
214 check_start_tree cvswork &&
215 check_file cvswork textfile.c v1.2 &&
216 check_file cvswork t3 v1.2 &&
217 check_file cvswork adir/afile v1.2 &&
218 check_file cvswork adir/a3file v1.2 &&
219 check_file cvswork adir/bdir/bfile v1.2 &&
220 check_file cvswork adir/bdir/b3file v1.2 &&
221 check_file cvswork cdir/cfile v1.2 &&
222 check_end_tree cvswork
223'
224
225# update to another version:
226test_expect_success 'cvs up -r v1' '
227 ( cd cvswork && cvs -f up -r v1 ) >cvs.log 2>&1 &&
228 check_start_tree cvswork &&
229 check_file cvswork textfile.c v1 &&
230 check_file cvswork t2 v1 &&
231 check_file cvswork adir/afile v1 &&
232 check_file cvswork adir/a2file v1 &&
233 check_file cvswork adir/bdir/bfile v1 &&
234 check_file cvswork adir/bdir/b2file v1 &&
235 check_end_tree cvswork
236'
237
238test_expect_success 'cvs up' '
239 ( cd cvswork && cvs -f up ) >cvs.log 2>&1 &&
240 check_start_tree cvswork &&
241 check_file cvswork textfile.c v1 &&
242 check_file cvswork t2 v1 &&
243 check_file cvswork adir/afile v1 &&
244 check_file cvswork adir/a2file v1 &&
245 check_file cvswork adir/bdir/bfile v1 &&
246 check_file cvswork adir/bdir/b2file v1 &&
247 check_end_tree cvswork
248'
249
250test_expect_success 'cvs up (again; check CVS/Tag files)' '
251 ( cd cvswork && cvs -f up -d ) >cvs.log 2>&1 &&
252 check_start_tree cvswork &&
253 check_file cvswork textfile.c v1 &&
254 check_file cvswork t2 v1 &&
255 check_file cvswork adir/afile v1 &&
256 check_file cvswork adir/a2file v1 &&
257 check_file cvswork adir/bdir/bfile v1 &&
258 check_file cvswork adir/bdir/b2file v1 &&
259 check_end_tree cvswork
260'
261
262test_expect_success 'setup simple b2' '
263 git branch b2 v1 &&
264 git push --tags gitcvs.git b2:b2
265'
266
267test_expect_success 'cvs co b2 [into cvswork2]' '
268 cvs -f co -r b2 -d cvswork2 master >cvs.log 2>&1 &&
269 check_start_tree cvswork &&
270 check_file cvswork textfile.c v1 &&
271 check_file cvswork t2 v1 &&
272 check_file cvswork adir/afile v1 &&
273 check_file cvswork adir/a2file v1 &&
274 check_file cvswork adir/bdir/bfile v1 &&
275 check_file cvswork adir/bdir/b2file v1 &&
276 check_end_tree cvswork
277'
278
279test_expect_success 'root dir edit [cvswork2]' '
280 (
281 cd cvswork2 && echo "Line 2" >>textfile.c &&
282 ! cvs -f diff -u >"$WORKDIR/cvsEdit1.diff" &&
283 cvs -f commit -m "edit textfile.c" textfile.c
284 ) >cvsEdit1.log 2>&1
285'
286
287test_expect_success 'root dir rm file [cvswork2]' '
288 (
289 cd cvswork2 &&
290 cvs -f rm -f t2 &&
291 cvs -f diff -u >../cvsEdit2-empty.diff &&
292 ! cvs -f diff -N -u >"$WORKDIR/cvsEdit2-N.diff" &&
293 cvs -f commit -m "rm t2"
294 ) >cvsEdit2.log 2>&1
295'
296
297test_expect_success 'subdir edit/add/rm files [cvswork2]' '
298 (
299 cd cvswork2 &&
300 sed -e "s/line 1/line 1 (v2)/" adir/bdir/bfile >adir/bdir/bfileNEW &&
301 mv -f adir/bdir/bfileNEW adir/bdir/bfile &&
302 rm adir/bdir/b2file &&
303 cd adir &&
304 cvs -f rm bdir/b2file &&
305 echo "4th file" >bdir/b4file &&
306 cvs -f add bdir/b4file &&
307 ! cvs -f diff -N -u >"$WORKDIR/cvsEdit3.diff" &&
308 git fetch gitcvs.git b2:b2 &&
309 (
310 cd .. &&
311 ! cvs -f diff -u -N -r v1.2 >"$WORKDIR/cvsEdit3-v1.2.diff" &&
312 ! cvs -f diff -u -N -r v1.2 -r v1 >"$WORKDIR/cvsEdit3-v1.2-v1.diff"
313 ) &&
314 cvs -f commit -m "various add/rm/edit"
315 ) >cvs.log 2>&1
316'
317
318test_expect_success 'validate result of edits [cvswork2]' '
319 git fetch gitcvs.git b2:b2 &&
320 git tag v2 b2 &&
321 git push --tags gitcvs.git b2:b2 &&
322 check_start_tree cvswork2 &&
323 check_file cvswork2 textfile.c v2 &&
324 check_file cvswork2 adir/afile v2 &&
325 check_file cvswork2 adir/a2file v2 &&
326 check_file cvswork2 adir/bdir/bfile v2 &&
327 check_file cvswork2 adir/bdir/b4file v2 &&
328 check_end_full_tree cvswork2 v2
329'
330
331test_expect_success 'validate basic diffs saved during above cvswork2 edits' '
332 test $(grep Index: cvsEdit1.diff | wc -l) = 1 &&
333 test_must_be_empty cvsEdit2-empty.diff &&
334 test $(grep Index: cvsEdit2-N.diff | wc -l) = 1 &&
335 test $(grep Index: cvsEdit3.diff | wc -l) = 3 &&
336 rm -rf diffSandbox &&
337 git clone -q -n . diffSandbox &&
338 (
339 cd diffSandbox &&
340 git checkout v1 &&
341 git apply -p0 --index <"$WORKDIR/cvsEdit1.diff" &&
342 git apply -p0 --index <"$WORKDIR/cvsEdit2-N.diff" &&
343 git apply -p0 --directory=adir --index <"$WORKDIR/cvsEdit3.diff" &&
344 git diff --exit-code v2
345 ) >"check_diff_apply.out" 2>&1
346'
347
348test_expect_success 'validate v1.2 diff saved during last cvswork2 edit' '
349 test $(grep Index: cvsEdit3-v1.2.diff | wc -l) = 9 &&
350 check_diff cvsEdit3-v1.2.diff v1.2 v2
351'
352
353test_expect_success 'validate v1.2 v1 diff saved during last cvswork2 edit' '
354 test $(grep Index: cvsEdit3-v1.2-v1.diff | wc -l) = 9 &&
355 check_diff cvsEdit3-v1.2-v1.diff v1.2 v1
356'
357
358test_expect_success 'cvs up [cvswork2]' '
359 ( cd cvswork2 && cvs -f up ) >cvs.log 2>&1 &&
360 check_start_tree cvswork2 &&
361 check_file cvswork2 textfile.c v2 &&
362 check_file cvswork2 adir/afile v2 &&
363 check_file cvswork2 adir/a2file v2 &&
364 check_file cvswork2 adir/bdir/bfile v2 &&
365 check_file cvswork2 adir/bdir/b4file v2 &&
366 check_end_full_tree cvswork2 v2
367'
368
369test_expect_success 'cvs up -r b2 [back to cvswork]' '
370 ( cd cvswork && cvs -f up -r b2 ) >cvs.log 2>&1 &&
371 check_start_tree cvswork &&
372 check_file cvswork textfile.c v2 &&
373 check_file cvswork adir/afile v2 &&
374 check_file cvswork adir/a2file v2 &&
375 check_file cvswork adir/bdir/bfile v2 &&
376 check_file cvswork adir/bdir/b4file v2 &&
377 check_end_full_tree cvswork v2
378'
379
380test_expect_success 'cvs up -r b1' '
381 ( cd cvswork && cvs -f up -r b1 ) >cvs.log 2>&1 &&
382 check_start_tree cvswork &&
383 check_file cvswork textfile.c v1.2 &&
384 check_file cvswork t3 v1.2 &&
385 check_file cvswork adir/afile v1.2 &&
386 check_file cvswork adir/a3file v1.2 &&
387 check_file cvswork adir/bdir/bfile v1.2 &&
388 check_file cvswork adir/bdir/b3file v1.2 &&
389 check_file cvswork cdir/cfile v1.2 &&
390 check_end_full_tree cvswork v1.2
391'
392
393test_expect_success 'cvs up -A' '
394 ( cd cvswork && cvs -f up -A ) >cvs.log 2>&1 &&
395 check_start_tree cvswork &&
396 check_file cvswork textfile.c v1 &&
397 check_file cvswork t2 v1 &&
398 check_file cvswork adir/afile v1 &&
399 check_file cvswork adir/a2file v1 &&
400 check_file cvswork adir/bdir/bfile v1 &&
401 check_file cvswork adir/bdir/b2file v1 &&
402 check_end_full_tree cvswork v1
403'
404
405test_expect_success 'cvs up (check CVS/Tag files)' '
406 ( cd cvswork && cvs -f up ) >cvs.log 2>&1 &&
407 check_start_tree cvswork &&
408 check_file cvswork textfile.c v1 &&
409 check_file cvswork t2 v1 &&
410 check_file cvswork adir/afile v1 &&
411 check_file cvswork adir/a2file v1 &&
412 check_file cvswork adir/bdir/bfile v1 &&
413 check_file cvswork adir/bdir/b2file v1 &&
414 check_end_full_tree cvswork v1
415'
416
417# This is not really legal CVS, but it seems to work anyway:
418test_expect_success 'cvs up -r heads/b1' '
419 ( cd cvswork && cvs -f up -r heads/b1 ) >cvs.log 2>&1 &&
420 check_start_tree cvswork &&
421 check_file cvswork textfile.c v1.2 &&
422 check_file cvswork t3 v1.2 &&
423 check_file cvswork adir/afile v1.2 &&
424 check_file cvswork adir/a3file v1.2 &&
425 check_file cvswork adir/bdir/bfile v1.2 &&
426 check_file cvswork adir/bdir/b3file v1.2 &&
427 check_file cvswork cdir/cfile v1.2 &&
428 check_end_full_tree cvswork v1.2
429'
430
431# But this should work even if CVS client checks -r more carefully:
432test_expect_success 'cvs up -r heads_-s-b2 (cvsserver escape mechanism)' '
433 ( cd cvswork && cvs -f up -r heads_-s-b2 ) >cvs.log 2>&1 &&
434 check_start_tree cvswork &&
435 check_file cvswork textfile.c v2 &&
436 check_file cvswork adir/afile v2 &&
437 check_file cvswork adir/a2file v2 &&
438 check_file cvswork adir/bdir/bfile v2 &&
439 check_file cvswork adir/bdir/b4file v2 &&
440 check_end_full_tree cvswork v2
441'
442
443v1hash=$(git rev-parse v1)
444test_expect_success 'cvs up -r $(git rev-parse v1)' '
445 test -n "$v1hash" &&
446 ( cd cvswork && cvs -f up -r "$v1hash" ) >cvs.log 2>&1 &&
447 check_start_tree cvswork &&
448 check_file cvswork textfile.c v1 &&
449 check_file cvswork t2 v1 &&
450 check_file cvswork adir/afile v1 &&
451 check_file cvswork adir/a2file v1 &&
452 check_file cvswork adir/bdir/bfile v1 &&
453 check_file cvswork adir/bdir/b2file v1 &&
454 check_end_full_tree cvswork v1
455'
456
457test_expect_success 'cvs diff -r v1 -u' '
458 ( cd cvswork && cvs -f diff -r v1 -u ) >cvsDiff.out 2>cvs.log &&
459 test_must_be_empty cvsDiff.out &&
460 test_must_be_empty cvs.log
461'
462
463test_expect_success 'cvs diff -N -r v2 -u' '
464 ( cd cvswork && ! cvs -f diff -N -r v2 -u ) >cvsDiff.out 2>cvs.log &&
465 test_must_be_empty cvs.log &&
466 test -s cvsDiff.out &&
467 check_diff cvsDiff.out v2 v1 >check_diff.out 2>&1
468'
469
470test_expect_success 'cvs diff -N -r v2 -r v1.2' '
471 ( cd cvswork && ! cvs -f diff -N -r v2 -r v1.2 -u ) >cvsDiff.out 2>cvs.log &&
472 test_must_be_empty cvs.log &&
473 test -s cvsDiff.out &&
474 check_diff cvsDiff.out v2 v1.2 >check_diff.out 2>&1
475'
476
477test_expect_success 'apply early [cvswork3] diff to b3' '
478 git clone -q . gitwork3 &&
479 (
480 cd gitwork3 &&
481 git checkout -b b3 v1 &&
482 git apply -p0 --index <"$WORKDIR/cvswork3edit.diff" &&
483 git commit -m "cvswork3 edits applied"
484 ) &&
485 git fetch gitwork3 b3:b3 &&
486 git tag v3 b3
487'
488
489test_expect_success 'check [cvswork3] diff' '
490 ( cd cvswork3 && ! cvs -f diff -N -u ) >"$WORKDIR/cvsDiff.out" 2>cvs.log &&
491 test_must_be_empty cvs.log &&
492 test -s cvsDiff.out &&
493 test $(grep Index: cvsDiff.out | wc -l) = 3 &&
494 test_cmp cvsDiff.out cvswork3edit.diff &&
495 check_diff cvsDiff.out v1 v3 >check_diff.out 2>&1
496'
497
498test_expect_success 'merge early [cvswork3] b3 with b1' '
499 ( cd gitwork3 && git merge -m "message" b1 ) &&
500 git fetch gitwork3 b3:b3 &&
501 git tag v3merged b3 &&
502 git push --tags gitcvs.git b3:b3
503'
504
505# This test would fail if cvsserver properly created a ".#afile"* file
506# for the merge.
507# TODO: Validate that the .# file was saved properly, and then
508# delete/ignore it when checking the tree.
509test_expect_success 'cvs up dirty [cvswork3]' '
510 (
511 cd cvswork3 &&
512 cvs -f up &&
513 ! cvs -f diff -N -u >"$WORKDIR/cvsDiff.out"
514 ) >cvs.log 2>&1 &&
515 test -s cvsDiff.out &&
516 test $(grep Index: cvsDiff.out | wc -l) = 2 &&
517 check_start_tree cvswork3 &&
518 check_file cvswork3 textfile.c v3merged &&
519 check_file cvswork3 t3 v3merged &&
520 check_file cvswork3 adir/afile v3merged &&
521 check_file cvswork3 adir/a3file v3merged &&
522 check_file cvswork3 adir/afile5 v3merged &&
523 check_file cvswork3 adir/bdir/bfile v3merged &&
524 check_file cvswork3 adir/bdir/b3file v3merged &&
525 check_file cvswork3 cdir/cfile v3merged &&
526 check_end_full_tree cvswork3 v3merged
527'
528
529# TODO: test cvs status
530
531test_expect_success 'cvs commit [cvswork3]' '
532 (
533 cd cvswork3 &&
534 cvs -f commit -m "dirty sandbox after auto-merge"
535 ) >cvs.log 2>&1 &&
536 check_start_tree cvswork3 &&
537 check_file cvswork3 textfile.c v3merged &&
538 check_file cvswork3 t3 v3merged &&
539 check_file cvswork3 adir/afile v3merged &&
540 check_file cvswork3 adir/a3file v3merged &&
541 check_file cvswork3 adir/afile5 v3merged &&
542 check_file cvswork3 adir/bdir/bfile v3merged &&
543 check_file cvswork3 adir/bdir/b3file v3merged &&
544 check_file cvswork3 cdir/cfile v3merged &&
545 check_end_full_tree cvswork3 v3merged &&
546 git fetch gitcvs.git b3:b4 &&
547 git tag v4.1 b4 &&
548 git diff --exit-code v4.1 v3merged >check_diff_apply.out 2>&1
549'
550
551test_done