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