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 (cd $testroot/repo
&& git
reset --hard master
> /dev
/null
)
27 (cd $testroot/repo
&& git 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" != "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" != "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 32 $commit1`
65 local short_commit2
=`trim_obj_id 32 $commit2`
66 local short_commit3
=`trim_obj_id 32 $commit3`
68 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
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" != "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" != "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 (cd $testroot/repo
&& git 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 32 $commit1`
114 local short_commit2
=`trim_obj_id 32 $commit2`
116 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
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" != "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" != "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 32 $commit1`
152 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
153 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
155 cmp -s $testroot/stdout.expected
$testroot/stdout
157 if [ "$ret" != "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" != "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 32 $commit1`
187 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
188 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
190 cmp -s $testroot/stdout.expected
$testroot/stdout
192 if [ "$ret" != "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" != "0" ]; then
204 test_done
"$testroot" "$ret"
208 jot 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 32 $commit1`
212 local author_time
=`git_show_author_time $testroot/repo`
214 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
216 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
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" != "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" != "0" ]; then
241 test_done
"$testroot" "$ret"
245 jot 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 32 $commit1`
249 local author_time
=`git_show_author_time $testroot/repo`
251 sed -i -e '/^[345]$/d' $testroot/wt
/alpha
252 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
253 local commit2
=`git_show_head $testroot/repo`
254 local short_commit2
=`trim_obj_id 32 $commit2`
256 jot 2 > $testroot/wt
/alpha
257 echo foo
>> $testroot/wt
/alpha
258 echo bar
>> $testroot/wt
/alpha
259 echo baz
>> $testroot/wt
/alpha
260 jot 8 6 8 1 >> $testroot/wt
/alpha
261 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
262 local commit3
=`git_show_head $testroot/repo`
263 local short_commit3
=`trim_obj_id 32 $commit3`
264 local author_time
=`git_show_author_time $testroot/repo`
266 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
268 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
269 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
270 echo "2) $short_commit1 $d $GOT_AUTHOR_8 2" >> $testroot/stdout.expected
271 echo "3) $short_commit3 $d $GOT_AUTHOR_8 foo" >> $testroot/stdout.expected
272 echo "4) $short_commit3 $d $GOT_AUTHOR_8 bar" >> $testroot/stdout.expected
273 echo "5) $short_commit3 $d $GOT_AUTHOR_8 baz" >> $testroot/stdout.expected
274 echo "6) $short_commit1 $d $GOT_AUTHOR_8 6" >> $testroot/stdout.expected
275 echo "7) $short_commit1 $d $GOT_AUTHOR_8 7" >> $testroot/stdout.expected
276 echo "8) $short_commit1 $d $GOT_AUTHOR_8 8" >> $testroot/stdout.expected
278 cmp -s $testroot/stdout.expected
$testroot/stdout
280 if [ "$ret" != "0" ]; then
281 diff -u $testroot/stdout.expected
$testroot/stdout
282 test_done
"$testroot" "$ret"
286 blame_cmp
"$testroot" "alpha"
288 test_done
"$testroot" "$ret"
291 test_blame_lines_shifted_down
() {
292 local testroot
=`test_init blame_lines_shifted_down`
294 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
296 if [ "$ret" != "0" ]; then
297 test_done
"$testroot" "$ret"
301 jot 8 > $testroot/wt
/alpha
302 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
303 local commit1
=`git_show_head $testroot/repo`
304 local short_commit1
=`trim_obj_id 32 $commit1`
305 local author_time
=`git_show_author_time $testroot/repo`
307 sed -i -e '/^8$/d' $testroot/wt
/alpha
308 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
309 local commit2
=`git_show_head $testroot/repo`
310 local short_commit2
=`trim_obj_id 32 $commit2`
312 jot 2 > $testroot/wt
/alpha
313 echo foo
>> $testroot/wt
/alpha
314 echo bar
>> $testroot/wt
/alpha
315 echo baz
>> $testroot/wt
/alpha
316 jot 8 3 8 1 >> $testroot/wt
/alpha
317 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
318 local commit3
=`git_show_head $testroot/repo`
319 local short_commit3
=`trim_obj_id 32 $commit3`
320 local author_time
=`git_show_author_time $testroot/repo`
322 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
324 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
325 echo "01) $short_commit1 $d $GOT_AUTHOR_8 1" \
326 > $testroot/stdout.expected
327 echo "02) $short_commit1 $d $GOT_AUTHOR_8 2" \
328 >> $testroot/stdout.expected
329 echo "03) $short_commit3 $d $GOT_AUTHOR_8 foo" \
330 >> $testroot/stdout.expected
331 echo "04) $short_commit3 $d $GOT_AUTHOR_8 bar" \
332 >> $testroot/stdout.expected
333 echo "05) $short_commit3 $d $GOT_AUTHOR_8 baz" \
334 >> $testroot/stdout.expected
335 echo "06) $short_commit1 $d $GOT_AUTHOR_8 3" \
336 >> $testroot/stdout.expected
337 echo "07) $short_commit1 $d $GOT_AUTHOR_8 4" \
338 >> $testroot/stdout.expected
339 echo "08) $short_commit1 $d $GOT_AUTHOR_8 5" \
340 >> $testroot/stdout.expected
341 echo "09) $short_commit1 $d $GOT_AUTHOR_8 6" \
342 >> $testroot/stdout.expected
343 echo "10) $short_commit1 $d $GOT_AUTHOR_8 7" \
344 >> $testroot/stdout.expected
345 echo "11) $short_commit3 $d $GOT_AUTHOR_8 8" \
346 >> $testroot/stdout.expected
348 cmp -s $testroot/stdout.expected
$testroot/stdout
350 if [ "$ret" != "0" ]; then
351 diff -u $testroot/stdout.expected
$testroot/stdout
352 test_done
"$testroot" "$ret"
356 blame_cmp
"$testroot" "alpha"
358 test_done
"$testroot" "$ret"
361 test_blame_commit_subsumed
() {
362 local testroot
=`test_init blame_commit_subsumed`
364 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
366 if [ "$ret" != "0" ]; then
367 test_done
"$testroot" "$ret"
371 cat > $testroot/wt
/alpha
<<EOF
372 SUBDIRS = ext modules codedocs docs
383 build-aux/gen-version
384 codedocs/doxygen.conf
385 contrib/powerdns.solaris.init.d
386 pdns/named.conf.parsertest
387 regression-tests/zones/unit.test
389 ACLOCAL_AMFLAGS = -I m4
391 dvi: # do nothing to build dvi
393 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
394 local commit1
=`git_show_head $testroot/repo`
395 local short_commit1
=`trim_obj_id 32 $commit1`
396 local author_time1
=`git_show_author_time $testroot/repo`
397 local d1
=`date -u -d "@$author_time1" +"%G-%m-%d"`
399 cat > $testroot/wt
/alpha
<<EOF
400 SUBDIRS = ext modules codedocs docs
409 build-aux/gen-version
410 codedocs/doxygen.conf
411 contrib/powerdns.solaris.init.d
412 pdns/named.conf.parsertest
413 regression-tests/zones/unit.test
415 ACLOCAL_AMFLAGS = -I m4
417 dvi: # do nothing to build dvi
419 # all changes in this commit will be subsumed by later commits
420 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
421 local commit2
=`git_show_head $testroot/repo`
422 local short_commit2
=`trim_obj_id 32 $commit2`
423 local author_time2
=`git_show_author_time $testroot/repo`
424 local d2
=`date -u -d "@$author_time2" +"%G-%m-%d"`
426 cat > $testroot/wt
/alpha
<<EOF
427 SUBDIRS = ext modules pdns codedocs docs
434 build-aux/gen-version
435 codedocs/doxygen.conf
436 contrib/powerdns.solaris.init.d
437 pdns/named.conf.parsertest
438 regression-tests/zones/unit.test
440 ACLOCAL_AMFLAGS = -I m4
442 dvi: # do nothing to build dvi
444 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
445 local commit3
=`git_show_head $testroot/repo`
446 local short_commit3
=`trim_obj_id 32 $commit3`
447 local author_time3
=`git_show_author_time $testroot/repo`
448 local d3
=`date -u -d "@$author_time3" +"%G-%m-%d"`
450 cat > $testroot/wt
/alpha
<<EOF
451 SUBDIRS = ext modules pdns codedocs docs
458 codedocs/doxygen.conf
459 contrib/powerdns.solaris.init.d
460 pdns/named.conf.parsertest
461 regression-tests/zones/unit.test
462 builder-support/gen-version
464 ACLOCAL_AMFLAGS = -I m4
466 dvi: # do nothing to build dvi
468 (cd $testroot/wt
&& got commit
-m "change 4" > /dev
/null
)
469 local commit4
=`git_show_head $testroot/repo`
470 local short_commit4
=`trim_obj_id 32 $commit4`
471 local author_time4
=`git_show_author_time $testroot/repo`
472 local d4
=`date -u -d "@$author_time4" +"%G-%m-%d"`
474 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
476 echo -n "01) $short_commit3 $d3 $GOT_AUTHOR_8 " \
477 > $testroot/stdout.expected
478 echo "SUBDIRS = ext modules pdns codedocs docs" \
479 >> $testroot/stdout.expected
480 echo "02) $short_commit1 $d1 $GOT_AUTHOR_8 " \
481 >> $testroot/stdout.expected
482 echo -n "03) $short_commit1 $d1 $GOT_AUTHOR_8 " \
483 >> $testroot/stdout.expected
484 echo 'EXTRA_DIST =' >> $testroot/stdout.expected
485 echo -n "04) $short_commit1 $d1 $GOT_AUTHOR_8 " \
486 >> $testroot/stdout.expected
487 printf "\tINSTALL\n" >> $testroot/stdout.expected
488 echo -n "05) $short_commit1 $d1 $GOT_AUTHOR_8 " \
489 >> $testroot/stdout.expected
490 printf "\tNOTICE\n" >> $testroot/stdout.expected
491 echo -n "06) $short_commit1 $d1 $GOT_AUTHOR_8 " \
492 >> $testroot/stdout.expected
493 printf "\tREADME\n" >> $testroot/stdout.expected
494 echo -n "07) $short_commit4 $d4 $GOT_AUTHOR_8 " \
495 >> $testroot/stdout.expected
496 printf "\tCOPYING\n" >> $testroot/stdout.expected
497 echo -n "08) $short_commit1 $d1 $GOT_AUTHOR_8 " \
498 >> $testroot/stdout.expected
499 printf "\tcodedocs/doxygen.conf\n" >> $testroot/stdout.expected
500 echo -n "09) $short_commit1 $d1 $GOT_AUTHOR_8 " \
501 >> $testroot/stdout.expected
502 printf "\tcontrib/powerdns.solaris.init.d\n" \
503 >> $testroot/stdout.expected
504 echo -n "10) $short_commit1 $d1 $GOT_AUTHOR_8 " \
505 >> $testroot/stdout.expected
506 printf "\tpdns/named.conf.parsertest\n" >> $testroot/stdout.expected
507 echo -n "11) $short_commit1 $d1 $GOT_AUTHOR_8 " \
508 >> $testroot/stdout.expected
509 printf "\tregression-tests/zones/unit.test\n" \
510 >> $testroot/stdout.expected
511 echo -n "12) $short_commit4 $d4 $GOT_AUTHOR_8 " \
512 >> $testroot/stdout.expected
513 printf "\tbuilder-support/gen-version\n" >> $testroot/stdout.expected
514 echo "13) $short_commit1 $d1 $GOT_AUTHOR_8 " \
515 >> $testroot/stdout.expected
516 echo -n "14) $short_commit1 $d1 $GOT_AUTHOR_8 " \
517 >> $testroot/stdout.expected
518 echo "ACLOCAL_AMFLAGS = -I m4" \
519 >> $testroot/stdout.expected
520 echo "15) $short_commit1 $d1 $GOT_AUTHOR_8 " \
521 >> $testroot/stdout.expected
522 echo -n "16) $short_commit1 $d1 $GOT_AUTHOR_8 " \
523 >> $testroot/stdout.expected
524 echo "dvi: # do nothing to build dvi" \
525 >> $testroot/stdout.expected
527 cmp -s $testroot/stdout.expected
$testroot/stdout
529 if [ "$ret" != "0" ]; then
530 diff -u $testroot/stdout.expected
$testroot/stdout
531 test_done
"$testroot" "$ret"
535 blame_cmp
"$testroot" "alpha"
537 test_done
"$testroot" "$ret"
540 test_blame_blame_h
() {
541 local testroot
=`test_init blame_blame_h`
543 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
545 if [ "$ret" != "0" ]; then
546 test_done
"$testroot" "$ret"
550 cat > $testroot/wt
/got_blame.h
<<EOF
552 * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
554 * Permission to use, copy, modify, and distribute this software for any
555 * purpose with or without fee is hereby granted, provided that the above
556 * copyright notice and this permission notice appear in all copies.
558 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
559 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
560 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
561 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
562 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
563 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
564 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
567 const struct got_error *got_blame(const char *, struct got_object_id *,
568 struct got_repository *, FILE *);
570 (cd $testroot/wt
&& got add got_blame.h
> /dev
/null
)
571 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
573 cat > $testroot/wt
/blame-2.
patch <<EOF
574 diff 63581804340e880bf611c6a4a59eda26c503799f 84451b3ef755f3226d0d79af367632e5f3a830e7
575 blob - b53ca469a18871cc2f6af334dab25028599c6488
576 blob + c787aadf05e2afab61bd34976f7349912252e6da
580 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
584 + * Write an annotated version of a file at a given in-repository path,
585 + * as found in the commit specified by ID, to the specified output file.
587 const struct got_error *got_blame(const char *, struct got_object_id *,
588 struct got_repository *, FILE *);
591 + * Like got_blame() but instead of generating an output file invoke
592 + * a callback whenever an annotation has been computed for a line.
594 + * The callback receives the provided void * argument, the total number
595 + * of lines of the annotated file, a line number, and the ID of the commit
596 + * which last changed this line.
598 +const struct got_error *got_blame_incremental(const char *,
599 + struct got_object_id *, struct got_repository *,
600 + const struct got_error *(*cb)(void *, int, int, struct got_object_id *),
603 (cd $testroot/wt
&& patch < blame-2.
patch > /dev
/null
)
604 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
606 cat > $testroot/wt
/blame-3.
patch <<EOF
607 diff 75b7a700d9d14ef8eb902961255212acbedef164 d68a0a7de13af722c55099582019c03240e13320
608 blob - c787aadf05e2afab61bd34976f7349912252e6da
609 blob + 5255d076c915accf159940978b821d06803ff2f8
612 @@ -28,6 +28,15 @@ const struct got_error *got_blame(const char *, struct
613 * The callback receives the provided void * argument, the total number
614 * of lines of the annotated file, a line number, and the ID of the commit
615 * which last changed this line.
617 + * The callback is invoked for each commit as history is traversed.
618 + * If no changes to the file were made in a commit, line number -1 and
619 + * commit ID NULL will be reported.
621 + * If the callback returns GOT_ERR_ITER_COMPLETED, the blame operation
622 + * will be aborted and this function returns NULL.
623 + * If the callback returns any other error, the blame operation will be
624 + * aborted and the callback's error is returned from this function.
626 const struct got_error *got_blame_incremental(const char *,
627 struct got_object_id *, struct got_repository *,
629 (cd $testroot/wt
&& patch < blame-3.
patch > /dev
/null
)
630 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
632 cat > $testroot/wt
/blame-4.
patch <<EOF
633 diff 3f60a8ef49086101685260fcb829f578cdf6d320 3bf198ba335fa30c8d16efb5c8e496200ac99c05
634 blob - 5255d076c915accf159940978b821d06803ff2f8
635 blob + 39623c468e733ee08abb50eafe29202b2b0a04ef
638 @@ -30,8 +30,8 @@ const struct got_error *got_blame(const char *, struct
639 * which last changed this line.
641 * The callback is invoked for each commit as history is traversed.
642 - * If no changes to the file were made in a commit, line number -1 and
643 - * commit ID NULL will be reported.
644 + * If no changes to the file were made in a commit, line number -1 will
647 * If the callback returns GOT_ERR_ITER_COMPLETED, the blame operation
648 * will be aborted and this function returns NULL.
650 (cd $testroot/wt
&& patch < blame-4.
patch > /dev
/null
)
651 (cd $testroot/wt
&& got commit
-m "change 4" > /dev
/null
)
653 cat > $testroot/wt
/blame-5.
patch <<EOF
654 diff 28315671b93d195163b0468fcb3879e29b25759c e27a7222faaa171dcb086ea0b566dc7bebb74a0b
655 blob - 39623c468e733ee08abb50eafe29202b2b0a04ef
656 blob + 6075cadbd177e1802679c7353515bf4ceebb51d0
663 - * Write an annotated version of a file at a given in-repository path,
664 - * as found in the commit specified by ID, to the specified output file.
666 -const struct got_error *got_blame(const char *, struct got_object_id *,
667 - struct got_repository *, FILE *);
670 - * Like got_blame() but instead of generating an output file invoke
671 + * Blame the blob at the specified path in the specified commit and invoke
672 * a callback whenever an annotation has been computed for a line.
674 * The callback receives the provided void * argument, the total number
676 (cd $testroot/wt
&& patch < blame-5.
patch > /dev
/null
)
677 (cd $testroot/wt
&& got commit
-m "change 5" > /dev
/null
)
679 blame_cmp
"$testroot" "got_blame.h"
681 test_done
"$testroot" "$ret"
684 test_blame_added_on_branch
() {
685 local testroot
=`test_init blame_added_on_branch`
687 got branch
-r $testroot/repo
-c master newbranch
689 if [ "$ret" != "0" ]; then
690 test_done
"$testroot" "$ret"
694 got checkout
-b newbranch
$testroot/repo
$testroot/wt
> /dev
/null
696 if [ "$ret" != "0" ]; then
697 test_done
"$testroot" "$ret"
701 echo 1 > $testroot/wt
/new
702 (cd $testroot/wt
&& got add new
> /dev
/null
)
703 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
704 local commit1
=`git_show_branch_head $testroot/repo newbranch`
706 echo 2 >> $testroot/wt
/new
707 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
708 local commit2
=`git_show_branch_head $testroot/repo newbranch`
710 echo 3 >> $testroot/wt
/new
711 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
712 local commit3
=`git_show_branch_head $testroot/repo newbranch`
713 local author_time
=`git_show_author_time $testroot/repo`
715 (cd $testroot/wt
&& got blame new
> $testroot/stdout
)
717 local short_commit1
=`trim_obj_id 32 $commit1`
718 local short_commit2
=`trim_obj_id 32 $commit2`
719 local short_commit3
=`trim_obj_id 32 $commit3`
721 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
722 echo "1) $short_commit1 $d $GOT_AUTHOR_8 1" > $testroot/stdout.expected
723 echo "2) $short_commit2 $d $GOT_AUTHOR_8 2" >> $testroot/stdout.expected
724 echo "3) $short_commit3 $d $GOT_AUTHOR_8 3" >> $testroot/stdout.expected
726 cmp -s $testroot/stdout.expected
$testroot/stdout
728 if [ "$ret" != "0" ]; then
729 diff -u $testroot/stdout.expected
$testroot/stdout
731 test_done
"$testroot" "$ret"
734 test_blame_submodule
() {
735 local testroot
=`test_init blame_submodule`
736 local commit_id0
=`git_show_head $testroot/repo`
737 local author_time
=`git_show_author_time $testroot/repo`
739 make_single_file_repo
$testroot/repo2 foo
741 (cd $testroot/repo
&& git submodule
-q add ..
/repo2
)
742 (cd $testroot/repo
&& git commit
-q -m 'adding submodule')
744 # Attempt a (nonsensical) blame of a submodule.
745 got blame
-r $testroot/repo repo2 \
746 > $testroot/stdout
2> $testroot/stderr
748 if [ "$ret" = "0" ]; then
749 echo "blame command succeeded unexpectedly" >&2
750 test_done
"$testroot" "1"
753 local submodule_id
=$
(got tree
-r $testroot/repo
-i | \
754 grep 'repo2\$$' | cut
-d ' ' -f1)
755 echo "got: object $submodule_id not found" > $testroot/stderr.expected
757 cmp -s $testroot/stderr.expected
$testroot/stderr
759 if [ "$ret" != "0" ]; then
760 diff -u $testroot/stderr.expected
$testroot/stderr
762 test_done
"$testroot" "$ret"
765 test_blame_symlink
() {
766 local testroot
=`test_init blame_symlink`
767 local commit_id0
=`git_show_head $testroot/repo`
768 local short_commit0
=`trim_obj_id 32 $commit_id0`
770 (cd $testroot/repo
&& ln -s alpha alpha.link
)
771 (cd $testroot/repo
&& ln -s epsilon epsilon.link
)
772 (cd $testroot/repo
&& ln -s /etc
/passwd passwd.link
)
773 (cd $testroot/repo
&& ln -s ..
/beta epsilon
/beta.link
)
774 (cd $testroot/repo
&& ln -s nonexistent nonexistent.link
)
775 (cd $testroot/repo
&& git add .
)
776 git_commit
$testroot/repo
-m "add symlinks"
778 local commit_id1
=`git_show_head $testroot/repo`
779 local short_commit1
=`trim_obj_id 32 $commit_id1`
780 local author_time
=`git_show_author_time $testroot/repo`
782 # got blame dereferences symlink to a regular file
783 got blame
-r $testroot/repo alpha.link
> $testroot/stdout
785 if [ "$ret" != "0" ]; then
786 echo "blame command failed unexpectedly" >&2
787 test_done
"$testroot" "$ret"
791 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
792 echo "1) $short_commit0 $d $GOT_AUTHOR_8 alpha" \
793 > $testroot/stdout.expected
795 cmp -s $testroot/stdout.expected
$testroot/stdout
797 if [ "$ret" != "0" -a "$xfail" = "" ]; then
798 diff -u $testroot/stdout.expected
$testroot/stdout
799 test_done
"$testroot" "1"
803 # got blame dereferences symlink with relative path
804 got blame
-r $testroot/repo epsilon
/beta.link
> $testroot/stdout
806 if [ "$ret" != "0" ]; then
807 echo "blame command failed unexpectedly" >&2
808 test_done
"$testroot" "$ret"
812 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
813 echo "1) $short_commit0 $d $GOT_AUTHOR_8 beta" \
814 > $testroot/stdout.expected
816 cmp -s $testroot/stdout.expected
$testroot/stdout
818 if [ "$ret" != "0" -a "$xfail" = "" ]; then
819 diff -u $testroot/stdout.expected
$testroot/stdout
820 test_done
"$testroot" "1"
824 got blame
-r $testroot/repo epsilon.link
> $testroot/stdout \
827 if [ "$ret" = "0" ]; then
828 echo "blame command succeeded unexpectedly" >&2
829 test_done
"$testroot" "1"
833 # blame dereferences symlink to a directory
834 echo "got: /epsilon: wrong type of object" > $testroot/stderr.expected
835 cmp -s $testroot/stderr.expected
$testroot/stderr
837 if [ "$ret" != "0" ]; then
838 diff -u $testroot/stderr.expected
$testroot/stderr
839 test_done
"$testroot" "1"
843 # got blame fails if symlink target does not exist in repo
844 got blame
-r $testroot/repo passwd.link
> $testroot/stdout \
847 if [ "$ret" = "0" ]; then
848 echo "blame command succeeded unexpectedly" >&2
849 test_done
"$testroot" "$ret"
853 echo "got: /etc/passwd: no such entry found in tree" \
854 > $testroot/stderr.expected
855 cmp -s $testroot/stderr.expected
$testroot/stderr
857 if [ "$ret" != "0" ]; then
858 diff -u $testroot/stderr.expected
$testroot/stderr
859 test_done
"$testroot" "1"
863 got blame
-r $testroot/repo nonexistent.link
> $testroot/stdout \
866 if [ "$ret" = "0" ]; then
867 echo "blame command succeeded unexpectedly" >&2
868 test_done
"$testroot" "$ret"
872 echo "got: /nonexistent: no such entry found in tree" \
873 > $testroot/stderr.expected
874 cmp -s $testroot/stderr.expected
$testroot/stderr
876 if [ "$ret" != "0" ]; then
877 diff -u $testroot/stderr.expected
$testroot/stderr
878 test_done
"$testroot" "1"
882 test_done
"$testroot" "$ret"
885 test_blame_lines_shifted_skip
() {
886 local testroot
=`test_init blame_lines_shifted_skip`
888 got checkout
$testroot/repo
$testroot/wt
> /dev
/null
890 if [ "$ret" != "0" ]; then
891 test_done
"$testroot" "$ret"
895 cat > $testroot/wt
/alpha
<<EOF
901 (cd $testroot/wt
&& got commit
-m "change 1" > /dev
/null
)
902 local commit1
=`git_show_head $testroot/repo`
903 local short_commit1
=`trim_obj_id 32 $commit1`
904 local author_time
=`git_show_author_time $testroot/repo`
906 cat > $testroot/wt
/alpha
<<EOF
914 (cd $testroot/wt
&& got commit
-m "change 2" > /dev
/null
)
915 local commit2
=`git_show_head $testroot/repo`
916 local short_commit2
=`trim_obj_id 32 $commit2`
918 cat > $testroot/wt
/alpha
<<EOF
927 (cd $testroot/wt
&& got commit
-m "change 3" > /dev
/null
)
928 local commit3
=`git_show_head $testroot/repo`
929 local short_commit3
=`trim_obj_id 32 $commit3`
930 local author_time
=`git_show_author_time $testroot/repo`
932 cat > $testroot/wt
/alpha
<<EOF
940 (cd $testroot/wt
&& got commit
-m "change 4" > /dev
/null
)
941 local commit4
=`git_show_head $testroot/repo`
942 local short_commit4
=`trim_obj_id 32 $commit4`
943 local author_time
=`git_show_author_time $testroot/repo`
945 cat > $testroot/wt
/alpha
<<EOF
954 (cd $testroot/wt
&& got commit
-m "change 5" > /dev
/null
)
955 local commit5
=`git_show_head $testroot/repo`
956 local short_commit5
=`trim_obj_id 32 $commit5`
957 local author_time
=`git_show_author_time $testroot/repo`
959 (cd $testroot/wt
&& got blame alpha
> $testroot/stdout
)
961 d
=`date -u -d "@$author_time" +"%G-%m-%d"`
962 echo "1) $short_commit5 $d $GOT_AUTHOR_8 X" > $testroot/stdout.expected
963 echo "2) $short_commit1 $d $GOT_AUTHOR_8 A" >> $testroot/stdout.expected
964 echo "3) $short_commit1 $d $GOT_AUTHOR_8 B" >> $testroot/stdout.expected
965 echo "4) $short_commit1 $d $GOT_AUTHOR_8 C" >> $testroot/stdout.expected
966 echo "5) $short_commit2 $d $GOT_AUTHOR_8 P" >> $testroot/stdout.expected
967 echo "6) $short_commit4 $d $GOT_AUTHOR_8 Y" >> $testroot/stdout.expected
968 echo "7) $short_commit2 $d $GOT_AUTHOR_8 Q" >> $testroot/stdout.expected
970 cmp -s $testroot/stdout.expected
$testroot/stdout
972 if [ "$ret" != "0" ]; then
973 diff -u $testroot/stdout.expected
$testroot/stdout
974 test_done
"$testroot" "$ret"
978 blame_cmp
"$testroot" "alpha"
980 test_done
"$testroot" "$ret"
984 run_test test_blame_basic
985 run_test test_blame_tag
986 run_test test_blame_file_single_line
987 run_test test_blame_file_single_line_no_newline
988 run_test test_blame_all_lines_replaced
989 run_test test_blame_lines_shifted_up
990 run_test test_blame_lines_shifted_down
991 run_test test_blame_commit_subsumed
992 run_test test_blame_blame_h
993 run_test test_blame_added_on_branch
994 run_test test_blame_submodule
995 run_test test_blame_symlink
996 run_test test_blame_lines_shifted_skip