3 # Copyright (c) 2019 Stefan Sperling <stsp@openbsd.org>
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.
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.
19 test_backout_basic
() {
20 local testroot
=`test_init backout_basic`
22 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
24 if [ $ret -ne 0 ]; then
25 test_done
"$testroot" "$ret"
29 echo "new" > $testroot/wt
/new
30 (cd $testroot/wt
&& got add new
> /dev
/null
)
31 echo "modified alpha" > $testroot/wt
/alpha
32 (cd $testroot/wt
&& got
rm epsilon
/zeta
> /dev
/null
)
33 (cd $testroot/wt
&& got commit
-m "bad changes" > /dev
/null
)
35 local bad_commit
=`git_show_head $testroot/repo`
38 (cd $testroot/wt
&& got update
> /dev
/null
)
40 echo "modified beta" > $testroot/wt
/beta
41 (cd $testroot/wt
&& got commit
-m "changing beta" > /dev
/null
)
43 (cd $testroot/wt
&& got update
> /dev
/null
)
45 (cd $testroot/wt
&& got backout
$bad_commit > $testroot/stdout
)
47 echo "G alpha" > $testroot/stdout.expected
48 echo "A epsilon/zeta" >> $testroot/stdout.expected
49 echo "D new" >> $testroot/stdout.expected
50 echo "Backed out commit $bad_commit" >> $testroot/stdout.expected
51 cmp -s $testroot/stdout.expected
$testroot/stdout
53 if [ $ret -ne 0 ]; then
54 diff -u $testroot/stdout.expected
$testroot/stdout
55 test_done
"$testroot" "$ret"
59 echo "alpha" > $testroot/content.expected
60 cat $testroot/wt
/alpha
> $testroot/content
61 cmp -s $testroot/content.expected
$testroot/content
63 if [ $ret -ne 0 ]; then
64 diff -u $testroot/content.expected
$testroot/content
65 test_done
"$testroot" "$ret"
69 if [ -e "$testroot/wt/new" ]; then
70 echo "file '$testroot/wt/new' still exists on disk" >&2
71 test_done
"$testroot" "$ret"
75 if [ ! -e "$testroot/wt/epsilon/zeta" ]; then
76 echo "file '$testroot/wt/epsilon/zeta' is missing on disk" >&2
77 test_done
"$testroot" "$ret"
81 echo 'M alpha' > $testroot/stdout.expected
82 echo 'A epsilon/zeta' >> $testroot/stdout.expected
83 echo 'D new' >> $testroot/stdout.expected
84 (cd $testroot/wt
&& got status
> $testroot/stdout
)
85 cmp -s $testroot/stdout.expected
$testroot/stdout
87 if [ $ret -ne 0 ]; then
88 diff -u $testroot/stdout.expected
$testroot/stdout
90 test_done
"$testroot" "$ret"
93 test_backout_edits_for_file_since_deleted
() {
94 local testroot
=`test_init backout_edits_for_file_since_deleted`
96 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
98 if [ $ret -ne 0 ]; then
99 test_done
"$testroot" "$ret"
103 echo "modified alpha" > $testroot/wt
/alpha
104 (cd $testroot/wt
&& got commit
-m "changing alpha" > /dev
/null
)
106 local bad_commit
=`git_show_head $testroot/repo`
109 (cd $testroot/wt
&& got update
> /dev
/null
)
111 (cd $testroot/wt
&& got
rm alpha
> /dev
/null
)
112 (cd $testroot/wt
&& got commit
-m "removing alpha" > /dev
/null
)
114 (cd $testroot/wt
&& got update
> /dev
/null
)
116 (cd $testroot/wt
&& got backout
$bad_commit > $testroot/stdout
)
118 echo "! alpha" > $testroot/stdout.expected
119 echo "Backed out commit $bad_commit" >> $testroot/stdout.expected
120 echo -n "Files which had incoming changes but could not be found " \
121 >> $testroot/stdout.expected
122 echo "in the work tree: 1" >> $testroot/stdout.expected
123 cmp -s $testroot/stdout.expected
$testroot/stdout
125 if [ $ret -ne 0 ]; then
126 diff -u $testroot/stdout.expected
$testroot/stdout
127 test_done
"$testroot" "$ret"
131 if [ -e "$testroot/wt/alpha" ]; then
132 echo "file '$testroot/wt/alpha' still exists on disk" >&2
133 test_done
"$testroot" "$ret"
137 echo -n '' > $testroot/stdout.expected
138 (cd $testroot/wt
&& got status
> $testroot/stdout
)
139 cmp -s $testroot/stdout.expected
$testroot/stdout
141 if [ $ret -ne 0 ]; then
142 diff -u $testroot/stdout.expected
$testroot/stdout
144 test_done
"$testroot" "$ret"
147 test_backout_next_commit
() {
148 local testroot
=`test_init backout_next_commit`
149 local commit0
=`git_show_head $testroot/repo`
151 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
153 if [ $ret -ne 0 ]; then
154 test_done
"$testroot" "$ret"
158 echo "new" > $testroot/wt
/new
159 (cd $testroot/wt
&& got add new
> /dev
/null
)
160 echo "modified alpha" > $testroot/wt
/alpha
161 (cd $testroot/wt
&& got
rm epsilon
/zeta
> /dev
/null
)
162 (cd $testroot/wt
&& got commit
-m "bad changes" > /dev
/null
)
164 local bad_commit
=`git_show_head $testroot/repo`
166 (cd $testroot/wt
&& got update
-c $commit0 > /dev
/null
)
168 (cd $testroot/wt
&& got backout
$bad_commit > $testroot/stdout
)
170 echo "G alpha" > $testroot/stdout.expected
171 echo "G epsilon/zeta" >> $testroot/stdout.expected
172 echo "! new" >> $testroot/stdout.expected
173 echo "Backed out commit $bad_commit" >> $testroot/stdout.expected
174 echo -n "Files which had incoming changes but could not be found " \
175 >> $testroot/stdout.expected
176 echo "in the work tree: 1" >> $testroot/stdout.expected
177 cmp -s $testroot/stdout.expected
$testroot/stdout
179 if [ $ret -ne 0 ]; then
180 diff -u $testroot/stdout.expected
$testroot/stdout
181 test_done
"$testroot" "$ret"
185 if [ -e "$testroot/wt/new" ]; then
186 echo "file '$testroot/wt/new' still exists on disk" >&2
187 test_done
"$testroot" "$ret"
191 echo "zeta" > $testroot/content.expected
192 cat $testroot/wt
/epsilon
/zeta
> $testroot/content
193 cmp -s $testroot/content.expected
$testroot/content
195 if [ $ret -ne 0 ]; then
196 diff -u $testroot/content.expected
$testroot/content
197 test_done
"$testroot" "$ret"
201 echo -n '' > $testroot/stdout.expected
202 (cd $testroot/wt
&& got status
> $testroot/stdout
)
203 cmp -s $testroot/stdout.expected
$testroot/stdout
205 if [ $ret -ne 0 ]; then
206 diff -u $testroot/stdout.expected
$testroot/stdout
208 test_done
"$testroot" "$ret"
211 test_backout_umask
() {
212 local testroot
=`test_init backout_umask`
214 got checkout
"$testroot/repo" "$testroot/wt" >/dev
/null
215 echo "edit alpha" >$testroot/wt
/alpha
216 (cd "$testroot/wt" && got commit
-m 'edit alpha') >/dev
/null
218 if [ $ret -ne 0 ]; then
219 test_done
"$testroot" $ret
223 local commit
=`git_show_head "$testroot/repo"`
225 (cd "$testroot/wt" && got update
) >/dev
/null
227 # using a subshell to avoid clobbering global umask
228 (umask 077 && cd "$testroot/wt" && got backout
$commit) >/dev
/null
230 if [ $ret -ne 0 ]; then
231 test_done
"$testroot" $ret
235 if ! ls -l "$testroot/wt/alpha" |
grep -q ^
-rw-------; then
236 echo "alpha is not 0600 after backout" >&2
237 ls -l "$testroot/wt/alpha" >&2
238 test_done
"$testroot" $ret
242 test_done
"$testroot" 0
245 test_backout_logmsg_ref
() {
246 local testroot
=`test_init backout_logmsg_ref`
248 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
250 if [ $ret -ne 0 ]; then
251 test_done
"$testroot" "$ret"
255 (cd $testroot/repo
&& git checkout
-q -b newbranch
)
257 echo "modified delta on branch" > $testroot/repo
/gamma
/delta
258 echo "modified alpha on branch" > $testroot/repo
/alpha
259 (cd $testroot/repo
&& git
rm -q beta
)
260 echo "new file on branch" > $testroot/repo
/epsilon
/new
261 (cd $testroot/repo
&& git add epsilon
/new
)
263 git_commit
$testroot/repo
-m "commit changes on newbranch"
264 local commit_time
=`git_show_author_time $testroot/repo`
265 local branch_rev
=`git_show_head $testroot/repo`
267 echo "modified new file on branch" > $testroot/repo
/epsilon
/new
269 git_commit
$testroot/repo
-m "commit modified new file on newbranch"
270 local commit_time2
=`git_show_author_time $testroot/repo`
271 local branch_rev2
=`git_show_head $testroot/repo`
273 (cd $testroot/wt
&& got backout
$branch_rev > /dev
/null
)
274 (cd $testroot/wt
&& got backout
$branch_rev2 > /dev
/null
)
276 # show all backout log message refs in the work tree
277 local sep
="-----------------------------------------------"
278 local logmsg
="commit changes on newbranch"
279 local changeset
=" M alpha\n D beta\n A epsilon/new\n M gamma/delta"
280 local logmsg2
="commit modified new file on newbranch"
281 local changeset2
=" M epsilon/new"
282 local date=`date -u -r $commit_time +"%a %b %e %X %Y UTC"`
283 local date2
=`date -u -r $commit_time2 +"%a %b %e %X %Y UTC"`
284 local ymd
=`date -u -r $commit_time +"%F"`
285 local short_id
=$
(printf '%.7s' $branch_rev)
286 local ymd2
=`date -u -r $commit_time2 +"%F"`
287 local short_id2
="newbranch"
288 local wt_sorted
=$
(printf "$branch_rev\n$branch_rev2" |
sort)
290 for r
in $wt_sorted; do
291 echo $sep >> $testroot/stdout.expected
292 if [ $r = $branch_rev ]; then
293 echo "backout $r" >> $testroot/stdout.expected
294 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
295 echo "date: $date" >> $testroot/stdout.expected
296 printf " \n $logmsg\n \n" >> $testroot/stdout.expected
297 printf "$changeset\n\n" >> $testroot/stdout.expected
299 # for forthcoming wt 'backout -X' test
300 echo "Deleted: $ymd $short_id $logmsg" >> \
301 $testroot/stdout.wt_deleted
303 echo "backout $r (newbranch)" \
304 >> $testroot/stdout.expected
305 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
306 echo "date: $date2" >> $testroot/stdout.expected
307 printf " \n $logmsg2\n \n" >> $testroot/stdout.expected
308 printf "$changeset2\n\n" >> $testroot/stdout.expected
310 # for forthcoming wt 'backout -X' test
311 echo "Deleted: $ymd2 $short_id2 $logmsg2" >> \
312 $testroot/stdout.wt_deleted
316 (cd $testroot/wt
&& got backout
-l > $testroot/stdout
)
318 cmp -s $testroot/stdout.expected
$testroot/stdout
320 if [ $ret -ne 0 ]; then
321 diff -u $testroot/stdout.expected
$testroot/stdout
322 test_done
"$testroot" "$ret"
326 # only show log message ref of the specified commit id
327 echo $sep > $testroot/stdout.expected
328 echo "backout $branch_rev" >> $testroot/stdout.expected
329 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
330 echo "date: $date" >> $testroot/stdout.expected
331 printf " \n $logmsg\n \n" >> $testroot/stdout.expected
332 printf "$changeset\n\n" >> $testroot/stdout.expected
334 (cd $testroot/wt
&& got backout
-l $branch_rev > $testroot/stdout
)
336 cmp -s $testroot/stdout.expected
$testroot/stdout
338 if [ $ret -ne 0 ]; then
339 diff -u $testroot/stdout.expected
$testroot/stdout
340 test_done
"$testroot" "$ret"
344 # only show log message ref of the specified symref
345 echo $sep > $testroot/stdout.expected
346 echo "backout $branch_rev2 (newbranch)" >> $testroot/stdout.expected
347 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
348 echo "date: $date2" >> $testroot/stdout.expected
349 printf " \n $logmsg2\n \n" >> $testroot/stdout.expected
350 printf "$changeset2\n\n" >> $testroot/stdout.expected
352 (cd $testroot/wt
&& got backout
-l "newbranch" > $testroot/stdout
)
354 cmp -s $testroot/stdout.expected
$testroot/stdout
356 if [ $ret -ne 0 ]; then
357 diff -u $testroot/stdout.expected
$testroot/stdout
358 test_done
"$testroot" "$ret"
362 # create a second work tree with backed-out commits and ensure
363 # bo -l within the new work tree only shows the refs it created
364 got checkout
$testroot/repo
$testroot/wt2
> /dev
/null
366 if [ $ret -ne 0 ]; then
367 test_done
"$testroot" "$ret"
371 (cd $testroot/repo
&& git checkout
-q -b newbranch2
)
373 echo "modified delta on branch2" > $testroot/repo
/gamma
/delta
374 echo "modified alpha on branch2" > $testroot/repo
/alpha
375 echo "new file on branch2" > $testroot/repo
/epsilon
/new2
376 (cd $testroot/repo
&& git add epsilon
/new2
)
378 git_commit
$testroot/repo
-m "commit changes on newbranch2"
379 local b2_commit_time
=`git_show_author_time $testroot/repo`
380 local branch2_rev
=`git_show_head $testroot/repo`
382 echo "modified file new2 on branch2" > $testroot/repo
/epsilon
/new2
384 git_commit
$testroot/repo
-m "commit modified file new2 on newbranch2"
385 local b2_commit_time2
=`git_show_author_time $testroot/repo`
386 local branch2_rev2
=`git_show_head $testroot/repo`
388 (cd $testroot/wt2
&& got backout
$branch2_rev > /dev
/null
)
389 (cd $testroot/wt2
&& got backout
$branch2_rev2 > /dev
/null
)
391 local b2_logmsg
="commit changes on newbranch2"
392 local b2_changeset
=" M alpha\n A epsilon/new2\n M gamma/delta"
393 local b2_logmsg2
="commit modified file new2 on newbranch2"
394 local b2_changeset2
=" M epsilon/new2"
395 date=`date -u -r $b2_commit_time +"%a %b %e %X %Y UTC"`
396 date2
=`date -u -r $b2_commit_time2 +"%a %b %e %X %Y UTC"`
397 local wt2_sorted
=$
(printf "$branch2_rev\n$branch2_rev2" |
sort)
399 echo -n > $testroot/stdout.expected
400 for r
in $wt2_sorted; do
401 echo $sep >> $testroot/stdout.expected
402 if [ $r = $branch2_rev ]; then
403 echo "backout $r" >> $testroot/stdout.expected
404 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
405 echo "date: $date" >> $testroot/stdout.expected
406 printf " \n $b2_logmsg\n \n" >> \
407 $testroot/stdout.expected
408 printf "$b2_changeset\n\n" >> \
409 $testroot/stdout.expected
411 echo "backout $r (newbranch2)" \
412 >> $testroot/stdout.expected
413 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
414 echo "date: $date2" >> $testroot/stdout.expected
415 printf " \n $b2_logmsg2\n \n" >> \
416 $testroot/stdout.expected
417 printf "$b2_changeset2\n\n" >> \
418 $testroot/stdout.expected
422 (cd $testroot/wt2
&& got backout
-l > $testroot/stdout
)
424 cmp -s $testroot/stdout.expected
$testroot/stdout
426 if [ $ret -ne 0 ]; then
427 diff -u $testroot/stdout.expected
$testroot/stdout
428 test_done
"$testroot" "$ret"
432 # ensure both wt and wt2 logmsg refs can be retrieved and the
433 # work tree UUID is displayed when listing refs from the repo
434 local wt_uuid
=$
(cat $testroot/wt
/.got
/uuid
)
435 local wt2_uuid
=$
(cat $testroot/wt
2/.got
/uuid
)
436 local wt_first
=`printf "$wt_uuid\n$wt2_uuid" | sort | head -1`
438 for r
in $wt_sorted; do
439 echo -n "backout $r" >> $testroot/wt.list
440 if [ $r = $branch_rev2 ]; then
441 echo -n " (newbranch)" >> $testroot/wt.list
443 echo >> $testroot/wt.list
444 echo "work tree: $wt_uuid" >> $testroot/wt.list
447 for r
in $wt2_sorted; do
448 echo -n "backout $r" >> $testroot/wt2.list
449 if [ $r = $branch2_rev2 ]; then
450 echo -n " (newbranch2)" >> $testroot/wt2.list
452 echo >> $testroot/wt2.list
453 echo "work tree: $wt2_uuid" >> $testroot/wt2.list
456 if [ $wt_uuid = $wt_first ]; then
457 mv $testroot/wt.list
$testroot/stdout.expected
458 cat $testroot/wt2.list
>> $testroot/stdout.expected
460 mv $testroot/wt2.list
$testroot/stdout.expected
461 cat $testroot/wt.list
>> $testroot/stdout.expected
464 (cd $testroot/repo
&& got backout
-l |
egrep "^(backout|work)" \
467 cmp -s $testroot/stdout.expected
$testroot/stdout
469 if [ $ret -ne 0 ]; then
470 diff -u $testroot/stdout.expected
$testroot/stdout
471 test_done
"$testroot" "$ret"
475 # delete logmsg ref of the specified commit in work tree 2
476 ymd
=`date -u -r $b2_commit_time +"%F"`
477 short_id
=$
(printf '%.7s' $branch2_rev)
479 echo "Deleted: $ymd $short_id $b2_logmsg" > $testroot/stdout.expected
480 (cd $testroot/wt2
&& got backout
-X $branch2_rev > $testroot/stdout
)
482 cmp -s $testroot/stdout.expected
$testroot/stdout
484 if [ $ret -ne 0 ]; then
485 diff -u $testroot/stdout.expected
$testroot/stdout
486 test_done
"$testroot" "$ret"
490 # delete all logmsg refs in work tree 1
491 (cd $testroot && mv stdout.wt_deleted stdout.expected
)
492 (cd $testroot/wt
&& got backout
-X > $testroot/stdout
)
494 cmp -s $testroot/stdout.expected
$testroot/stdout
496 if [ $ret -ne 0 ]; then
497 diff -u $testroot/stdout.expected
$testroot/stdout
498 test_done
"$testroot" "$ret"
502 # confirm all work tree 1 refs were deleted
503 echo -n > $testroot/stdout.expected
504 (cd $testroot/wt
&& got backout
-l > $testroot/stdout
)
506 cmp -s $testroot/stdout.expected
$testroot/stdout
508 if [ $ret -ne 0 ]; then
509 diff -u $testroot/stdout.expected
$testroot/stdout
510 test_done
"$testroot" "$ret"
514 # make sure the remaining ref in work tree 2 was not also deleted
515 echo $sep > $testroot/stdout.expected
516 echo "backout $branch2_rev2 (newbranch2)" >> $testroot/stdout.expected
517 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
518 echo "date: $date2" >> $testroot/stdout.expected
519 printf " \n $b2_logmsg2\n \n" >> $testroot/stdout.expected
520 printf "$b2_changeset2\n\n" >> $testroot/stdout.expected
522 (cd $testroot/wt2
&& got backout
-l > $testroot/stdout
)
524 cmp -s $testroot/stdout.expected
$testroot/stdout
526 if [ $ret -ne 0 ]; then
527 diff -u $testroot/stdout.expected
$testroot/stdout
528 test_done
"$testroot" "$ret"
532 # ensure we can delete work tree refs from the repository dir
533 ymd
=`date -u -r $b2_commit_time2 +"%F"`
534 echo "Deleted: $ymd newbranch2 $b2_logmsg2" > $testroot/stdout.expected
535 (cd $testroot/repo
&& got backout
-X > $testroot/stdout
)
537 cmp -s $testroot/stdout.expected
$testroot/stdout
539 if [ $ret -ne 0 ]; then
540 diff -u $testroot/stdout.expected
$testroot/stdout
543 test_done
"$testroot" "$ret"
547 run_test test_backout_basic
548 run_test test_backout_edits_for_file_since_deleted
549 run_test test_backout_next_commit
550 run_test test_backout_umask
551 run_test test_backout_logmsg_ref