Blob


1 #!/bin/sh
2 #
3 # Copyright (c) 2019 Stefan Sperling <stsp@openbsd.org>
4 #
5 # Permission to use, copy, modify, and distribute this software for any
6 # purpose with or without fee is hereby granted, provided that the above
7 # copyright notice and this permission notice appear in all copies.
8 #
9 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 . ./common.sh
19 test_cherrypick_basic() {
20 local testroot=`test_init cherrypick_basic`
22 got checkout $testroot/repo $testroot/wt > /dev/null
23 ret=$?
24 if [ $ret -ne 0 ]; then
25 test_done "$testroot" "$ret"
26 return 1
27 fi
29 (cd $testroot/repo && git checkout -q -b newbranch)
30 echo "modified delta on branch" > $testroot/repo/gamma/delta
31 git_commit $testroot/repo -m "committing to delta on newbranch"
33 echo "modified alpha on branch" > $testroot/repo/alpha
34 (cd $testroot/repo && git rm -q beta)
35 echo "new file on branch" > $testroot/repo/epsilon/new
36 (cd $testroot/repo && git add epsilon/new)
37 git_commit $testroot/repo -m "committing more changes on newbranch"
39 local branch_rev=`git_show_head $testroot/repo`
41 echo "modified new file on branch" > $testroot/repo/epsilon/new
42 git_commit $testroot/repo -m "committing more changes on newbranch"
43 local branch_rev2=`git_show_head $testroot/repo`
45 (cd $testroot/wt && got cherrypick $branch_rev > $testroot/stdout)
47 echo "G alpha" > $testroot/stdout.expected
48 echo "D beta" >> $testroot/stdout.expected
49 echo "A epsilon/new" >> $testroot/stdout.expected
50 echo "Merged commit $branch_rev" >> $testroot/stdout.expected
52 cmp -s $testroot/stdout.expected $testroot/stdout
53 ret=$?
54 if [ $ret -ne 0 ]; then
55 diff -u $testroot/stdout.expected $testroot/stdout
56 test_done "$testroot" "$ret"
57 return 1
58 fi
60 echo "modified alpha on branch" > $testroot/content.expected
61 cat $testroot/wt/alpha > $testroot/content
62 cmp -s $testroot/content.expected $testroot/content
63 ret=$?
64 if [ $ret -ne 0 ]; then
65 diff -u $testroot/content.expected $testroot/content
66 test_done "$testroot" "$ret"
67 return 1
68 fi
70 if [ -e $testroot/wt/beta ]; then
71 echo "removed file beta still exists on disk" >&2
72 test_done "$testroot" "1"
73 return 1
74 fi
76 echo "new file on branch" > $testroot/content.expected
77 cat $testroot/wt/epsilon/new > $testroot/content
78 cmp -s $testroot/content.expected $testroot/content
79 ret=$?
80 if [ $ret -ne 0 ]; then
81 diff -u $testroot/content.expected $testroot/content
82 test_done "$testroot" "$ret"
83 return 1
84 fi
86 echo 'M alpha' > $testroot/stdout.expected
87 echo 'D beta' >> $testroot/stdout.expected
88 echo 'A epsilon/new' >> $testroot/stdout.expected
90 (cd $testroot/wt && got status > $testroot/stdout)
92 cmp -s $testroot/stdout.expected $testroot/stdout
93 ret=$?
94 if [ $ret -ne 0 ]; then
95 diff -u $testroot/stdout.expected $testroot/stdout
96 test_done "$testroot" "$ret"
97 return 1
98 fi
100 (cd $testroot/wt && got cherrypick $branch_rev2 > $testroot/stdout)
102 echo "G epsilon/new" > $testroot/stdout.expected
103 echo "Merged commit $branch_rev2" >> $testroot/stdout.expected
105 cmp -s $testroot/stdout.expected $testroot/stdout
106 ret=$?
107 if [ $ret -ne 0 ]; then
108 diff -u $testroot/stdout.expected $testroot/stdout
109 test_done "$testroot" "$ret"
110 return 1
111 fi
113 echo 'M alpha' > $testroot/stdout.expected
114 echo 'D beta' >> $testroot/stdout.expected
115 echo 'A epsilon/new' >> $testroot/stdout.expected
117 (cd $testroot/wt && got status > $testroot/stdout)
119 cmp -s $testroot/stdout.expected $testroot/stdout
120 ret=$?
121 if [ $ret -ne 0 ]; then
122 diff -u $testroot/stdout.expected $testroot/stdout
123 fi
124 test_done "$testroot" "$ret"
127 test_cherrypick_root_commit() {
128 local testroot=`test_init cherrypick_root_commit`
130 got checkout $testroot/repo $testroot/wt > /dev/null
131 ret=$?
132 if [ $ret -ne 0 ]; then
133 test_done "$testroot" "$ret"
134 return 1
135 fi
137 (cd $testroot/repo && git checkout -q -b newbranch)
138 (cd $testroot/repo && git rm -q alpha)
139 (cd $testroot/repo && git rm -q beta)
140 (cd $testroot/repo && git rm -q epsilon/zeta)
141 (cd $testroot/repo && git rm -q gamma/delta)
142 mkdir -p $testroot/repo/epsilon
143 echo "new file on branch" > $testroot/repo/epsilon/new
144 (cd $testroot/repo && git add epsilon/new)
145 git_commit $testroot/repo -m "committing on newbranch"
147 echo "modified new file on branch" >> $testroot/repo/epsilon/new
148 git_commit $testroot/repo -m "committing on newbranch again"
150 tree=`git_show_tree $testroot/repo`
151 root_commit=`git_commit_tree $testroot/repo "new root commit" $tree`
153 (cd $testroot/wt && got cherrypick $root_commit > $testroot/stdout)
155 echo "A epsilon/new" > $testroot/stdout.expected
156 echo "Merged commit $root_commit" >> $testroot/stdout.expected
158 cmp -s $testroot/stdout.expected $testroot/stdout
159 ret=$?
160 if [ $ret -ne 0 ]; then
161 diff -u $testroot/stdout.expected $testroot/stdout
162 test_done "$testroot" "$ret"
163 return 1
164 fi
166 echo "new file on branch" > $testroot/content.expected
167 echo "modified new file on branch" >> $testroot/content.expected
168 cat $testroot/wt/epsilon/new > $testroot/content
169 cmp -s $testroot/content.expected $testroot/content
170 ret=$?
171 if [ $ret -ne 0 ]; then
172 diff -u $testroot/content.expected $testroot/content
173 test_done "$testroot" "$ret"
174 return 1
175 fi
177 echo 'A epsilon/new' > $testroot/stdout.expected
179 (cd $testroot/wt && got status > $testroot/stdout)
181 cmp -s $testroot/stdout.expected $testroot/stdout
182 ret=$?
183 if [ $ret -ne 0 ]; then
184 diff -u $testroot/stdout.expected $testroot/stdout
185 fi
186 test_done "$testroot" "$ret"
189 test_cherrypick_into_work_tree_with_conflicts() {
190 local testroot=`test_init cherrypick_into_work_tree_with_conflicts`
192 got checkout $testroot/repo $testroot/wt > /dev/null
193 ret=$?
194 if [ $ret -ne 0 ]; then
195 test_done "$testroot" "$ret"
196 return 1
197 fi
199 (cd $testroot/repo && git checkout -q -b newbranch)
200 echo "modified delta on branch" > $testroot/repo/gamma/delta
201 git_commit $testroot/repo -m "committing to delta on newbranch"
203 echo "modified alpha on branch" > $testroot/repo/alpha
204 (cd $testroot/repo && git rm -q beta)
205 echo "new file on branch" > $testroot/repo/epsilon/new
206 (cd $testroot/repo && git add epsilon/new)
207 git_commit $testroot/repo -m "committing more changes on newbranch"
209 local branch_rev=`git_show_head $testroot/repo`
211 # fake a merge conflict
212 echo '<<<<<<<' > $testroot/wt/alpha
213 echo 'alpha' >> $testroot/wt/alpha
214 echo '=======' >> $testroot/wt/alpha
215 echo 'alpha, too' >> $testroot/wt/alpha
216 echo '>>>>>>>' >> $testroot/wt/alpha
217 cp $testroot/wt/alpha $testroot/content.expected
219 echo "C alpha" > $testroot/stdout.expected
220 (cd $testroot/wt && got status > $testroot/stdout)
221 cmp -s $testroot/stdout.expected $testroot/stdout
222 ret=$?
223 if [ $ret -ne 0 ]; then
224 diff -u $testroot/stdout.expected $testroot/stdout
225 test_done "$testroot" "$ret"
226 return 1
227 fi
229 (cd $testroot/wt && got cherrypick $branch_rev \
230 > $testroot/stdout 2> $testroot/stderr)
231 ret=$?
232 if [ $ret -eq 0 ]; then
233 echo "cherrypick succeeded unexpectedly" >&2
234 test_done "$testroot" "1"
235 return 1
236 fi
238 echo -n > $testroot/stdout.expected
239 echo -n "got: work tree contains conflicted files; " \
240 > $testroot/stderr.expected
241 echo "these conflicts must be resolved first" \
242 >> $testroot/stderr.expected
244 cmp -s $testroot/stdout.expected $testroot/stdout
245 ret=$?
246 if [ $ret -ne 0 ]; then
247 diff -u $testroot/stdout.expected $testroot/stdout
248 test_done "$testroot" "$ret"
249 return 1
250 fi
252 cmp -s $testroot/stderr.expected $testroot/stderr
253 ret=$?
254 if [ $ret -ne 0 ]; then
255 diff -u $testroot/stderr.expected $testroot/stderr
256 test_done "$testroot" "$ret"
257 return 1
258 fi
260 cmp -s $testroot/content.expected $testroot/wt/alpha
261 ret=$?
262 if [ $ret -ne 0 ]; then
263 diff -u $testroot/content.expected $testroot/wt/alpha
264 fi
265 test_done "$testroot" "$ret"
268 test_cherrypick_into_work_tree_with_mixed_commits() {
269 local testroot=`test_init cherrypick_into_work_tree_with_mixed_commits`
270 local first_rev=`git_show_head $testroot/repo`
272 echo "modified alpha" > $testroot/repo/alpha
273 git_commit $testroot/repo -m "committing to alpha"
274 local second_rev=`git_show_head $testroot/repo`
276 got checkout $testroot/repo $testroot/wt > /dev/null
277 ret=$?
278 if [ $ret -ne 0 ]; then
279 test_done "$testroot" "$ret"
280 return 1
281 fi
283 (cd $testroot/repo && git checkout -q -b newbranch)
284 echo "modified delta on branch" > $testroot/repo/gamma/delta
285 git_commit $testroot/repo -m "committing to delta on newbranch"
287 (cd $testroot/repo && git rm -q beta)
288 echo "new file on branch" > $testroot/repo/epsilon/new
289 (cd $testroot/repo && git add epsilon/new)
290 git_commit $testroot/repo -m "committing more changes on newbranch"
292 local branch_rev=`git_show_head $testroot/repo`
294 (cd $testroot/wt && got update -c $first_rev alpha >/dev/null)
296 (cd $testroot/wt && got cherrypick $branch_rev \
297 > $testroot/stdout 2> $testroot/stderr)
298 ret=$?
299 if [ $ret -eq 0 ]; then
300 echo "cherrypick succeeded unexpectedly" >&2
301 test_done "$testroot" "1"
302 return 1
303 fi
305 echo -n > $testroot/stdout.expected
306 echo -n "got: work tree contains files from multiple base commits; " \
307 > $testroot/stderr.expected
308 echo "the entire work tree must be updated first" \
309 >> $testroot/stderr.expected
311 cmp -s $testroot/stdout.expected $testroot/stdout
312 ret=$?
313 if [ $ret -ne 0 ]; then
314 diff -u $testroot/stdout.expected $testroot/stdout
315 test_done "$testroot" "$ret"
316 return 1
317 fi
319 cmp -s $testroot/stderr.expected $testroot/stderr
320 ret=$?
321 if [ $ret -ne 0 ]; then
322 diff -u $testroot/stderr.expected $testroot/stderr
323 fi
324 test_done "$testroot" "$ret"
328 test_cherrypick_modified_submodule() {
329 local testroot=`test_init cherrypick_modified_submodules`
331 make_single_file_repo $testroot/repo2 foo
333 (cd $testroot/repo && git -c protocol.file.allow=always \
334 submodule -q add ../repo2)
335 (cd $testroot/repo && git commit -q -m 'adding submodule')
337 got checkout $testroot/repo $testroot/wt > /dev/null
339 echo "modified foo" > $testroot/repo2/foo
340 (cd $testroot/repo2 && git commit -q -a -m 'modified a submodule')
342 (cd $testroot/repo && git checkout -q -b newbranch)
343 # Update the repo/repo2 submodule link on newbranch
344 (cd $testroot/repo && git -C repo2 pull -q)
345 (cd $testroot/repo && git add repo2)
346 git_commit $testroot/repo -m "modified submodule link"
347 local commit_id=`git_show_head $testroot/repo`
349 # This cherrypick is a no-op because Got's file index
350 # does not track submodules.
351 (cd $testroot/wt && got cherrypick $commit_id > $testroot/stdout)
353 echo -n > $testroot/stdout.expected
354 cmp -s $testroot/stdout.expected $testroot/stdout
355 ret=$?
356 if [ $ret -ne 0 ]; then
357 diff -u $testroot/stdout.expected $testroot/stdout
358 fi
359 test_done "$testroot" "$ret"
362 test_cherrypick_added_submodule() {
363 local testroot=`test_init cherrypick_added_submodules`
365 got checkout $testroot/repo $testroot/wt > /dev/null
367 make_single_file_repo $testroot/repo2 foo
369 # Add the repo/repo2 submodule on newbranch
370 (cd $testroot/repo && git checkout -q -b newbranch)
371 (cd $testroot/repo && git -c protocol.file.allow=always \
372 submodule -q add ../repo2)
373 (cd $testroot/repo && git commit -q -m 'adding submodule')
374 local commit_id=`git_show_head $testroot/repo`
376 (cd $testroot/wt && got cherrypick $commit_id > $testroot/stdout)
378 echo "A .gitmodules" > $testroot/stdout.expected
379 echo "Merged commit $commit_id" >> $testroot/stdout.expected
380 cmp -s $testroot/stdout.expected $testroot/stdout
381 ret=$?
382 if [ $ret -ne 0 ]; then
383 diff -u $testroot/stdout.expected $testroot/stdout
384 fi
385 test_done "$testroot" "$ret"
388 test_cherrypick_conflict_wt_file_vs_repo_submodule() {
389 local testroot=`test_init cherrypick_conflict_wt_file_vs_repo_submodule`
391 got checkout $testroot/repo $testroot/wt > /dev/null
393 # Add a file which will clash with the submodule
394 echo "This is a file called repo2" > $testroot/wt/repo2
395 (cd $testroot/wt && got add repo2 > /dev/null)
396 (cd $testroot/wt && got commit -m 'add file repo2' > /dev/null)
397 ret=$?
398 if [ $ret -ne 0 ]; then
399 echo "commit failed unexpectedly" >&2
400 test_done "$testroot" "1"
401 return 1
402 fi
404 make_single_file_repo $testroot/repo2 foo
406 # Add the repo/repo2 submodule on newbranch
407 (cd $testroot/repo && git checkout -q -b newbranch)
408 (cd $testroot/repo && git -c protocol.file.allow=always \
409 submodule -q add ../repo2)
410 (cd $testroot/repo && git commit -q -m 'adding submodule')
411 local commit_id=`git_show_head $testroot/repo`
413 # Modify the clashing file such that any modifications brought
414 # in by 'got cherrypick' would require a merge.
415 echo "This file was changed" > $testroot/wt/repo2
417 (cd $testroot/wt && got update >/dev/null)
418 (cd $testroot/wt && got cherrypick $commit_id > $testroot/stdout)
420 echo "A .gitmodules" > $testroot/stdout.expected
421 echo "Merged commit $commit_id" >> $testroot/stdout.expected
422 cmp -s $testroot/stdout.expected $testroot/stdout
423 ret=$?
424 if [ $ret -ne 0 ]; then
425 diff -u $testroot/stdout.expected $testroot/stdout
426 test_done "$testroot" "$ret"
427 return 1
428 fi
430 (cd $testroot/wt && got status > $testroot/stdout)
432 echo "A .gitmodules" > $testroot/stdout.expected
433 echo "M repo2" >> $testroot/stdout.expected
434 cmp -s $testroot/stdout.expected $testroot/stdout
435 ret=$?
436 if [ $ret -ne 0 ]; then
437 diff -u $testroot/stdout.expected $testroot/stdout
438 fi
439 test_done "$testroot" "$ret"
442 test_cherrypick_modified_symlinks() {
443 local testroot=`test_init cherrypick_modified_symlinks`
445 (cd $testroot/repo && ln -s alpha alpha.link)
446 (cd $testroot/repo && ln -s epsilon epsilon.link)
447 (cd $testroot/repo && ln -s /etc/passwd passwd.link)
448 (cd $testroot/repo && ln -s ../beta epsilon/beta.link)
449 (cd $testroot/repo && ln -s nonexistent nonexistent.link)
450 (cd $testroot/repo && git add .)
451 git_commit $testroot/repo -m "add symlinks"
452 local commit_id1=`git_show_head $testroot/repo`
454 got tree -r $testroot/repo -R -c $commit_id1 \
455 > $testroot/stdout
456 cat > $testroot/stdout.expected <<EOF
457 alpha
458 alpha.link@ -> alpha
459 beta
460 epsilon/
461 epsilon/beta.link@ -> ../beta
462 epsilon/zeta
463 epsilon.link@ -> epsilon
464 gamma/
465 gamma/delta
466 nonexistent.link@ -> nonexistent
467 passwd.link@ -> /etc/passwd
468 EOF
469 cmp -s $testroot/stdout.expected $testroot/stdout
470 ret=$?
471 if [ $ret -ne 0 ]; then
472 diff -u $testroot/stdout.expected $testroot/stdout
473 test_done "$testroot" "$ret"
474 return 1
475 fi
477 got branch -r $testroot/repo foo
479 got checkout -b foo $testroot/repo $testroot/wt > /dev/null
481 (cd $testroot/repo && ln -sf beta alpha.link)
482 (cd $testroot/repo && rm epsilon.link && ln -s gamma epsilon.link)
483 (cd $testroot/repo && ln -sf ../gamma/delta epsilon/beta.link)
484 (cd $testroot/repo && ln -sf .got/foo $testroot/repo/dotgotfoo.link)
485 (cd $testroot/repo && git rm -q nonexistent.link)
486 (cd $testroot/repo && ln -sf epsilon/zeta zeta.link)
487 (cd $testroot/repo && git add .)
488 git_commit $testroot/repo -m "change symlinks"
489 local commit_id2=`git_show_head $testroot/repo`
491 (cd $testroot/wt && got cherrypick $commit_id2 > $testroot/stdout)
493 echo "G alpha.link" > $testroot/stdout.expected
494 echo "G epsilon/beta.link" >> $testroot/stdout.expected
495 echo "A dotgotfoo.link" >> $testroot/stdout.expected
496 echo "G epsilon.link" >> $testroot/stdout.expected
497 echo "D nonexistent.link" >> $testroot/stdout.expected
498 echo "A zeta.link" >> $testroot/stdout.expected
499 echo "Merged commit $commit_id2" >> $testroot/stdout.expected
500 cmp -s $testroot/stdout.expected $testroot/stdout
501 ret=$?
502 if [ $ret -ne 0 ]; then
503 diff -u $testroot/stdout.expected $testroot/stdout
504 test_done "$testroot" "$ret"
505 return 1
506 fi
508 if ! [ -h $testroot/wt/alpha.link ]; then
509 echo "alpha.link is not a symlink"
510 test_done "$testroot" "1"
511 return 1
512 fi
514 readlink $testroot/wt/alpha.link > $testroot/stdout
515 echo "beta" > $testroot/stdout.expected
516 cmp -s $testroot/stdout.expected $testroot/stdout
517 ret=$?
518 if [ $ret -ne 0 ]; then
519 diff -u $testroot/stdout.expected $testroot/stdout
520 test_done "$testroot" "$ret"
521 return 1
522 fi
524 if ! [ -h $testroot/wt/dotgotfoo.link ]; then
525 echo "dotgotfoo.link is not a symlink"
526 test_done "$testroot" "1"
527 return 1
528 fi
530 readlink $testroot/wt/dotgotfoo.link > $testroot/stdout
531 echo ".got/foo" > $testroot/stdout.expected
532 cmp -s $testroot/stdout.expected $testroot/stdout
533 ret=$?
534 if [ $ret -ne 0 ]; then
535 diff -u $testroot/stdout.expected $testroot/stdout
536 test_done "$testroot" "$ret"
537 return 1
538 fi
540 if ! [ -h $testroot/wt/epsilon.link ]; then
541 echo "epsilon.link is not a symlink"
542 test_done "$testroot" "1"
543 return 1
544 fi
546 readlink $testroot/wt/epsilon.link > $testroot/stdout
547 echo "gamma" > $testroot/stdout.expected
548 cmp -s $testroot/stdout.expected $testroot/stdout
549 ret=$?
550 if [ $ret -ne 0 ]; then
551 diff -u $testroot/stdout.expected $testroot/stdout
552 test_done "$testroot" "$ret"
553 return 1
554 fi
556 if [ -h $testroot/wt/passwd.link ]; then
557 echo -n "passwd.link symlink points outside of work tree: " >&2
558 readlink $testroot/wt/passwd.link >&2
559 test_done "$testroot" "1"
560 return 1
561 fi
563 echo -n "/etc/passwd" > $testroot/content.expected
564 cp $testroot/wt/passwd.link $testroot/content
566 cmp -s $testroot/content.expected $testroot/content
567 ret=$?
568 if [ $ret -ne 0 ]; then
569 diff -u $testroot/content.expected $testroot/content
570 test_done "$testroot" "$ret"
571 return 1
572 fi
574 readlink $testroot/wt/epsilon/beta.link > $testroot/stdout
575 echo "../gamma/delta" > $testroot/stdout.expected
576 cmp -s $testroot/stdout.expected $testroot/stdout
577 ret=$?
578 if [ $ret -ne 0 ]; then
579 diff -u $testroot/stdout.expected $testroot/stdout
580 test_done "$testroot" "$ret"
581 return 1
582 fi
584 if [ -h $testroot/wt/nonexistent.link ]; then
585 echo -n "nonexistent.link still exists on disk: " >&2
586 readlink $testroot/wt/nonexistent.link >&2
587 test_done "$testroot" "1"
588 return 1
589 fi
591 (cd $testroot/wt && got commit -m 'commit cherrypick result' \
592 > /dev/null 2>$testroot/stderr)
593 ret=$?
594 if [ $ret -eq 0 ]; then
595 echo "got commit succeeded unexpectedly" >&2
596 test_done "$testroot" "1"
597 return 1
598 fi
599 echo -n "got: $testroot/wt/dotgotfoo.link: symbolic link points " \
600 > $testroot/stderr.expected
601 echo "outside of paths under version control" \
602 >> $testroot/stderr.expected
603 cmp -s $testroot/stderr.expected $testroot/stderr
604 ret=$?
605 if [ $ret -ne 0 ]; then
606 diff -u $testroot/stderr.expected $testroot/stderr
607 test_done "$testroot" "$ret"
608 return 1
609 fi
611 (cd $testroot/wt && got commit -S -m 'commit cherrypick result' \
612 > /dev/null)
613 ret=$?
614 if [ $ret -ne 0 ]; then
615 echo "got commit failed unexpectedly" >&2
616 test_done "$testroot" "$ret"
617 return 1
618 fi
619 local commit_id2=`git_show_head $testroot/repo`
621 got tree -r $testroot/repo -R -c $commit_id2 \
622 > $testroot/stdout
623 cat > $testroot/stdout.expected <<EOF
624 alpha
625 alpha.link@ -> beta
626 beta
627 dotgotfoo.link@ -> .got/foo
628 epsilon/
629 epsilon/beta.link@ -> ../gamma/delta
630 epsilon/zeta
631 epsilon.link@ -> gamma
632 gamma/
633 gamma/delta
634 passwd.link@ -> /etc/passwd
635 zeta.link@ -> epsilon/zeta
636 EOF
637 cmp -s $testroot/stdout.expected $testroot/stdout
638 ret=$?
639 if [ $ret -ne 0 ]; then
640 diff -u $testroot/stdout.expected $testroot/stdout
641 fi
642 test_done "$testroot" "$ret"
645 test_cherrypick_symlink_conflicts() {
646 local testroot=`test_init cherrypick_symlink_conflicts`
648 (cd $testroot/repo && ln -s alpha alpha.link)
649 (cd $testroot/repo && ln -s epsilon epsilon.link)
650 (cd $testroot/repo && ln -s /etc/passwd passwd.link)
651 (cd $testroot/repo && ln -s ../beta epsilon/beta.link)
652 (cd $testroot/repo && ln -s nonexistent nonexistent.link)
653 (cd $testroot/repo && ln -sf epsilon/zeta zeta.link)
654 (cd $testroot/repo && git add .)
655 git_commit $testroot/repo -m "add symlinks"
656 local commit_id1=`git_show_head $testroot/repo`
658 (cd $testroot/repo && ln -sf beta alpha.link)
659 (cd $testroot/repo && ln -sf beta boo.link)
660 (cd $testroot/repo && rm epsilon.link && ln -s gamma epsilon.link)
661 (cd $testroot/repo && ln -sf ../gamma/delta epsilon/beta.link)
662 echo 'this is regular file foo' > $testroot/repo/dotgotfoo.link
663 (cd $testroot/repo && ln -sf .got/bar dotgotbar.link)
664 (cd $testroot/repo && git rm -q nonexistent.link)
665 (cd $testroot/repo && ln -sf gamma/delta zeta.link)
666 (cd $testroot/repo && ln -sf alpha new.link)
667 (cd $testroot/repo && git add .)
668 git_commit $testroot/repo -m "change symlinks"
669 local commit_id2=`git_show_head $testroot/repo`
671 got branch -r $testroot/repo -c $commit_id1 foo
672 got checkout -b foo $testroot/repo $testroot/wt > /dev/null
674 # modified symlink to file A vs modified symlink to file B
675 (cd $testroot/wt && ln -sf gamma/delta alpha.link)
676 # modified symlink to dir A vs modified symlink to file B
677 (cd $testroot/wt && rm epsilon.link && ln -s beta epsilon.link)
678 # modeified symlink to file A vs modified symlink to dir B
679 (cd $testroot/wt && rm epsilon/beta.link && ln -s ../gamma \
680 epsilon/beta.link)
681 # added regular file A vs added bad symlink to file A
682 (cd $testroot/wt && ln -sf .got/foo dotgotfoo.link)
683 (cd $testroot/wt && got add dotgotfoo.link > /dev/null)
684 # added bad symlink to file A vs added regular file A
685 echo 'this is regular file bar' > $testroot/wt/dotgotbar.link
686 (cd $testroot/wt && got add dotgotbar.link > /dev/null)
687 # added symlink to file A vs unversioned file A
688 echo 'this is unversioned file boo' > $testroot/wt/boo.link
689 # removed symlink to non-existent file A vs modified symlink
690 # to nonexistent file B
691 (cd $testroot/wt && ln -sf nonexistent2 nonexistent.link)
692 # modified symlink to file A vs removed symlink to file A
693 (cd $testroot/wt && got rm zeta.link > /dev/null)
694 # added symlink to file A vs added symlink to file B
695 (cd $testroot/wt && ln -sf beta new.link)
696 (cd $testroot/wt && got add new.link > /dev/null)
697 (cd $testroot/wt && got commit -S -m "change symlinks on foo" \
698 > /dev/null)
700 (cd $testroot/wt && got update >/dev/null)
701 (cd $testroot/wt && got cherrypick $commit_id2 > $testroot/stdout)
703 echo -n > $testroot/stdout.expected
704 echo "C alpha.link" >> $testroot/stdout.expected
705 echo "C epsilon/beta.link" >> $testroot/stdout.expected
706 echo "? boo.link" >> $testroot/stdout.expected
707 echo "C epsilon.link" >> $testroot/stdout.expected
708 echo "C dotgotbar.link" >> $testroot/stdout.expected
709 echo "C dotgotfoo.link" >> $testroot/stdout.expected
710 echo "D nonexistent.link" >> $testroot/stdout.expected
711 echo "! zeta.link" >> $testroot/stdout.expected
712 echo "C new.link" >> $testroot/stdout.expected
713 echo "Merged commit $commit_id2" >> $testroot/stdout.expected
714 echo "Files with new merge conflicts: 6" >> $testroot/stdout.expected
715 echo -n "Files which had incoming changes but could not be found " \
716 >> $testroot/stdout.expected
717 echo "in the work tree: 1" >> $testroot/stdout.expected
718 echo -n "Files not merged because an unversioned file was found in " \
719 >> $testroot/stdout.expected
720 echo "the work tree: 1" >> $testroot/stdout.expected
721 cmp -s $testroot/stdout.expected $testroot/stdout
722 ret=$?
723 if [ $ret -ne 0 ]; then
724 diff -u $testroot/stdout.expected $testroot/stdout
725 test_done "$testroot" "$ret"
726 return 1
727 fi
729 if [ -h $testroot/wt/alpha.link ]; then
730 echo "alpha.link is a symlink"
731 test_done "$testroot" "1"
732 return 1
733 fi
735 echo "<<<<<<< merged change: commit $commit_id2" \
736 > $testroot/content.expected
737 echo "beta" >> $testroot/content.expected
738 echo "3-way merge base: commit $commit_id1" \
739 >> $testroot/content.expected
740 echo "alpha" >> $testroot/content.expected
741 echo "=======" >> $testroot/content.expected
742 echo "gamma/delta" >> $testroot/content.expected
743 echo '>>>>>>>' >> $testroot/content.expected
744 echo -n "" >> $testroot/content.expected
746 cp $testroot/wt/alpha.link $testroot/content
747 cmp -s $testroot/content.expected $testroot/content
748 ret=$?
749 if [ $ret -ne 0 ]; then
750 diff -u $testroot/content.expected $testroot/content
751 test_done "$testroot" "$ret"
752 return 1
753 fi
755 if [ -h $testroot/wt/boo.link ]; then
756 echo "boo.link is a symlink"
757 test_done "$testroot" "1"
758 return 1
759 fi
761 echo "this is unversioned file boo" > $testroot/content.expected
762 cp $testroot/wt/boo.link $testroot/content
763 cmp -s $testroot/content.expected $testroot/content
764 ret=$?
765 if [ $ret -ne 0 ]; then
766 diff -u $testroot/content.expected $testroot/content
767 test_done "$testroot" "$ret"
768 return 1
769 fi
771 if [ -h $testroot/wt/epsilon.link ]; then
772 echo "epsilon.link is a symlink"
773 test_done "$testroot" "1"
774 return 1
775 fi
777 echo "<<<<<<< merged change: commit $commit_id2" \
778 > $testroot/content.expected
779 echo "gamma" >> $testroot/content.expected
780 echo "3-way merge base: commit $commit_id1" \
781 >> $testroot/content.expected
782 echo "epsilon" >> $testroot/content.expected
783 echo "=======" >> $testroot/content.expected
784 echo "beta" >> $testroot/content.expected
785 echo '>>>>>>>' >> $testroot/content.expected
786 echo -n "" >> $testroot/content.expected
788 cp $testroot/wt/epsilon.link $testroot/content
789 cmp -s $testroot/content.expected $testroot/content
790 ret=$?
791 if [ $ret -ne 0 ]; then
792 diff -u $testroot/content.expected $testroot/content
793 test_done "$testroot" "$ret"
794 return 1
795 fi
797 if [ -h $testroot/wt/passwd.link ]; then
798 echo -n "passwd.link symlink points outside of work tree: " >&2
799 readlink $testroot/wt/passwd.link >&2
800 test_done "$testroot" "1"
801 return 1
802 fi
804 echo -n "/etc/passwd" > $testroot/content.expected
805 cp $testroot/wt/passwd.link $testroot/content
807 cmp -s $testroot/content.expected $testroot/content
808 ret=$?
809 if [ $ret -ne 0 ]; then
810 diff -u $testroot/content.expected $testroot/content
811 test_done "$testroot" "$ret"
812 return 1
813 fi
815 if [ -h $testroot/wt/epsilon/beta.link ]; then
816 echo "epsilon/beta.link is a symlink"
817 test_done "$testroot" "1"
818 return 1
819 fi
821 echo "<<<<<<< merged change: commit $commit_id2" \
822 > $testroot/content.expected
823 echo "../gamma/delta" >> $testroot/content.expected
824 echo "3-way merge base: commit $commit_id1" \
825 >> $testroot/content.expected
826 echo "../beta" >> $testroot/content.expected
827 echo "=======" >> $testroot/content.expected
828 echo "../gamma" >> $testroot/content.expected
829 echo '>>>>>>>' >> $testroot/content.expected
830 echo -n "" >> $testroot/content.expected
832 cp $testroot/wt/epsilon/beta.link $testroot/content
833 cmp -s $testroot/content.expected $testroot/content
834 ret=$?
835 if [ $ret -ne 0 ]; then
836 diff -u $testroot/content.expected $testroot/content
837 test_done "$testroot" "$ret"
838 return 1
839 fi
841 if [ -h $testroot/wt/nonexistent.link ]; then
842 echo -n "nonexistent.link still exists on disk: " >&2
843 readlink $testroot/wt/nonexistent.link >&2
844 test_done "$testroot" "1"
845 return 1
846 fi
848 if [ -h $testroot/wt/dotgotfoo.link ]; then
849 echo "dotgotfoo.link is a symlink"
850 test_done "$testroot" "1"
851 return 1
852 fi
854 echo "<<<<<<< merged change: commit $commit_id2" \
855 > $testroot/content.expected
856 echo "this is regular file foo" >> $testroot/content.expected
857 echo "=======" >> $testroot/content.expected
858 echo -n ".got/foo" >> $testroot/content.expected
859 echo '>>>>>>>' >> $testroot/content.expected
860 cp $testroot/wt/dotgotfoo.link $testroot/content
861 cmp -s $testroot/content.expected $testroot/content
862 ret=$?
863 if [ $ret -ne 0 ]; then
864 diff -u $testroot/content.expected $testroot/content
865 test_done "$testroot" "$ret"
866 return 1
867 fi
869 if [ -h $testroot/wt/dotgotbar.link ]; then
870 echo "dotgotbar.link is a symlink"
871 test_done "$testroot" "1"
872 return 1
873 fi
874 echo "<<<<<<< merged change: commit $commit_id2" \
875 > $testroot/content.expected
876 echo -n ".got/bar" >> $testroot/content.expected
877 echo "=======" >> $testroot/content.expected
878 echo "this is regular file bar" >> $testroot/content.expected
879 echo '>>>>>>>' >> $testroot/content.expected
880 echo -n "" >> $testroot/content.expected
881 cp $testroot/wt/dotgotbar.link $testroot/content
882 cmp -s $testroot/content.expected $testroot/content
883 ret=$?
884 if [ $ret -ne 0 ]; then
885 diff -u $testroot/content.expected $testroot/content
886 test_done "$testroot" "$ret"
887 return 1
888 fi
890 if [ -h $testroot/wt/new.link ]; then
891 echo "new.link is a symlink"
892 test_done "$testroot" "1"
893 return 1
894 fi
896 echo "<<<<<<< merged change: commit $commit_id2" \
897 > $testroot/content.expected
898 echo "alpha" >> $testroot/content.expected
899 echo "=======" >> $testroot/content.expected
900 echo "beta" >> $testroot/content.expected
901 echo '>>>>>>>' >> $testroot/content.expected
902 echo -n "" >> $testroot/content.expected
904 cp $testroot/wt/new.link $testroot/content
905 cmp -s $testroot/content.expected $testroot/content
906 ret=$?
907 if [ $ret -ne 0 ]; then
908 diff -u $testroot/content.expected $testroot/content
909 test_done "$testroot" "$ret"
910 return 1
911 fi
913 echo "A dotgotfoo.link" > $testroot/stdout.expected
914 echo "M new.link" >> $testroot/stdout.expected
915 echo "D nonexistent.link" >> $testroot/stdout.expected
916 (cd $testroot/wt && got status > $testroot/stdout)
917 ret=$?
918 if [ $ret -ne 0 ]; then
919 diff -u $testroot/stdout.expected $testroot/stdout
920 test_done "$testroot" "$ret"
921 return 1
922 fi
924 test_done "$testroot" "0"
927 test_cherrypick_with_path_prefix_and_empty_tree() {
928 local testroot=`test_init cherrypick_with_path_prefix_and_empty_tree 1`
930 (cd $testroot/repo && git commit --allow-empty \
931 -m "initial empty commit" >/dev/null)
933 (cd $testroot/repo && got br bar >/dev/null)
935 mkdir -p $testroot/repo/epsilon
936 echo "file foo" > $testroot/repo/epsilon/foo
937 (cd $testroot/repo && git add .)
938 git_commit $testroot/repo -m "add file foo"
939 local commit_id=`git_show_head $testroot/repo`
941 got checkout -b bar $testroot/repo $testroot/wt > /dev/null
942 ret=$?
943 if [ $ret -ne 0 ]; then
944 echo "got checkout failed unexpectedly" >&2
945 test_done "$testroot" "$ret"
946 return 1
947 fi
949 mkdir -p $testroot/wt/epsilon
950 echo "new file" > $testroot/wt/epsilon/new
951 (cd $testroot/wt && got add epsilon/new >/dev/null)
952 (cd $testroot/wt && got commit -m "add file on branch bar" > /dev/null)
954 got checkout -b bar -p epsilon $testroot/repo $testroot/wt2 > /dev/null
955 ret=$?
956 if [ $ret -ne 0 ]; then
957 echo "got checkout failed unexpectedly" >&2
958 test_done "$testroot" "$ret"
959 return 1
960 fi
961 (cd $testroot/wt2 && got cherrypick $commit_id > $testroot/stdout)
963 echo "A foo" > $testroot/stdout.expected
964 echo "Merged commit $commit_id" >> $testroot/stdout.expected
966 cmp -s $testroot/stdout.expected $testroot/stdout
967 ret=$?
968 if [ $ret -ne 0 ]; then
969 diff -u $testroot/stdout.expected $testroot/stdout
970 fi
971 test_done "$testroot" "$ret"
974 test_cherrypick_conflict_no_eol() {
975 local testroot=`test_init cherrypick_conflict_no_eol 1`
976 local content_a="aaa\naaa\naaa\naaa\naaa\naaa\n"
977 local content_b="aaa\naaa\nbbb\naaa\naaa\naaa\naaa"
978 local content_c="aaa\naaa\nccc\naaa\naaa\naaa\naaa"
980 printf "$content_a" > $testroot/repo/a
981 (cd $testroot/repo && git add a)
982 git_commit $testroot/repo -m "initial commit"
984 (cd $testroot/repo && got branch newbranch)
986 printf "$content_b" > $testroot/repo/a
987 git_commit $testroot/repo -m "change bbb"
989 printf "$content_c" > $testroot/repo/a
990 git_commit $testroot/repo -m "change ccc"
991 local ccc_commit=`git_show_head $testroot/repo`
993 got checkout -b newbranch $testroot/repo $testroot/wt > /dev/null
994 ret=$?
995 if [ $ret -ne 0 ]; then
996 test_done "$testroot" "$ret"
997 return 1
998 fi
1000 (cd $testroot/wt && got cherrypick $ccc_commit > $testroot/stdout)
1002 echo "C a" > $testroot/stdout.expected
1003 echo "Merged commit $ccc_commit" >> $testroot/stdout.expected
1004 echo "Files with new merge conflicts: 1" >> $testroot/stdout.expected
1006 cmp -s $testroot/stdout.expected $testroot/stdout
1007 ret=$?
1008 if [ $ret -ne 0 ]; then
1009 diff -u $testroot/stdout.expected $testroot/stdout
1011 test_done "$testroot" "$ret"
1014 test_cherrypick_conflict_no_eol2() {
1015 local testroot=`test_init cherrypick_conflict_no_eol2 1`
1016 local content_a="aaa\naaa\naaa\naaa\naaa\naaa"
1017 local content_b="aaa\naaa\nbbb\naaa\naaa\naaa"
1018 local content_c="aaa\naaa\nbbb\naaa\naaa\naaa\n"
1020 printf "$content_a" > $testroot/repo/a
1021 (cd $testroot/repo && git add a)
1022 git_commit $testroot/repo -m "initial commit"
1024 (cd $testroot/repo && got branch newbranch)
1026 printf "$content_b" > $testroot/repo/a
1027 git_commit $testroot/repo -m "change bbb"
1029 printf "$content_c" > $testroot/repo/a
1030 git_commit $testroot/repo -m "change ccc"
1031 local ccc_commit=`git_show_head $testroot/repo`
1033 got checkout -b newbranch $testroot/repo $testroot/wt > /dev/null
1034 ret=$?
1035 if [ $ret -ne 0 ]; then
1036 test_done "$testroot" "$ret"
1037 return 1
1040 (cd $testroot/wt && got cherrypick $ccc_commit \
1041 > $testroot/stdout 2> $testroot/stderr)
1043 echo "C a" > $testroot/stdout.expected
1044 echo "Merged commit $ccc_commit" >> $testroot/stdout.expected
1045 echo "Files with new merge conflicts: 1" >> $testroot/stdout.expected
1047 cmp -s $testroot/stdout.expected $testroot/stdout
1048 ret=$?
1049 if [ $ret -ne 0 ]; then
1050 diff -u $testroot/stdout.expected $testroot/stdout
1052 test_done "$testroot" "$ret"
1055 test_cherrypick_unrelated_changes() {
1056 local testroot=`test_init cherrypick_unrelated_changes`
1058 # Sorry about the large HERE document but I have not found
1059 # a smaller reproduction recipe yet...
1060 cat > $testroot/repo/reference.c <<EOF
1061 const struct got_error *
1062 got_ref_alloc(struct got_reference **ref, const char *name,
1063 struct got_object_id *id)
1065 if (!is_valid_ref_name(name))
1066 return got_error_path(name, GOT_ERR_BAD_REF_NAME);
1068 return alloc_ref(ref, name, id, 0);
1071 static const struct got_error *
1072 parse_packed_ref_line(struct got_reference **ref, const char *abs_refname,
1073 const char *line)
1075 struct got_object_id id;
1076 const char *name;
1078 *ref = NULL;
1080 if (line[0] == '#' || line[0] == '^')
1081 return NULL;
1083 if (!got_parse_sha1_digest(id.sha1, line))
1084 return got_error(GOT_ERR_BAD_REF_DATA);
1086 if (abs_refname) {
1087 if (strcmp(line + SHA1_DIGEST_STRING_LENGTH, abs_refname) != 0)
1088 return NULL;
1089 name = abs_refname;
1090 } else
1091 name = line + SHA1_DIGEST_STRING_LENGTH;
1093 return alloc_ref(ref, name, &id, GOT_REF_IS_PACKED);
1096 static const struct got_error *
1097 open_packed_ref(struct got_reference **ref, FILE *f, const char **subdirs,
1098 int nsubdirs, const char *refname)
1100 const struct got_error *err = NULL;
1101 char *abs_refname;
1102 char *line = NULL;
1103 size_t linesize = 0;
1104 ssize_t linelen;
1105 int i, ref_is_absolute = (strncmp(refname, "refs/", 5) == 0);
1107 *ref = NULL;
1109 if (ref_is_absolute)
1110 abs_refname = (char *)refname;
1111 do {
1112 linelen = getline(&line, &linesize, f);
1113 if (linelen == -1) {
1114 if (feof(f))
1115 break;
1116 err = got_ferror(f, GOT_ERR_BAD_REF_DATA);
1117 break;
1119 if (linelen > 0 && line[linelen - 1] == '\n')
1120 line[linelen - 1] = '\0';
1121 for (i = 0; i < nsubdirs; i++) {
1122 if (!ref_is_absolute &&
1123 asprintf(&abs_refname, "refs/%s/%s", subdirs[i],
1124 refname) == -1)
1125 return got_error_from_errno("asprintf");
1126 err = parse_packed_ref_line(ref, abs_refname, line);
1127 if (!ref_is_absolute)
1128 free(abs_refname);
1129 if (err || *ref != NULL)
1130 break;
1132 if (err)
1133 break;
1134 } while (*ref == NULL);
1135 free(line);
1137 return err;
1140 static const struct got_error *
1141 open_ref(struct got_reference **ref, const char *path_refs, const char *subdir,
1142 const char *name, int lock)
1144 const struct got_error *err = NULL;
1145 char *path = NULL;
1146 char *absname = NULL;
1147 int ref_is_absolute = (strncmp(name, "refs/", 5) == 0);
1148 int ref_is_well_known = (subdir[0] == '\0' && is_well_known_ref(name));
1150 *ref = NULL;
1152 if (ref_is_absolute || ref_is_well_known) {
1153 if (asprintf(&path, "%s/%s", path_refs, name) == -1)
1154 return got_error_from_errno("asprintf");
1155 absname = (char *)name;
1156 } else {
1157 if (asprintf(&path, "%s/%s%s%s", path_refs, subdir,
1158 subdir[0] ? "/" : "", name) == -1)
1159 return got_error_from_errno("asprintf");
1161 if (asprintf(&absname, "refs/%s%s%s",
1162 subdir, subdir[0] ? "/" : "", name) == -1) {
1163 err = got_error_from_errno("asprintf");
1164 goto done;
1168 err = parse_ref_file(ref, name, absname, path, lock);
1169 done:
1170 if (!ref_is_absolute && !ref_is_well_known)
1171 free(absname);
1172 free(path);
1173 return err;
1176 const struct got_error *
1177 got_ref_open(struct got_reference **ref, struct got_repository *repo,
1178 const char *refname, int lock)
1180 const struct got_error *err = NULL;
1181 char *path_refs = NULL;
1182 const char *subdirs[] = {
1183 GOT_REF_HEADS, GOT_REF_TAGS, GOT_REF_REMOTES
1185 size_t i;
1186 int well_known = is_well_known_ref(refname);
1187 struct got_lockfile *lf = NULL;
1189 *ref = NULL;
1191 path_refs = get_refs_dir_path(repo, refname);
1192 if (path_refs == NULL) {
1193 err = got_error_from_errno2("get_refs_dir_path", refname);
1194 goto done;
1197 if (well_known) {
1198 err = open_ref(ref, path_refs, "", refname, lock);
1199 } else {
1200 char *packed_refs_path;
1201 FILE *f;
1203 /* Search on-disk refs before packed refs! */
1204 for (i = 0; i < nitems(subdirs); i++) {
1205 err = open_ref(ref, path_refs, subdirs[i], refname,
1206 lock);
1207 if ((err && err->code != GOT_ERR_NOT_REF) || *ref)
1208 goto done;
1211 packed_refs_path = got_repo_get_path_packed_refs(repo);
1212 if (packed_refs_path == NULL) {
1213 err = got_error_from_errno(
1214 "got_repo_get_path_packed_refs");
1215 goto done;
1218 if (lock) {
1219 err = got_lockfile_lock(&lf, packed_refs_path);
1220 if (err)
1221 goto done;
1223 f = fopen(packed_refs_path, "rb");
1224 free(packed_refs_path);
1225 if (f != NULL) {
1226 err = open_packed_ref(ref, f, subdirs, nitems(subdirs),
1227 refname);
1228 if (!err) {
1229 if (fclose(f) == EOF) {
1230 err = got_error_from_errno("fclose");
1231 got_ref_close(*ref);
1232 *ref = NULL;
1233 } else if (*ref)
1234 (*ref)->lf = lf;
1238 done:
1239 if (!err && *ref == NULL)
1240 err = got_error_not_ref(refname);
1241 if (err && lf)
1242 got_lockfile_unlock(lf);
1243 free(path_refs);
1244 return err;
1247 struct got_reference *
1248 got_ref_dup(struct got_reference *ref)
1250 struct got_reference *ret;
1252 ret = calloc(1, sizeof(*ret));
1253 if (ret == NULL)
1254 return NULL;
1256 ret->flags = ref->flags;
1257 if (ref->flags & GOT_REF_IS_SYMBOLIC) {
1258 ret->ref.symref.name = strdup(ref->ref.symref.name);
1259 if (ret->ref.symref.name == NULL) {
1260 free(ret);
1261 return NULL;
1263 ret->ref.symref.ref = strdup(ref->ref.symref.ref);
1264 if (ret->ref.symref.ref == NULL) {
1265 free(ret->ref.symref.name);
1266 free(ret);
1267 return NULL;
1269 } else {
1270 ret->ref.ref.name = strdup(ref->ref.ref.name);
1271 if (ret->ref.ref.name == NULL) {
1272 free(ret);
1273 return NULL;
1275 memcpy(ret->ref.ref.sha1, ref->ref.ref.sha1,
1276 sizeof(ret->ref.ref.sha1));
1279 return ret;
1282 const struct got_error *
1283 got_reflist_entry_dup(struct got_reflist_entry **newp,
1284 struct got_reflist_entry *re)
1286 const struct got_error *err = NULL;
1287 struct got_reflist_entry *new;
1289 *newp = NULL;
1291 new = malloc(sizeof(*new));
1292 if (new == NULL)
1293 return got_error_from_errno("malloc");
1295 new->ref = got_ref_dup(re->ref);
1296 if (new->ref == NULL) {
1297 err = got_error_from_errno("got_ref_dup");
1298 free(new);
1299 return err;
1302 *newp = new;
1303 return NULL;
1306 void
1307 got_ref_list_free(struct got_reflist_head *refs)
1309 struct got_reflist_entry *re;
1311 while ((re = TAILQ_FIRST(refs))) {
1312 TAILQ_REMOVE(refs, re, entry);
1313 free(re);
1316 EOF
1317 (cd $testroot/repo && git add reference.c)
1318 git_commit $testroot/repo -m "added reference.c file"
1319 local base_commit=`git_show_head $testroot/repo`
1321 got checkout $testroot/repo $testroot/wt > /dev/null
1322 ret=$?
1323 if [ $ret -ne 0 ]; then
1324 test_done "$testroot" "$ret"
1325 return 1
1328 (cd $testroot/repo && git checkout -q -b newbranch)
1329 ed -s $testroot/repo/reference.c <<EOF
1330 91a
1331 if (!is_valid_ref_name(name))
1332 return got_error_path(name, GOT_ERR_BAD_REF_NAME);
1337 EOF
1338 git_commit $testroot/repo -m "added lines on newbranch"
1339 local branch_rev1=`git_show_head $testroot/repo`
1341 ed -s $testroot/repo/reference.c <<EOF
1342 255a
1343 got_ref_close(re->ref);
1347 EOF
1348 git_commit $testroot/repo -m "more lines on newbranch"
1350 local branch_rev2=`git_show_head $testroot/repo`
1352 (cd $testroot/wt && got cherrypick $branch_rev2 > $testroot/stdout)
1354 echo "G reference.c" > $testroot/stdout.expected
1355 echo "Merged commit $branch_rev2" >> $testroot/stdout.expected
1357 cmp -s $testroot/stdout.expected $testroot/stdout
1358 ret=$?
1359 if [ $ret -ne 0 ]; then
1360 diff -u $testroot/stdout.expected $testroot/stdout
1361 test_done "$testroot" "$ret"
1362 return 1
1365 cat > $testroot/diff.expected <<EOF
1366 --- reference.c
1367 +++ reference.c
1368 @@ -250,6 +250,7 @@ got_ref_list_free(struct got_reflist_head *refs)
1370 while ((re = TAILQ_FIRST(refs))) {
1371 TAILQ_REMOVE(refs, re, entry);
1372 + got_ref_close(re->ref);
1373 free(re);
1376 EOF
1377 (cd $testroot/wt && got diff |
1378 egrep -v '^(diff|blob|file|commit|path)' > $testroot/diff)
1379 cmp -s $testroot/diff.expected $testroot/diff
1380 ret=$?
1381 if [ $ret -ne 0 ]; then
1382 diff -u $testroot/diff.expected $testroot/diff
1385 test_done "$testroot" "$ret"
1388 test_cherrypick_same_branch() {
1389 local testroot=`test_init cherrypick_same_branch`
1391 got checkout $testroot/repo $testroot/wt > /dev/null
1392 ret=$?
1393 if [ $ret -ne 0 ]; then
1394 test_done "$testroot" "$ret"
1395 return 1
1398 (cd $testroot/repo && git checkout -q -b newbranch)
1399 echo "modified delta on branch" > $testroot/repo/gamma/delta
1400 git_commit $testroot/repo -m "committing to delta on newbranch"
1402 echo "modified alpha on branch" > $testroot/repo/alpha
1403 (cd $testroot/repo && git rm -q beta)
1404 echo "new file on branch" > $testroot/repo/epsilon/new
1405 (cd $testroot/repo && git add epsilon/new)
1406 git_commit $testroot/repo -m "committing more changes on newbranch"
1408 local branch_rev=`git_show_head $testroot/repo`
1410 # picking a commit from the branch's own history does not make
1411 # sense but we should have test coverage for this case regardless
1412 (cd $testroot/wt && got up -b newbranch > /dev/null)
1413 (cd $testroot/wt && got cherrypick $branch_rev > $testroot/stdout)
1415 echo "G alpha" > $testroot/stdout.expected
1416 echo "! beta" >> $testroot/stdout.expected
1417 echo "G epsilon/new" >> $testroot/stdout.expected
1418 echo "Merged commit $branch_rev" >> $testroot/stdout.expected
1419 echo -n "Files which had incoming changes but could not be found " \
1420 >> $testroot/stdout.expected
1421 echo "in the work tree: 1" >> $testroot/stdout.expected
1423 cmp -s $testroot/stdout.expected $testroot/stdout
1424 ret=$?
1425 if [ $ret -ne 0 ]; then
1426 diff -u $testroot/stdout.expected $testroot/stdout
1428 test_done "$testroot" "$ret"
1431 test_cherrypick_dot_on_a_line_by_itself() {
1432 local testroot=`test_init cherrypick_dot_on_a_line_by_itself`
1434 got checkout $testroot/repo $testroot/wt > /dev/null
1435 ret=$?
1436 if [ $ret -ne 0 ]; then
1437 test_done "$testroot" "$ret"
1438 return 1
1441 (cd $testroot/repo && git checkout -q -b newbranch)
1442 printf "modified\n:delta\n.\non\n:branch\n" > $testroot/repo/gamma/delta
1443 git_commit $testroot/repo -m "committing to delta on newbranch"
1444 local branch_rev=`git_show_head $testroot/repo`
1446 (cd $testroot/wt && got cherrypick newbranch > $testroot/stdout)
1448 echo "G gamma/delta" >> $testroot/stdout.expected
1449 echo "Merged commit $branch_rev" >> $testroot/stdout.expected
1451 cmp -s $testroot/stdout.expected $testroot/stdout
1452 ret=$?
1453 if [ $ret -ne 0 ]; then
1454 diff -u $testroot/stdout.expected $testroot/stdout
1455 test_done "$testroot" "$ret"
1456 return 1
1459 printf "modified\n:delta\n.\non\n:branch\n" > $testroot/content.expected
1460 cat $testroot/wt/gamma/delta > $testroot/content
1461 cmp -s $testroot/content.expected $testroot/content
1462 ret=$?
1463 if [ $ret -ne 0 ]; then
1464 diff -u $testroot/content.expected $testroot/content
1466 test_done "$testroot" "$ret"
1469 test_cherrypick_binary_file() {
1470 local testroot=`test_init cherrypick_binary_file`
1471 local commit_id0=`git_show_head $testroot/repo`
1473 got checkout $testroot/repo $testroot/wt > /dev/null
1474 ret=$?
1475 if [ $ret -ne 0 ]; then
1476 test_done "$testroot" "$ret"
1477 return 1
1480 cp /bin/ls $testroot/wt/foo
1481 chmod 755 $testroot/wt/foo
1482 (cd $testroot/wt && got add foo >/dev/null)
1483 (cd $testroot/wt && got commit -m 'add binary file' > /dev/null)
1484 local commit_id1=`git_show_head $testroot/repo`
1486 cp /bin/cat $testroot/wt/foo
1487 chmod 755 $testroot/wt/foo
1488 (cd $testroot/wt && got commit -m 'change binary file' > /dev/null)
1489 local commit_id2=`git_show_head $testroot/repo`
1491 cp /bin/cp $testroot/wt/foo
1492 chmod 755 $testroot/wt/foo
1493 (cd $testroot/wt && got commit -m 'change binary file' > /dev/null)
1494 local commit_id3=`git_show_head $testroot/repo`
1496 (cd $testroot/wt && got rm foo >/dev/null)
1497 (cd $testroot/wt && got commit -m 'remove binary file' > /dev/null)
1498 local commit_id4=`git_show_head $testroot/repo`
1500 # backdate the work tree to make it usable for cherry-picking
1501 (cd $testroot/wt && got up -c $commit_id0 > /dev/null)
1503 # cherry-pick addition of a binary file
1504 (cd $testroot/wt && got cy $commit_id1 > $testroot/stdout)
1506 echo "A foo" > $testroot/stdout.expected
1507 echo "Merged commit $commit_id1" >> $testroot/stdout.expected
1509 cmp -s $testroot/stdout.expected $testroot/stdout
1510 ret=$?
1511 if [ $ret -ne 0 ]; then
1512 diff -u $testroot/stdout.expected $testroot/stdout
1513 test_done "$testroot" "$ret"
1514 return 1
1517 cp /bin/ls $testroot/content.expected
1518 chmod 755 $testroot/content.expected
1519 cp $testroot/wt/foo $testroot/content
1520 cmp -s $testroot/content.expected $testroot/content
1521 ret=$?
1522 if [ $ret -ne 0 ]; then
1523 diff -u $testroot/content.expected $testroot/content
1524 test_done "$testroot" "$ret"
1525 return 1
1528 # cherry-pick modification of a binary file
1529 (cd $testroot/wt && got cy $commit_id2 > $testroot/stdout)
1531 echo "G foo" > $testroot/stdout.expected
1532 echo "Merged commit $commit_id2" >> $testroot/stdout.expected
1534 cmp -s $testroot/stdout.expected $testroot/stdout
1535 ret=$?
1536 if [ $ret -ne 0 ]; then
1537 diff -u $testroot/stdout.expected $testroot/stdout
1538 test_done "$testroot" "$ret"
1539 return 1
1542 cp /bin/cat $testroot/content.expected
1543 chmod 755 $testroot/content.expected
1544 cp $testroot/wt/foo $testroot/content
1545 cmp -s $testroot/content.expected $testroot/content
1546 ret=$?
1547 if [ $ret -ne 0 ]; then
1548 diff -u $testroot/content.expected $testroot/content
1549 test_done "$testroot" "$ret"
1550 return 1
1553 # cherry-pick conflicting addition of a binary file
1554 (cd $testroot/wt && got cy $commit_id1 > $testroot/stdout)
1556 echo "C foo" > $testroot/stdout.expected
1557 echo "Merged commit $commit_id1" >> $testroot/stdout.expected
1558 echo "Files with new merge conflicts: 1" >> $testroot/stdout.expected
1560 cmp -s $testroot/stdout.expected $testroot/stdout
1561 ret=$?
1562 if [ $ret -ne 0 ]; then
1563 diff -u $testroot/stdout.expected $testroot/stdout
1564 test_done "$testroot" "$ret"
1565 return 1
1568 echo "Binary files differ and cannot be merged automatically:" \
1569 > $testroot/content.expected
1570 echo "<<<<<<< merged change: commit $commit_id1" \
1571 >> $testroot/content.expected
1572 echo -n "file " >> $testroot/content.expected
1573 ls $testroot/wt/foo-1-* >> $testroot/content.expected
1574 echo '=======' >> $testroot/content.expected
1575 echo -n "file " >> $testroot/content.expected
1576 ls $testroot/wt/foo-2-* >> $testroot/content.expected
1577 echo '>>>>>>>' >> $testroot/content.expected
1578 cp $testroot/wt/foo $testroot/content
1579 cmp -s $testroot/content.expected $testroot/content
1580 ret=$?
1581 if [ $ret -ne 0 ]; then
1582 diff -u $testroot/content.expected $testroot/content
1583 test_done "$testroot" "$ret"
1584 return 1
1587 # revert local changes to allow further testing
1588 (cd $testroot/wt && got revert -R . >/dev/null)
1590 (cd $testroot/wt && got status > $testroot/stdout)
1591 echo '? foo' > $testroot/stdout.expected
1592 echo -n '? ' >> $testroot/stdout.expected
1593 (cd $testroot/wt && ls foo-1-* >> $testroot/stdout.expected)
1594 echo -n '? ' >> $testroot/stdout.expected
1595 (cd $testroot/wt && ls foo-2-* >> $testroot/stdout.expected)
1596 cmp -s $testroot/stdout.expected $testroot/stdout
1597 ret=$?
1598 if [ $ret -ne 0 ]; then
1599 diff -u $testroot/stdout.expected $testroot/stdout
1600 test_done "$testroot" "$ret"
1601 return 1
1604 # tidy up
1605 rm $testroot/wt/foo $testroot/wt/foo-1-* $testroot/wt/foo-2-*
1606 (cd $testroot/wt && got up -c $commit_id1 > /dev/null)
1608 # cherry-pick conflicting modification of a binary file
1609 (cd $testroot/wt && got cy $commit_id3 > $testroot/stdout)
1611 echo "C foo" > $testroot/stdout.expected
1612 echo "Merged commit $commit_id3" >> $testroot/stdout.expected
1613 echo "Files with new merge conflicts: 1" >> $testroot/stdout.expected
1615 cmp -s $testroot/stdout.expected $testroot/stdout
1616 ret=$?
1617 if [ $ret -ne 0 ]; then
1618 diff -u $testroot/stdout.expected $testroot/stdout
1619 test_done "$testroot" "$ret"
1620 return 1
1623 echo "Binary files differ and cannot be merged automatically:" \
1624 > $testroot/content.expected
1625 echo '<<<<<<<' >> $testroot/content.expected
1626 echo -n "file " >> $testroot/content.expected
1627 ls $testroot/wt/foo-1-* >> $testroot/content.expected
1628 echo "||||||| 3-way merge base: commit $commit_id2" \
1629 >> $testroot/content.expected
1630 echo -n "file " >> $testroot/content.expected
1631 ls $testroot/wt/foo-orig-* >> $testroot/content.expected
1632 echo '=======' >> $testroot/content.expected
1633 echo -n "file " >> $testroot/content.expected
1634 ls $testroot/wt/foo-2-* >> $testroot/content.expected
1635 echo ">>>>>>> merged change: commit $commit_id3" \
1636 >> $testroot/content.expected
1637 cp $testroot/wt/foo $testroot/content
1638 cmp -s $testroot/content.expected $testroot/content
1639 ret=$?
1640 if [ $ret -ne 0 ]; then
1641 diff -u $testroot/content.expected $testroot/content
1642 test_done "$testroot" "$ret"
1643 return 1
1646 cp /bin/ls $testroot/content.expected
1647 chmod 755 $testroot/content.expected
1648 cat $testroot/wt/foo-1-* > $testroot/content
1649 cmp -s $testroot/content.expected $testroot/content
1650 ret=$?
1651 if [ $ret -ne 0 ]; then
1652 diff -u $testroot/content.expected $testroot/content
1653 test_done "$testroot" "$ret"
1654 return 1
1657 cp /bin/cp $testroot/content.expected
1658 chmod 755 $testroot/content.expected
1659 cat $testroot/wt/foo-2-* > $testroot/content
1660 cmp -s $testroot/content.expected $testroot/content
1661 ret=$?
1662 if [ $ret -ne 0 ]; then
1663 diff -u $testroot/content.expected $testroot/content
1664 test_done "$testroot" "$ret"
1665 return 1
1668 # revert local changes to allow further testing
1669 (cd $testroot/wt && got revert -R . > /dev/null)
1670 rm $testroot/wt/foo-1-*
1671 rm $testroot/wt/foo-2-*
1672 (cd $testroot/wt && got up -c $commit_id3 > /dev/null)
1674 # cherry-pick deletion of a binary file
1675 (cd $testroot/wt && got cy $commit_id4 > $testroot/stdout)
1677 echo "D foo" > $testroot/stdout.expected
1678 echo "Merged commit $commit_id4" >> $testroot/stdout.expected
1680 cmp -s $testroot/stdout.expected $testroot/stdout
1681 ret=$?
1682 if [ $ret -ne 0 ]; then
1683 diff -u $testroot/stdout.expected $testroot/stdout
1684 test_done "$testroot" "$ret"
1685 return 1
1688 if [ -e $testroot/wt/foo ]; then
1689 echo "removed file foo still exists on disk" >&2
1690 test_done "$testroot" "1"
1691 return 1
1693 test_done "$testroot" "0"
1696 test_cherrypick_umask() {
1697 local testroot=`test_init cherrypick_umask`
1699 got checkout $testroot/repo $testroot/wt >/dev/null
1700 ret=$?
1701 if [ $ret -ne 0 ]; then
1702 test_done "$testroot" $ret
1703 return 1
1706 (cd "$testroot/wt" && got branch newbranch) >/dev/null
1707 echo "modified alpha on branch" > $testroot/wt/alpha
1708 (cd "$testroot/wt" && got commit -m 'edit alpha') >/dev/null
1709 (cd "$testroot/wt" && got update -b master) >/dev/null
1711 # using a subshell to avoid clobbering global umask
1712 (umask 077 && cd "$testroot/wt" && got cherrypick newbranch) >/dev/null
1713 ret=$?
1714 if [ $ret -ne 0 ]; then
1715 test_done "$testroot" $ret
1716 return 1
1719 if ! ls -l "$testroot/wt/alpha" | grep -q ^-rw-------; then
1720 echo "alpha is not 0600 after cherrypick!" >&2
1721 ls -l "$testroot/wt/alpha" >&2
1722 test_done "$testroot" $ret
1723 return 1
1726 test_done "$testroot" 0
1729 test_cherrypick_logmsg_ref() {
1730 local testroot=`test_init cherrypick_logmsg_ref`
1732 got checkout $testroot/repo $testroot/wt > /dev/null
1733 ret=$?
1734 if [ $ret -ne 0 ]; then
1735 test_done "$testroot" "$ret"
1736 return 1
1739 (cd $testroot/repo && git checkout -q -b newbranch)
1741 echo "modified delta on branch" > $testroot/repo/gamma/delta
1742 echo "modified alpha on branch" > $testroot/repo/alpha
1743 (cd $testroot/repo && git rm -q beta)
1744 echo "new file on branch" > $testroot/repo/epsilon/new
1745 (cd $testroot/repo && git add epsilon/new)
1747 git_commit $testroot/repo -m "commit changes on newbranch"
1748 local commit_time=`git_show_author_time $testroot/repo`
1749 local branch_rev=`git_show_head $testroot/repo`
1751 echo "modified new file on branch" > $testroot/repo/epsilon/new
1753 git_commit $testroot/repo -m "commit modified new file on newbranch"
1754 local commit_time2=`git_show_author_time $testroot/repo`
1755 local branch_rev2=`git_show_head $testroot/repo`
1757 (cd $testroot/wt && got cherrypick $branch_rev > /dev/null)
1758 (cd $testroot/wt && got cherrypick $branch_rev2 > /dev/null)
1760 # show all log message refs in the work tree
1761 local sep="-----------------------------------------------"
1762 local logmsg="commit changes on newbranch"
1763 local changeset=" M alpha\n D beta\n A epsilon/new\n M gamma/delta"
1764 local logmsg2="commit modified new file on newbranch"
1765 local changeset2=" M epsilon/new"
1766 local date=`date -u -r $commit_time +"%a %b %e %X %Y UTC"`
1767 local date2=`date -u -r $commit_time2 +"%a %b %e %X %Y UTC"`
1768 local ymd=`date -u -r $commit_time +"%F"`
1769 local short_id=$(printf '%.7s' $branch_rev)
1770 local ymd2=`date -u -r $commit_time2 +"%F"`
1771 local short_id2="newbranch"
1772 local wt_sorted=$(printf "$branch_rev\n$branch_rev2" | sort)
1774 for r in $wt_sorted; do
1775 echo $sep >> $testroot/stdout.expected
1776 if [ $r = $branch_rev ]; then
1777 echo "cherrypick $r" >> $testroot/stdout.expected
1778 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
1779 echo "date: $date" >> $testroot/stdout.expected
1780 printf " \n $logmsg\n \n" >> $testroot/stdout.expected
1781 printf "$changeset\n\n" >> $testroot/stdout.expected
1783 # for forthcoming wt 'cherrypick -X' test
1784 echo "Deleted: $ymd $short_id $logmsg" >> \
1785 $testroot/stdout.wt_deleted
1786 else
1787 echo "cherrypick $r (newbranch)" \
1788 >> $testroot/stdout.expected
1789 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
1790 echo "date: $date2" >> $testroot/stdout.expected
1791 printf " \n $logmsg2\n \n" >> $testroot/stdout.expected
1792 printf "$changeset2\n\n" >> $testroot/stdout.expected
1794 # for forthcoming wt 'cherrypick -X' test
1795 echo "Deleted: $ymd2 $short_id2 $logmsg2" >> \
1796 $testroot/stdout.wt_deleted
1798 done
1800 (cd $testroot/wt && got cherrypick -l > $testroot/stdout)
1802 cmp -s $testroot/stdout.expected $testroot/stdout
1803 ret=$?
1804 if [ $ret -ne 0 ]; then
1805 diff -u $testroot/stdout.expected $testroot/stdout
1806 test_done "$testroot" "$ret"
1807 return 1
1810 # only show log message ref of the specified commit id
1811 echo $sep > $testroot/stdout.expected
1812 echo "cherrypick $branch_rev" >> $testroot/stdout.expected
1813 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
1814 echo "date: $date" >> $testroot/stdout.expected
1815 printf " \n $logmsg\n \n" >> $testroot/stdout.expected
1816 printf "$changeset\n\n" >> $testroot/stdout.expected
1818 (cd $testroot/wt && got cherrypick -l $branch_rev > $testroot/stdout)
1820 cmp -s $testroot/stdout.expected $testroot/stdout
1821 ret=$?
1822 if [ $ret -ne 0 ]; then
1823 diff -u $testroot/stdout.expected $testroot/stdout
1824 test_done "$testroot" "$ret"
1825 return 1
1828 # only show log message ref of the specified symref
1829 echo $sep > $testroot/stdout.expected
1830 echo "cherrypick $branch_rev2 (newbranch)" >> $testroot/stdout.expected
1831 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
1832 echo "date: $date2" >> $testroot/stdout.expected
1833 printf " \n $logmsg2\n \n" >> $testroot/stdout.expected
1834 printf "$changeset2\n\n" >> $testroot/stdout.expected
1836 (cd $testroot/wt && got cherrypick -l "newbranch" > $testroot/stdout)
1838 cmp -s $testroot/stdout.expected $testroot/stdout
1839 ret=$?
1840 if [ $ret -ne 0 ]; then
1841 diff -u $testroot/stdout.expected $testroot/stdout
1842 test_done "$testroot" "$ret"
1843 return 1
1846 # create a second work tree with cherrypicked commits and ensure
1847 # cy -l within the new work tree only shows the refs it created
1848 got checkout $testroot/repo $testroot/wt2 > /dev/null
1849 ret=$?
1850 if [ $ret -ne 0 ]; then
1851 test_done "$testroot" "$ret"
1852 return 1
1855 (cd $testroot/repo && git checkout -q -b newbranch2)
1857 echo "modified delta on branch2" > $testroot/repo/gamma/delta
1858 echo "modified alpha on branch2" > $testroot/repo/alpha
1859 echo "new file on branch2" > $testroot/repo/epsilon/new2
1860 (cd $testroot/repo && git add epsilon/new2)
1862 git_commit $testroot/repo -m "commit changes on newbranch2"
1863 local b2_commit_time=`git_show_author_time $testroot/repo`
1864 local branch2_rev=`git_show_head $testroot/repo`
1866 echo "modified file new2 on branch2" > $testroot/repo/epsilon/new2
1868 git_commit $testroot/repo -m "commit modified file new2 on newbranch2"
1869 local b2_commit_time2=`git_show_author_time $testroot/repo`
1870 local branch2_rev2=`git_show_head $testroot/repo`
1872 (cd $testroot/wt2 && got cherrypick $branch2_rev > /dev/null)
1873 (cd $testroot/wt2 && got cherrypick $branch2_rev2 > /dev/null)
1875 local b2_logmsg="commit changes on newbranch2"
1876 local b2_changeset=" M alpha\n A epsilon/new2\n M gamma/delta"
1877 local b2_logmsg2="commit modified file new2 on newbranch2"
1878 local b2_changeset2=" M epsilon/new2"
1879 date=`date -u -r $b2_commit_time +"%a %b %e %X %Y UTC"`
1880 date2=`date -u -r $b2_commit_time2 +"%a %b %e %X %Y UTC"`
1881 local wt2_sorted=$(printf "$branch2_rev\n$branch2_rev2" | sort)
1883 echo -n > $testroot/stdout.expected
1884 for r in $wt2_sorted; do
1885 echo $sep >> $testroot/stdout.expected
1886 if [ $r = $branch2_rev ]; then
1887 echo "cherrypick $r" >> $testroot/stdout.expected
1888 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
1889 echo "date: $date" >> $testroot/stdout.expected
1890 printf " \n $b2_logmsg\n \n" >> \
1891 $testroot/stdout.expected
1892 printf "$b2_changeset\n\n" >> \
1893 $testroot/stdout.expected
1894 else
1895 echo "cherrypick $r (newbranch2)" \
1896 >> $testroot/stdout.expected
1897 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
1898 echo "date: $date2" >> $testroot/stdout.expected
1899 printf " \n $b2_logmsg2\n \n" >> \
1900 $testroot/stdout.expected
1901 printf "$b2_changeset2\n\n" >> \
1902 $testroot/stdout.expected
1904 done
1906 (cd $testroot/wt2 && got cherrypick -l > $testroot/stdout)
1908 cmp -s $testroot/stdout.expected $testroot/stdout
1909 ret=$?
1910 if [ $ret -ne 0 ]; then
1911 diff -u $testroot/stdout.expected $testroot/stdout
1912 test_done "$testroot" "$ret"
1913 return 1
1916 # ensure both wt and wt2 logmsg refs can be retrieved and the
1917 # work tree UUID is displayed when listing refs from the repo
1918 local wt_uuid=$(cat $testroot/wt/.got/uuid)
1919 local wt2_uuid=$(cat $testroot/wt2/.got/uuid)
1920 local wt_first=`printf "$wt_uuid\n$wt2_uuid" | sort | head -1`
1922 for r in $wt_sorted; do
1923 echo -n "cherrypick $r" >> $testroot/wt.list
1924 if [ $r = $branch_rev2 ]; then
1925 echo -n " (newbranch)" >> $testroot/wt.list
1927 echo >> $testroot/wt.list
1928 echo "work tree: $wt_uuid" >> $testroot/wt.list
1929 done
1931 for r in $wt2_sorted; do
1932 echo -n "cherrypick $r" >> $testroot/wt2.list
1933 if [ $r = $branch2_rev2 ]; then
1934 echo -n " (newbranch2)" >> $testroot/wt2.list
1936 echo >> $testroot/wt2.list
1937 echo "work tree: $wt2_uuid" >> $testroot/wt2.list
1938 done
1940 if [ $wt_uuid = $wt_first ]; then
1941 mv $testroot/wt.list $testroot/stdout.expected
1942 cat $testroot/wt2.list >> $testroot/stdout.expected
1943 else
1944 mv $testroot/wt2.list $testroot/stdout.expected
1945 cat $testroot/wt.list >> $testroot/stdout.expected
1948 (cd $testroot/repo && got cherrypick -l | egrep "^(cherrypick|work)" \
1949 > $testroot/stdout)
1951 cmp -s $testroot/stdout.expected $testroot/stdout
1952 ret=$?
1953 if [ $ret -ne 0 ]; then
1954 diff -u $testroot/stdout.expected $testroot/stdout
1955 test_done "$testroot" "$ret"
1956 return 1
1959 # delete logmsg ref of the specified commit in work tree 2
1960 ymd=`date -u -r $b2_commit_time +"%F"`
1961 short_id=$(printf '%.7s' $branch2_rev)
1963 echo "Deleted: $ymd $short_id $b2_logmsg" > $testroot/stdout.expected
1964 (cd $testroot/wt2 && got cherrypick -X $branch2_rev > $testroot/stdout)
1966 cmp -s $testroot/stdout.expected $testroot/stdout
1967 ret=$?
1968 if [ $ret -ne 0 ]; then
1969 diff -u $testroot/stdout.expected $testroot/stdout
1970 test_done "$testroot" "$ret"
1971 return 1
1974 # delete all logmsg refs in work tree 1
1975 (cd $testroot && mv stdout.wt_deleted stdout.expected)
1976 (cd $testroot/wt && got cherrypick -X > $testroot/stdout)
1978 cmp -s $testroot/stdout.expected $testroot/stdout
1979 ret=$?
1980 if [ $ret -ne 0 ]; then
1981 diff -u $testroot/stdout.expected $testroot/stdout
1982 test_done "$testroot" "$ret"
1983 return 1
1986 # confirm all work tree 1 refs were deleted
1987 echo -n > $testroot/stdout.expected
1988 (cd $testroot/wt && got cherrypick -l > $testroot/stdout)
1990 cmp -s $testroot/stdout.expected $testroot/stdout
1991 ret=$?
1992 if [ $ret -ne 0 ]; then
1993 diff -u $testroot/stdout.expected $testroot/stdout
1994 test_done "$testroot" "$ret"
1995 return 1
1998 # make sure the remaining ref in work tree 2 was not also deleted
1999 echo $sep > $testroot/stdout.expected
2000 echo "cherrypick $branch2_rev2 (newbranch2)" \
2001 >> $testroot/stdout.expected
2002 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
2003 echo "date: $date2" >> $testroot/stdout.expected
2004 printf " \n $b2_logmsg2\n \n" >> $testroot/stdout.expected
2005 printf "$b2_changeset2\n\n" >> $testroot/stdout.expected
2007 (cd $testroot/wt2 && got cherrypick -l > $testroot/stdout)
2009 cmp -s $testroot/stdout.expected $testroot/stdout
2010 ret=$?
2011 if [ $ret -ne 0 ]; then
2012 diff -u $testroot/stdout.expected $testroot/stdout
2013 test_done "$testroot" "$ret"
2014 return 1
2017 # ensure we can delete work tree refs from the repository dir
2018 ymd=`date -u -r $b2_commit_time2 +"%F"`
2019 echo "Deleted: $ymd newbranch2 $b2_logmsg2" > $testroot/stdout.expected
2020 (cd $testroot/repo && got cherrypick -X > $testroot/stdout)
2022 cmp -s $testroot/stdout.expected $testroot/stdout
2023 ret=$?
2024 if [ $ret -ne 0 ]; then
2025 diff -u $testroot/stdout.expected $testroot/stdout
2028 test_done "$testroot" "$ret"
2031 test_parseargs "$@"
2032 run_test test_cherrypick_basic
2033 run_test test_cherrypick_root_commit
2034 run_test test_cherrypick_into_work_tree_with_conflicts
2035 run_test test_cherrypick_into_work_tree_with_mixed_commits
2036 run_test test_cherrypick_modified_submodule
2037 run_test test_cherrypick_added_submodule
2038 run_test test_cherrypick_conflict_wt_file_vs_repo_submodule
2039 run_test test_cherrypick_modified_symlinks
2040 run_test test_cherrypick_symlink_conflicts
2041 run_test test_cherrypick_with_path_prefix_and_empty_tree
2042 run_test test_cherrypick_conflict_no_eol
2043 run_test test_cherrypick_conflict_no_eol2
2044 run_test test_cherrypick_unrelated_changes
2045 run_test test_cherrypick_same_branch
2046 run_test test_cherrypick_dot_on_a_line_by_itself
2047 run_test test_cherrypick_binary_file
2048 run_test test_cherrypick_umask
2049 run_test test_cherrypick_logmsg_ref