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.
24 (cd $testroot/wt
&& got blame
"$file" | cut
-d ' ' -f 2 \
25 > $testroot/${file}.blame.got
)
26 git
-C $testroot/repo
reset --hard master
> /dev
/null
27 git
-C $testroot/repo blame
"$file" | cut
-d ' ' -f 1 \
28 > $testroot/${file}.blame.git
30 cmp -s $testroot/${file}.blame.git
$testroot/${file}.blame.got
32 if [ $ret -ne 0 -a "$xfail" = "" ]; then
33 diff -u $testroot/${file}.blame.git
$testroot/${file}.blame.got
40 local testroot
=`test_init blame_basic`
42 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
44 if [ $ret -ne 0 ]; then
45 test_done
"$testroot" "$ret"
49 echo 1 > $testroot/wt
/alpha
50 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
51 local commit1
=`git_show_head $testroot/repo`
53 echo 2 >> $testroot/wt
/alpha
54 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
55 local commit2
=`git_show_head $testroot/repo`
57 echo 3 >> $testroot/wt
/alpha
58 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
59 local commit3
=`git_show_head $testroot/repo`
60 local author_time
=`git_show_author_time $testroot/repo`
62 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
64 local short_commit1
=`trim_obj_id 8 $commit1`
65 local short_commit2
=`trim_obj_id 8 $commit2`
66 local short_commit3
=`trim_obj_id 8 $commit3`
68 d
=`date -u -r $author_time +"%F"`
69 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
70 echo "2) $short_commit2 $d $GOT_AUTHOR_8 2" >> $testroot/stdout.expected
71 echo "3) $short_commit3 $d $GOT_AUTHOR_8 3" >> $testroot/stdout.expected
73 cmp -s $testroot/stdout.expected
$testroot/stdout
75 if [ $ret -ne 0 ]; then
76 diff -u $testroot/stdout.expected
$testroot/stdout
77 test_done
"$testroot" "$ret"
81 blame_cmp
"$testroot" "alpha"
83 test_done
"$testroot" "$ret"
87 local testroot
=`test_init blame_tag`
90 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
92 if [ $ret -ne 0 ]; then
93 test_done
"$testroot" "$ret"
96 echo 1 > $testroot/wt
/alpha
97 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
98 local commit1
=`git_show_head $testroot/repo`
100 echo 2 >> $testroot/wt
/alpha
101 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
102 local commit2
=`git_show_head $testroot/repo`
104 git
-C $testroot/repo tag
-a -m "test" $tag
106 echo 3 >> $testroot/wt
/alpha
107 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
108 local commit3
=`git_show_head $testroot/repo`
109 local author_time
=`git_show_author_time $testroot/repo`
111 (cd $testroot/wt
&& got blame
-c $tag alpha
> $testroot/stdout
)
113 local short_commit1
=`trim_obj_id 8 $commit1`
114 local short_commit2
=`trim_obj_id 8 $commit2`
116 d
=`date -u -r $author_time +"%F"`
117 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
118 echo "2) $short_commit2 $d $GOT_AUTHOR_8 2" >> $testroot/stdout.expected
120 cmp -s $testroot/stdout.expected
$testroot/stdout
122 if [ $ret -ne 0 ]; then
123 diff -u $testroot/stdout.expected
$testroot/stdout
124 test_done
"$testroot" "$ret"
128 blame_cmp
"$testroot" "alpha"
130 test_done
"$testroot" "$ret"
133 test_blame_file_single_line
() {
134 local testroot
=`test_init blame_file_single_line`
136 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
138 if [ $ret -ne 0 ]; then
139 test_done
"$testroot" "$ret"
143 echo 1 > $testroot/wt
/alpha
144 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
145 local commit1
=`git_show_head $testroot/repo`
146 local author_time
=`git_show_author_time $testroot/repo`
148 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
150 local short_commit1
=`trim_obj_id 8 $commit1`
152 d
=`date -u -r $author_time +"%F"`
153 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
155 cmp -s $testroot/stdout.expected
$testroot/stdout
157 if [ $ret -ne 0 ]; then
158 diff -u $testroot/stdout.expected
$testroot/stdout
159 test_done
"$testroot" "$ret"
163 blame_cmp
"$testroot" "alpha"
165 test_done
"$testroot" "$ret"
168 test_blame_file_single_line_no_newline
() {
169 local testroot
=`test_init blame_file_single_line_no_newline`
171 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
173 if [ $ret -ne 0 ]; then
174 test_done
"$testroot" "$ret"
178 echo -n 1 > $testroot/wt
/alpha
179 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
180 local commit1
=`git_show_head $testroot/repo`
181 local author_time
=`git_show_author_time $testroot/repo`
183 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
185 local short_commit1
=`trim_obj_id 8 $commit1`
187 d
=`date -u -r $author_time +"%F"`
188 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
190 cmp -s $testroot/stdout.expected
$testroot/stdout
192 if [ $ret -ne 0 ]; then
193 diff -u $testroot/stdout.expected
$testroot/stdout
195 test_done
"$testroot" "$ret"
198 test_blame_all_lines_replaced
() {
199 local testroot
=`test_init blame_all_lines_replaced`
201 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
203 if [ $ret -ne 0 ]; then
204 test_done
"$testroot" "$ret"
208 seq 8 > $testroot/wt
/alpha
209 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
210 local commit1
=`git_show_head $testroot/repo`
211 local short_commit1
=`trim_obj_id 8 $commit1`
212 local author_time
=`git_show_author_time $testroot/repo`
214 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
216 d
=`date -u -r $author_time +"%F"`
217 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
218 echo "2) $short_commit1 $d $GOT_AUTHOR_8 2" >> $testroot/stdout.expected
219 echo "3) $short_commit1 $d $GOT_AUTHOR_8 3" >> $testroot/stdout.expected
220 echo "4) $short_commit1 $d $GOT_AUTHOR_8 4" >> $testroot/stdout.expected
221 echo "5) $short_commit1 $d $GOT_AUTHOR_8 5" >> $testroot/stdout.expected
222 echo "6) $short_commit1 $d $GOT_AUTHOR_8 6" >> $testroot/stdout.expected
223 echo "7) $short_commit1 $d $GOT_AUTHOR_8 7" >> $testroot/stdout.expected
224 echo "8) $short_commit1 $d $GOT_AUTHOR_8 8" >> $testroot/stdout.expected
226 cmp -s $testroot/stdout.expected
$testroot/stdout
228 if [ $ret -ne 0 ]; then
229 diff -u $testroot/stdout.expected
$testroot/stdout
231 test_done
"$testroot" "$ret"
235 test_blame_lines_shifted_up
() {
236 local testroot
=`test_init blame_lines_shifted_up`
238 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
240 if [ $ret -ne 0 ]; then
241 test_done
"$testroot" "$ret"
245 seq 8 > $testroot/wt
/alpha
246 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
247 local commit1
=`git_show_head $testroot/repo`
248 local short_commit1
=`trim_obj_id 8 $commit1`
249 local author_time
=`git_show_author_time $testroot/repo`
251 ed
-s $testroot/wt
/alpha
<<-\EOF
255 (cd $testroot/wt && got commit -m "change 2" > /dev/null)
256 local commit2=`git_show_head $testroot/repo`
257 local short_commit2=`trim_obj_id 8 $commit2`
259 seq 2 > $testroot/wt/alpha
260 echo foo >> $testroot/wt/alpha
261 echo bar >> $testroot/wt/alpha
262 echo baz >> $testroot/wt/alpha
263 seq 6 8 >> $testroot/wt/alpha
264 (cd $testroot/wt && got commit -m "change 3" > /dev/null)
265 local commit3=`git_show_head $testroot/repo`
266 local short_commit3=`trim_obj_id 8 $commit3`
267 local author_time=`git_show_author_time $testroot/repo`
269 (cd $testroot/wt && got blame alpha > $testroot/stdout)
271 d=`date -u -r $author_time +"%F"`
272 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
273 echo "2) $short_commit1 $d $GOT_AUTHOR_8 2" >> $testroot/stdout.expected
274 echo "3) $short_commit3 $d $GOT_AUTHOR_8 foo" >> $testroot/stdout.expected
275 echo "4) $short_commit3 $d $GOT_AUTHOR_8 bar" >> $testroot/stdout.expected
276 echo "5) $short_commit3 $d $GOT_AUTHOR_8 baz" >> $testroot/stdout.expected
277 echo "6) $short_commit1 $d $GOT_AUTHOR_8 6" >> $testroot/stdout.expected
278 echo "7) $short_commit1 $d $GOT_AUTHOR_8 7" >> $testroot/stdout.expected
279 echo "8) $short_commit1 $d $GOT_AUTHOR_8 8" >> $testroot/stdout.expected
281 cmp -s $testroot/stdout.expected $testroot/stdout
283 if [ $ret -ne 0 ]; then
284 diff -u $testroot/stdout.expected $testroot/stdout
285 test_done "$testroot" "$ret"
289 blame_cmp "$testroot" "alpha"
291 test_done "$testroot" "$ret"
294 test_blame_lines_shifted_down() {
295 local testroot=`test_init blame_lines_shifted_down`
297 got checkout $testroot/repo $testroot/wt > /dev/null
299 if [ $ret -ne 0 ]; then
300 test_done "$testroot" "$ret"
304 seq 8 > $testroot/wt/alpha
305 (cd $testroot/wt && got commit -m "change 1" > /dev/null)
306 local commit1=`git_show_head $testroot/repo`
307 local short_commit1=`trim_obj_id 8 $commit1`
308 local author_time=`git_show_author_time $testroot/repo`
310 ed -s $testroot/wt/alpha <<-\
EOF
314 (cd $testroot/wt && got commit -m "change 2" > /dev/null)
315 local commit2=`git_show_head $testroot/repo`
316 local short_commit2=`trim_obj_id 8 $commit2`
318 seq 2 > $testroot/wt/alpha
319 echo foo >> $testroot/wt/alpha
320 echo bar >> $testroot/wt/alpha
321 echo baz >> $testroot/wt/alpha
322 seq 3 8 >> $testroot/wt/alpha
323 (cd $testroot/wt && got commit -m "change 3" > /dev/null)
324 local commit3=`git_show_head $testroot/repo`
325 local short_commit3=`trim_obj_id 8 $commit3`
326 local author_time=`git_show_author_time $testroot/repo`
328 (cd $testroot/wt && got blame alpha > $testroot/stdout)
330 d=`date -u -r $author_time +"%F"`
331 echo "01) $short_commit1 $d $GOT_AUTHOR_8 1" \
332 > $testroot/stdout.expected
333 echo "02) $short_commit1 $d $GOT_AUTHOR_8 2" \
334 >> $testroot/stdout.expected
335 echo "03) $short_commit3 $d $GOT_AUTHOR_8 foo" \
336 >> $testroot/stdout.expected
337 echo "04) $short_commit3 $d $GOT_AUTHOR_8 bar" \
338 >> $testroot/stdout.expected
339 echo "05) $short_commit3 $d $GOT_AUTHOR_8 baz" \
340 >> $testroot/stdout.expected
341 echo "06) $short_commit1 $d $GOT_AUTHOR_8 3" \
342 >> $testroot/stdout.expected
343 echo "07) $short_commit1 $d $GOT_AUTHOR_8 4" \
344 >> $testroot/stdout.expected
345 echo "08) $short_commit1 $d $GOT_AUTHOR_8 5" \
346 >> $testroot/stdout.expected
347 echo "09) $short_commit1 $d $GOT_AUTHOR_8 6" \
348 >> $testroot/stdout.expected
349 echo "10) $short_commit1 $d $GOT_AUTHOR_8 7" \
350 >> $testroot/stdout.expected
351 echo "11) $short_commit3 $d $GOT_AUTHOR_8 8" \
352 >> $testroot/stdout.expected
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 blame_cmp "$testroot" "alpha"
364 test_done "$testroot" "$ret"
367 test_blame_commit_subsumed() {
368 local testroot=`test_init blame_commit_subsumed`
370 got checkout $testroot/repo $testroot/wt > /dev/null
372 if [ $ret -ne 0 ]; then
373 test_done "$testroot" "$ret"
377 cat > $testroot/wt/alpha <<EOF
378 SUBDIRS = ext modules codedocs docs
389 build-aux/gen-version
390 codedocs/doxygen.conf
391 contrib/powerdns.solaris.init.d
392 pdns/named.conf.parsertest
393 regression-tests/zones/unit.test
395 ACLOCAL_AMFLAGS = -I m4
397 dvi: # do nothing to build dvi
399 (cd $testroot/wt && got commit -m "change 1" > /dev/null)
400 local commit1=`git_show_head $testroot/repo`
401 local short_commit1=`trim_obj_id 8 $commit1`
402 local author_time1=`git_show_author_time $testroot/repo`
403 local d1=`date -u -r $author_time1 +"%F"`
405 cat > $testroot/wt/alpha <<EOF
406 SUBDIRS = ext modules codedocs docs
415 build-aux/gen-version
416 codedocs/doxygen.conf
417 contrib/powerdns.solaris.init.d
418 pdns/named.conf.parsertest
419 regression-tests/zones/unit.test
421 ACLOCAL_AMFLAGS = -I m4
423 dvi: # do nothing to build dvi
425 # all changes in this commit will be subsumed by later commits
426 (cd $testroot/wt && got commit -m "change 2" > /dev/null)
427 local commit2=`git_show_head $testroot/repo`
428 local short_commit2=`trim_obj_id 8 $commit2`
429 local author_time2=`git_show_author_time $testroot/repo`
430 local d2=`date -u -r $author_time2 +"%F"`
432 cat > $testroot/wt/alpha <<EOF
433 SUBDIRS = ext modules pdns codedocs docs
440 build-aux/gen-version
441 codedocs/doxygen.conf
442 contrib/powerdns.solaris.init.d
443 pdns/named.conf.parsertest
444 regression-tests/zones/unit.test
446 ACLOCAL_AMFLAGS = -I m4
448 dvi: # do nothing to build dvi
450 (cd $testroot/wt && got commit -m "change 3" > /dev/null)
451 local commit3=`git_show_head $testroot/repo`
452 local short_commit3=`trim_obj_id 8 $commit3`
453 local author_time3=`git_show_author_time $testroot/repo`
454 local d3=`date -u -r $author_time3 +"%F"`
456 cat > $testroot/wt/alpha <<EOF
457 SUBDIRS = ext modules pdns codedocs docs
464 codedocs/doxygen.conf
465 contrib/powerdns.solaris.init.d
466 pdns/named.conf.parsertest
467 regression-tests/zones/unit.test
468 builder-support/gen-version
470 ACLOCAL_AMFLAGS = -I m4
472 dvi: # do nothing to build dvi
474 (cd $testroot/wt && got commit -m "change 4" > /dev/null)
475 local commit4=`git_show_head $testroot/repo`
476 local short_commit4=`trim_obj_id 8 $commit4`
477 local author_time4=`git_show_author_time $testroot/repo`
478 local d4=`date -u -r $author_time4 +"%F"`
480 (cd $testroot/wt && got blame alpha > $testroot/stdout)
482 echo -n "01) $short_commit3 $d3 $GOT_AUTHOR_8 " \
483 > $testroot/stdout.expected
484 echo "SUBDIRS = ext modules pdns codedocs docs" \
485 >> $testroot/stdout.expected
486 echo "02) $short_commit1 $d1 $GOT_AUTHOR_8 " \
487 >> $testroot/stdout.expected
488 echo -n "03) $short_commit1 $d1 $GOT_AUTHOR_8 " \
489 >> $testroot/stdout.expected
490 echo 'EXTRA_DIST =' >> $testroot/stdout.expected
491 echo -n "04) $short_commit1 $d1 $GOT_AUTHOR_8 " \
492 >> $testroot/stdout.expected
493 printf "\tINSTALL\n" >> $testroot/stdout.expected
494 echo -n "05) $short_commit1 $d1 $GOT_AUTHOR_8 " \
495 >> $testroot/stdout.expected
496 printf "\tNOTICE\n" >> $testroot/stdout.expected
497 echo -n "06) $short_commit1 $d1 $GOT_AUTHOR_8 " \
498 >> $testroot/stdout.expected
499 printf "\tREADME\n" >> $testroot/stdout.expected
500 echo -n "07) $short_commit4 $d4 $GOT_AUTHOR_8 " \
501 >> $testroot/stdout.expected
502 printf "\tCOPYING\n" >> $testroot/stdout.expected
503 echo -n "08) $short_commit1 $d1 $GOT_AUTHOR_8 " \
504 >> $testroot/stdout.expected
505 printf "\tcodedocs/doxygen.conf\n" >> $testroot/stdout.expected
506 echo -n "09) $short_commit1 $d1 $GOT_AUTHOR_8 " \
507 >> $testroot/stdout.expected
508 printf "\tcontrib/powerdns.solaris.init.d\n" \
509 >> $testroot/stdout.expected
510 echo -n "10) $short_commit1 $d1 $GOT_AUTHOR_8 " \
511 >> $testroot/stdout.expected
512 printf "\tpdns/named.conf.parsertest\n" >> $testroot/stdout.expected
513 echo -n "11) $short_commit1 $d1 $GOT_AUTHOR_8 " \
514 >> $testroot/stdout.expected
515 printf "\tregression-tests/zones/unit.test\n" \
516 >> $testroot/stdout.expected
517 echo -n "12) $short_commit4 $d4 $GOT_AUTHOR_8 " \
518 >> $testroot/stdout.expected
519 printf "\tbuilder-support/gen-version\n" >> $testroot/stdout.expected
520 echo "13) $short_commit1 $d1 $GOT_AUTHOR_8 " \
521 >> $testroot/stdout.expected
522 echo -n "14) $short_commit1 $d1 $GOT_AUTHOR_8 " \
523 >> $testroot/stdout.expected
524 echo "ACLOCAL_AMFLAGS = -I m4" \
525 >> $testroot/stdout.expected
526 echo "15) $short_commit1 $d1 $GOT_AUTHOR_8 " \
527 >> $testroot/stdout.expected
528 echo -n "16) $short_commit1 $d1 $GOT_AUTHOR_8 " \
529 >> $testroot/stdout.expected
530 echo "dvi: # do nothing to build dvi" \
531 >> $testroot/stdout.expected
533 cmp -s $testroot/stdout.expected $testroot/stdout
535 if [ $ret -ne 0 ]; then
536 diff -u $testroot/stdout.expected $testroot/stdout
537 test_done "$testroot" "$ret"
541 blame_cmp "$testroot" "alpha"
543 test_done "$testroot" "$ret"
546 test_blame_blame_h() {
547 local testroot=`test_init blame_blame_h`
549 got checkout $testroot/repo $testroot/wt > /dev/null
551 if [ $ret -ne 0 ]; then
552 test_done "$testroot" "$ret"
556 cat > $testroot/wt/got_blame.h <<EOF
558 * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
560 * Permission to use, copy, modify, and distribute this software for any
561 * purpose with or without fee is hereby granted, provided that the above
562 * copyright notice and this permission notice appear in all copies.
564 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
565 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
566 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
567 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
568 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
569 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
570 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
573 const struct got_error *got_blame(const char *, struct got_object_id *,
574 struct got_repository *, FILE *);
576 (cd $testroot/wt && got add got_blame.h > /dev/null)
577 (cd $testroot/wt && got commit -m "change 1" > /dev/null)
579 cat > $testroot/wt/blame-2.patch <<EOF
580 diff 63581804340e880bf611c6a4a59eda26c503799f 84451b3ef755f3226d0d79af367632e5f3a830e7
581 blob - b53ca469a18871cc2f6af334dab25028599c6488
582 blob
+ c787aadf05e2afab61bd34976f7349912252e6da
586 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
590 + * Write an annotated version of a
file at a given in-repository path
,
591 + * as found
in the commit specified by ID
, to the specified output
file.
593 const struct got_error
*got_blame
(const char
*, struct got_object_id
*,
594 struct got_repository
*, FILE
*);
597 + * Like got_blame
() but instead of generating an output
file invoke
598 + * a callback whenever an annotation has been computed
for a line.
600 + * The callback receives the provided void
* argument
, the total number
601 + * of lines of the annotated
file, a line number
, and the ID of the commit
602 + * which last changed this line.
604 +const struct got_error
*got_blame_incremental
(const char
*,
605 + struct got_object_id
*, struct got_repository
*,
606 + const struct got_error
*(*cb
)(void
*, int
, int
, struct got_object_id
*),
609 (cd $testroot/wt
&& patch < blame-2.
patch > /dev
/null
)
610 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
612 cat > $testroot/wt
/blame-3.
patch <<EOF
613 diff 75b7a700d9d14ef8eb902961255212acbedef164 d68a0a7de13af722c55099582019c03240e13320
614 blob - c787aadf05e2afab61bd34976f7349912252e6da
615 blob + 5255d076c915accf159940978b821d06803ff2f8
618 @@ -28,6 +28,15 @@ const struct got_error *got_blame(const char *, struct
619 * The callback receives the provided void * argument, the total number
620 * of lines of the annotated file, a line number, and the ID of the commit
621 * which last changed this line.
623 + * The callback is invoked for each commit as history is traversed.
624 + * If no changes to the file were made in a commit, line number -1 and
625 + * commit ID NULL will be reported.
627 + * If the callback returns GOT_ERR_ITER_COMPLETED, the blame operation
628 + * will be aborted and this function returns NULL.
629 + * If the callback returns any other error, the blame operation will be
630 + * aborted and the callback's error is returned from this function.
632 const struct got_error *got_blame_incremental(const char *,
633 struct got_object_id *, struct got_repository *,
635 (cd $testroot/wt
&& patch < blame-3.
patch > /dev
/null
)
636 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
638 cat > $testroot/wt
/blame-4.
patch <<EOF
639 diff 3f60a8ef49086101685260fcb829f578cdf6d320 3bf198ba335fa30c8d16efb5c8e496200ac99c05
640 blob - 5255d076c915accf159940978b821d06803ff2f8
641 blob + 39623c468e733ee08abb50eafe29202b2b0a04ef
644 @@ -30,8 +30,8 @@ const struct got_error *got_blame(const char *, struct
645 * which last changed this line.
647 * The callback is invoked for each commit as history is traversed.
648 - * If no changes to the file were made in a commit, line number -1 and
649 - * commit ID NULL will be reported.
650 + * If no changes to the file were made in a commit, line number -1 will
653 * If the callback returns GOT_ERR_ITER_COMPLETED, the blame operation
654 * will be aborted and this function returns NULL.
656 (cd $testroot/wt
&& patch < blame-4.
patch > /dev
/null
)
657 (cd $testroot/wt
&& got commit
-m "change 4" > /dev
/null
)
659 cat > $testroot/wt
/blame-5.
patch <<EOF
660 diff 28315671b93d195163b0468fcb3879e29b25759c e27a7222faaa171dcb086ea0b566dc7bebb74a0b
661 blob - 39623c468e733ee08abb50eafe29202b2b0a04ef
662 blob + 6075cadbd177e1802679c7353515bf4ceebb51d0
669 - * Write an annotated version of a file at a given in-repository path,
670 - * as found in the commit specified by ID, to the specified output file.
672 -const struct got_error *got_blame(const char *, struct got_object_id *,
673 - struct got_repository *, FILE *);
676 - * Like got_blame() but instead of generating an output file invoke
677 + * Blame the blob at the specified path in the specified commit and invoke
678 * a callback whenever an annotation has been computed for a line.
680 * The callback receives the provided void * argument, the total number
682 (cd $testroot/wt
&& patch < blame-5.
patch > /dev
/null
)
683 (cd $testroot/wt
&& got commit
-m "change 5" > /dev
/null
)
685 blame_cmp
"$testroot" "got_blame.h"
687 test_done
"$testroot" "$ret"
690 test_blame_added_on_branch
() {
691 local testroot
=`test_init blame_added_on_branch`
693 got branch
-r $testroot/repo
-c master newbranch
695 if [ $ret -ne 0 ]; then
696 test_done
"$testroot" "$ret"
700 got checkout
-b newbranch
$testroot/repo
$testroot/wt
> /dev
/null
702 if [ $ret -ne 0 ]; then
703 test_done
"$testroot" "$ret"
707 echo 1 > $testroot/wt
/new
708 (cd $testroot/wt
&& got add new
> /dev
/null
)
709 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
710 local commit1
=`git_show_branch_head $testroot/repo newbranch`
712 echo 2 >> $testroot/wt
/new
713 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
714 local commit2
=`git_show_branch_head $testroot/repo newbranch`
716 echo 3 >> $testroot/wt
/new
717 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
718 local commit3
=`git_show_branch_head $testroot/repo newbranch`
719 local author_time
=`git_show_author_time $testroot/repo`
721 (cd $testroot/wt
&& got blame new
> $testroot/stdout
)
723 local short_commit1
=`trim_obj_id 8 $commit1`
724 local short_commit2
=`trim_obj_id 8 $commit2`
725 local short_commit3
=`trim_obj_id 8 $commit3`
727 d
=`date -u -r $author_time +"%F"`
728 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
729 echo "2) $short_commit2 $d $GOT_AUTHOR_8 2" >> $testroot/stdout.expected
730 echo "3) $short_commit3 $d $GOT_AUTHOR_8 3" >> $testroot/stdout.expected
732 cmp -s $testroot/stdout.expected
$testroot/stdout
734 if [ $ret -ne 0 ]; then
735 diff -u $testroot/stdout.expected
$testroot/stdout
737 test_done
"$testroot" "$ret"
740 test_blame_submodule
() {
741 local testroot
=`test_init blame_submodule`
742 local commit_id0
=`git_show_head $testroot/repo`
743 local author_time
=`git_show_author_time $testroot/repo`
745 make_single_file_repo
$testroot/repo2 foo
747 git
-C $testroot/repo
-c protocol.
file.allow
=always \
748 submodule
-q add ..
/repo2
749 git
-C $testroot/repo commit
-q -m 'adding submodule'
751 # Attempt a (nonsensical) blame of a submodule.
752 got blame
-r $testroot/repo repo2 \
753 > $testroot/stdout
2> $testroot/stderr
755 if [ $ret -eq 0 ]; then
756 echo "blame command succeeded unexpectedly" >&2
757 test_done
"$testroot" "1"
760 local submodule_id
=$
(got tree
-r $testroot/repo
-i | \
761 grep 'repo2\$$' | cut
-d ' ' -f1)
762 echo "got: object $submodule_id not found" > $testroot/stderr.expected
764 cmp -s $testroot/stderr.expected
$testroot/stderr
766 if [ $ret -ne 0 ]; then
767 diff -u $testroot/stderr.expected
$testroot/stderr
769 test_done
"$testroot" "$ret"
772 test_blame_symlink
() {
773 local testroot
=`test_init blame_symlink`
774 local commit_id0
=`git_show_head $testroot/repo`
775 local short_commit0
=`trim_obj_id 8 $commit_id0`
777 (cd $testroot/repo
&& ln -s alpha alpha.link
)
778 (cd $testroot/repo
&& ln -s epsilon epsilon.link
)
779 (cd $testroot/repo
&& ln -s /etc
/passwd passwd.link
)
780 (cd $testroot/repo
&& ln -s ..
/beta epsilon
/beta.link
)
781 (cd $testroot/repo
&& ln -s nonexistent nonexistent.link
)
782 git
-C $testroot/repo add .
783 git_commit
$testroot/repo
-m "add symlinks"
785 local commit_id1
=`git_show_head $testroot/repo`
786 local short_commit1
=`trim_obj_id 8 $commit_id1`
787 local author_time
=`git_show_author_time $testroot/repo`
789 # got blame dereferences symlink to a regular file
790 got blame
-r $testroot/repo alpha.link
> $testroot/stdout
792 if [ $ret -ne 0 ]; then
793 echo "blame command failed unexpectedly" >&2
794 test_done
"$testroot" "$ret"
798 d
=`date -u -r $author_time +"%F"`
799 echo "1) $short_commit0 $d $GOT_AUTHOR_8 alpha" \
800 > $testroot/stdout.expected
802 cmp -s $testroot/stdout.expected
$testroot/stdout
804 if [ $ret -ne 0 -a "$xfail" = "" ]; then
805 diff -u $testroot/stdout.expected
$testroot/stdout
806 test_done
"$testroot" "1"
810 # got blame dereferences symlink with relative path
811 got blame
-r $testroot/repo epsilon
/beta.link
> $testroot/stdout
813 if [ $ret -ne 0 ]; then
814 echo "blame command failed unexpectedly" >&2
815 test_done
"$testroot" "$ret"
819 d
=`date -u -r $author_time +"%F"`
820 echo "1) $short_commit0 $d $GOT_AUTHOR_8 beta" \
821 > $testroot/stdout.expected
823 cmp -s $testroot/stdout.expected
$testroot/stdout
825 if [ $ret -ne 0 -a "$xfail" = "" ]; then
826 diff -u $testroot/stdout.expected
$testroot/stdout
827 test_done
"$testroot" "1"
831 got blame
-r $testroot/repo epsilon.link
> $testroot/stdout \
834 if [ $ret -eq 0 ]; then
835 echo "blame command succeeded unexpectedly" >&2
836 test_done
"$testroot" "1"
840 # blame dereferences symlink to a directory
841 echo "got: /epsilon: wrong type of object" > $testroot/stderr.expected
842 cmp -s $testroot/stderr.expected
$testroot/stderr
844 if [ $ret -ne 0 ]; then
845 diff -u $testroot/stderr.expected
$testroot/stderr
846 test_done
"$testroot" "1"
850 # got blame fails if symlink target does not exist in repo
851 got blame
-r $testroot/repo passwd.link
> $testroot/stdout \
854 if [ $ret -eq 0 ]; then
855 echo "blame command succeeded unexpectedly" >&2
856 test_done
"$testroot" "1"
860 echo "got: /etc/passwd: no such entry found in tree" \
861 > $testroot/stderr.expected
862 cmp -s $testroot/stderr.expected
$testroot/stderr
864 if [ $ret -ne 0 ]; then
865 diff -u $testroot/stderr.expected
$testroot/stderr
866 test_done
"$testroot" "1"
870 got blame
-r $testroot/repo nonexistent.link
> $testroot/stdout \
873 if [ $ret -eq 0 ]; then
874 echo "blame command succeeded unexpectedly" >&2
875 test_done
"$testroot" "1"
879 echo "got: /nonexistent: no such entry found in tree" \
880 > $testroot/stderr.expected
881 cmp -s $testroot/stderr.expected
$testroot/stderr
883 if [ $ret -ne 0 ]; then
884 diff -u $testroot/stderr.expected
$testroot/stderr
885 test_done
"$testroot" "1"
889 test_done
"$testroot" "$ret"
892 test_blame_lines_shifted_skip
() {
893 local testroot
=`test_init blame_lines_shifted_skip`
895 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
897 if [ $ret -ne 0 ]; then
898 test_done
"$testroot" "$ret"
902 cat > $testroot/wt
/alpha
<<EOF
908 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
909 local commit1
=`git_show_head $testroot/repo`
910 local short_commit1
=`trim_obj_id 8 $commit1`
911 local author_time1
=`git_show_author_time $testroot/repo`
913 cat > $testroot/wt
/alpha
<<EOF
921 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
922 local commit2
=`git_show_head $testroot/repo`
923 local short_commit2
=`trim_obj_id 8 $commit2`
924 local author_time2
=`git_show_author_time $testroot/repo`
926 cat > $testroot/wt
/alpha
<<EOF
935 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
936 local commit3
=`git_show_head $testroot/repo`
937 local short_commit3
=`trim_obj_id 8 $commit3`
938 local author_time3
=`git_show_author_time $testroot/repo`
940 cat > $testroot/wt
/alpha
<<EOF
948 (cd $testroot/wt
&& got commit
-m "change 4" > /dev
/null
)
949 local commit4
=`git_show_head $testroot/repo`
950 local short_commit4
=`trim_obj_id 8 $commit4`
951 local author_time4
=`git_show_author_time $testroot/repo`
953 cat > $testroot/wt
/alpha
<<EOF
962 (cd $testroot/wt
&& got commit
-m "change 5" > /dev
/null
)
963 local commit5
=`git_show_head $testroot/repo`
964 local short_commit5
=`trim_obj_id 8 $commit5`
965 local author_time5
=`git_show_author_time $testroot/repo`
967 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
969 d1
=`date -u -r $author_time1 +"%F"`
970 d2
=`date -u -r $author_time2 +"%F"`
971 d4
=`date -u -r $author_time4 +"%F"`
972 d5
=`date -u -r $author_time5 +"%F"`
973 echo "1) $short_commit5 $d5 $GOT_AUTHOR_8 X" > $testroot/stdout.expected
974 echo "2) $short_commit1 $d1 $GOT_AUTHOR_8 A" >> $testroot/stdout.expected
975 echo "3) $short_commit1 $d1 $GOT_AUTHOR_8 B" >> $testroot/stdout.expected
976 echo "4) $short_commit1 $d1 $GOT_AUTHOR_8 C" >> $testroot/stdout.expected
977 echo "5) $short_commit2 $d2 $GOT_AUTHOR_8 P" >> $testroot/stdout.expected
978 echo "6) $short_commit4 $d4 $GOT_AUTHOR_8 Y" >> $testroot/stdout.expected
979 echo "7) $short_commit2 $d5 $GOT_AUTHOR_8 Q" >> $testroot/stdout.expected
981 cmp -s $testroot/stdout.expected
$testroot/stdout
983 if [ $ret -ne 0 ]; then
984 diff -u $testroot/stdout.expected
$testroot/stdout
985 test_done
"$testroot" "$ret"
989 blame_cmp
"$testroot" "alpha"
991 test_done
"$testroot" "$ret"
994 test_blame_commit_keywords
() {
995 local testroot
=$
(test_init blame_commit_keywords
)
996 local repo
="$testroot/repo"
997 local wt
="$testroot/wt"
998 local id
=$
(git_show_head
"$repo")
1000 set -- "$(trim_obj_id 8 $id)"
1002 # :base requires work tree
1003 echo "got: '-c :base' requires work tree" > "$testroot/stderr.expected"
1004 got blame
-r "$repo" -c:base alpha
2> "$testroot/stderr"
1006 if [ $ret -eq 0 ]; then
1007 echo "blame command succeeded unexpectedly" >&2
1008 test_done
"$testroot" "1"
1012 cmp -s "$testroot/stderr.expected" "$testroot/stderr"
1014 if [ $ret -ne 0 ]; then
1015 diff -u "$testroot/stderr.expected" "$testroot/stderr"
1016 test_done
"$testroot" "$ret"
1020 got checkout
"$repo" "$wt" > /dev
/null
1022 if [ $ret -ne 0 ]; then
1023 test_done
"$testroot" "$ret"
1027 echo -n > "$wt/alpha"
1029 for i
in $
(seq 8); do
1030 echo "change $i" >> "$wt/alpha"
1032 (cd "$wt" && got ci
-m "commit $i" > /dev
/null
)
1034 if [ $ret -ne 0 ]; then
1035 echo "commit failed unexpectedly" >&2
1036 test_done
"$testroot" "$ret"
1040 id
=$
(git_show_head
"$repo")
1041 set -- "$@" "$(trim_obj_id 8 $id)"
1044 local author_time
=$
(git_show_author_time
"$repo")
1045 local d
=$
(date -u -r $author_time +"%F")
1047 got blame
-r "$repo" -c:head:-8 alpha
> "$testroot/stdout"
1048 echo "1) $(pop_idx 1 $@) $d $GOT_AUTHOR_8 alpha" > \
1049 "$testroot/stdout.expected"
1051 cmp -s $testroot/stdout.expected
$testroot/stdout
1053 if [ $ret -ne 0 ]; then
1054 diff -u "$testroot/stdout.expected" "$testroot/stdout"
1055 test_done
"$testroot" "$ret"
1059 (cd "$wt" && got blame
-cmaster:-5 alpha
> "$testroot/stdout")
1061 echo "1) $(pop_idx 2 $@) $d $GOT_AUTHOR_8 change 1" > \
1062 "$testroot/stdout.expected"
1063 echo "2) $(pop_idx 3 $@) $d $GOT_AUTHOR_8 change 2" >> \
1064 "$testroot/stdout.expected"
1065 echo "3) $(pop_idx 4 $@) $d $GOT_AUTHOR_8 change 3" >> \
1066 "$testroot/stdout.expected"
1068 cmp -s $testroot/stdout.expected
$testroot/stdout
1070 if [ $ret -ne 0 ]; then
1071 diff -u "$testroot/stdout.expected" "$testroot/stdout"
1072 test_done
"$testroot" "$ret"
1076 (cd "$wt" && got blame
-c:head:-4 alpha
> "$testroot/stdout")
1078 echo "1) $(pop_idx 2 $@) $d $GOT_AUTHOR_8 change 1" > \
1079 "$testroot/stdout.expected"
1080 echo "2) $(pop_idx 3 $@) $d $GOT_AUTHOR_8 change 2" >> \
1081 "$testroot/stdout.expected"
1082 echo "3) $(pop_idx 4 $@) $d $GOT_AUTHOR_8 change 3" >> \
1083 "$testroot/stdout.expected"
1084 echo "4) $(pop_idx 5 $@) $d $GOT_AUTHOR_8 change 4" >> \
1085 "$testroot/stdout.expected"
1087 cmp -s $testroot/stdout.expected
$testroot/stdout
1089 if [ $ret -ne 0 ]; then
1090 diff -u "$testroot/stdout.expected" "$testroot/stdout"
1091 test_done
"$testroot" "$ret"
1095 (cd "$wt" && got up
-c:head:-8 > /dev
/null
)
1096 (cd "$wt" && got blame
-c:base
:+5 alpha
> "$testroot/stdout")
1098 echo "1) $(pop_idx 2 $@) $d $GOT_AUTHOR_8 change 1" > \
1099 "$testroot/stdout.expected"
1100 echo "2) $(pop_idx 3 $@) $d $GOT_AUTHOR_8 change 2" >> \
1101 "$testroot/stdout.expected"
1102 echo "3) $(pop_idx 4 $@) $d $GOT_AUTHOR_8 change 3" >> \
1103 "$testroot/stdout.expected"
1104 echo "4) $(pop_idx 5 $@) $d $GOT_AUTHOR_8 change 4" >> \
1105 "$testroot/stdout.expected"
1106 echo "5) $(pop_idx 6 $@) $d $GOT_AUTHOR_8 change 5" >> \
1107 "$testroot/stdout.expected"
1109 cmp -s $testroot/stdout.expected
$testroot/stdout
1111 if [ $ret -ne 0 ]; then
1112 diff -u "$testroot/stdout.expected" "$testroot/stdout"
1113 test_done
"$testroot" "$ret"
1117 blame_cmp
"$testroot" "alpha"
1119 test_done
"$testroot" "$ret"
1123 run_test test_blame_basic
1124 run_test test_blame_tag
1125 run_test test_blame_file_single_line
1126 run_test test_blame_file_single_line_no_newline
1127 run_test test_blame_all_lines_replaced
1128 run_test test_blame_lines_shifted_up
1129 run_test test_blame_lines_shifted_down
1130 run_test test_blame_commit_subsumed
1131 run_test test_blame_blame_h
1132 run_test test_blame_added_on_branch
1133 run_test test_blame_submodule
1134 run_test test_blame_symlink
1135 run_test test_blame_lines_shifted_skip
1136 run_test test_blame_commit_keywords