blame: move scoreboard-related methods to libgit
Signed-off-by: Jeff Smith <whydoubt@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff Smith committed
May 24, 2017 at 00:15 UTC
b543bb1cdfc9b61b262a848f936c326f4b060a6c
3 files changed
+1324
-1318
blame.c
+1313
@@ -1,6 +1,9 @@
1
#include "cache.h"
2
#include "refs.h"
3
#include "cache-tree.h"
4
+#include "mergesort.h"
5
+#include "diff.h"
6
+#include "diffcore.h"
7
#include "blame.h"
8
9
void blame_origin_decref(struct blame_origin *o)
@@ -261,3 +264,1313 @@ struct commit *fake_working_tree_commit(struct diff_options *opt,
264
265
return commit;
266
}
267
+
268
+
269
+
270
+static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
271
+ xdl_emit_hunk_consume_func_t hunk_func, void *cb_data, int xdl_opts)
272
+{
273
+ xpparam_t xpp = {0};
274
+ xdemitconf_t xecfg = {0};
275
+ xdemitcb_t ecb = {NULL};
276
+
277
+ xpp.flags = xdl_opts;
278
+ xecfg.hunk_func = hunk_func;
279
+ ecb.priv = cb_data;
280
+ return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
281
+}
282
+
283
+/*
284
+ * Given an origin, prepare mmfile_t structure to be used by the
285
+ * diff machinery
286
+ */
287
+static void fill_origin_blob(struct diff_options *opt,
288
+ struct blame_origin *o, mmfile_t *file, int *num_read_blob)
289
+{
290
+ if (!o->file.ptr) {
291
+ enum object_type type;
292
+ unsigned long file_size;
293
+
294
+ (*num_read_blob)++;
295
+ if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
296
+ textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size))
297
+ ;
298
+ else
299
+ file->ptr = read_sha1_file(o->blob_oid.hash, &type,
300
+ &file_size);
301
+ file->size = file_size;
302
+
303
+ if (!file->ptr)
304
+ die("Cannot read blob %s for path %s",
305
+ oid_to_hex(&o->blob_oid),
306
+ o->path);
307
+ o->file = *file;
308
+ }
309
+ else
310
+ *file = o->file;
311
+}
312
+
313
+static void drop_origin_blob(struct blame_origin *o)
314
+{
315
+ if (o->file.ptr) {
316
+ free(o->file.ptr);
317
+ o->file.ptr = NULL;
318
+ }
319
+}
320
+
321
+/*
322
+ * Any merge of blames happens on lists of blames that arrived via
323
+ * different parents in a single suspect. In this case, we want to
324
+ * sort according to the suspect line numbers as opposed to the final
325
+ * image line numbers. The function body is somewhat longish because
326
+ * it avoids unnecessary writes.
327
+ */
328
+
329
+static struct blame_entry *blame_merge(struct blame_entry *list1,
330
+ struct blame_entry *list2)
331
+{
332
+ struct blame_entry *p1 = list1, *p2 = list2,
333
+ **tail = &list1;
334
+
335
+ if (!p1)
336
+ return p2;
337
+ if (!p2)
338
+ return p1;
339
+
340
+ if (p1->s_lno <= p2->s_lno) {
341
+ do {
342
+ tail = &p1->next;
343
+ if ((p1 = *tail) == NULL) {
344
+ *tail = p2;
345
+ return list1;
346
+ }
347
+ } while (p1->s_lno <= p2->s_lno);
348
+ }
349
+ for (;;) {
350
+ *tail = p2;
351
+ do {
352
+ tail = &p2->next;
353
+ if ((p2 = *tail) == NULL) {
354
+ *tail = p1;
355
+ return list1;
356
+ }
357
+ } while (p1->s_lno > p2->s_lno);
358
+ *tail = p1;
359
+ do {
360
+ tail = &p1->next;
361
+ if ((p1 = *tail) == NULL) {
362
+ *tail = p2;
363
+ return list1;
364
+ }
365
+ } while (p1->s_lno <= p2->s_lno);
366
+ }
367
+}
368
+
369
+static void *get_next_blame(const void *p)
370
+{
371
+ return ((struct blame_entry *)p)->next;
372
+}
373
+
374
+static void set_next_blame(void *p1, void *p2)
375
+{
376
+ ((struct blame_entry *)p1)->next = p2;
377
+}
378
+
379
+/*
380
+ * Final image line numbers are all different, so we don't need a
381
+ * three-way comparison here.
382
+ */
383
+
384
+static int compare_blame_final(const void *p1, const void *p2)
385
+{
386
+ return ((struct blame_entry *)p1)->lno > ((struct blame_entry *)p2)->lno
387
+ ? 1 : -1;
388
+}
389
+
390
+static int compare_blame_suspect(const void *p1, const void *p2)
391
+{
392
+ const struct blame_entry *s1 = p1, *s2 = p2;
393
+ /*
394
+ * to allow for collating suspects, we sort according to the
395
+ * respective pointer value as the primary sorting criterion.
396
+ * The actual relation is pretty unimportant as long as it
397
+ * establishes a total order. Comparing as integers gives us
398
+ * that.
399
+ */
400
+ if (s1->suspect != s2->suspect)
401
+ return (intptr_t)s1->suspect > (intptr_t)s2->suspect ? 1 : -1;
402
+ if (s1->s_lno == s2->s_lno)
403
+ return 0;
404
+ return s1->s_lno > s2->s_lno ? 1 : -1;
405
+}
406
+
407
+void blame_sort_final(struct blame_scoreboard *sb)
408
+{
409
+ sb->ent = llist_mergesort(sb->ent, get_next_blame, set_next_blame,
410
+ compare_blame_final);
411
+}
412
+
413
+/*
414
+ * For debugging -- origin is refcounted, and this asserts that
415
+ * we do not underflow.
416
+ */
417
+static void sanity_check_refcnt(struct blame_scoreboard *sb)
418
+{
419
+ int baa = 0;
420
+ struct blame_entry *ent;
421
+
422
+ for (ent = sb->ent; ent; ent = ent->next) {
423
+ /* Nobody should have zero or negative refcnt */
424
+ if (ent->suspect->refcnt <= 0) {
425
+ fprintf(stderr, "%s in %s has negative refcnt %d\n",
426
+ ent->suspect->path,
427
+ oid_to_hex(&ent->suspect->commit->object.oid),
428
+ ent->suspect->refcnt);
429
+ baa = 1;
430
+ }
431
+ }
432
+ if (baa)
433
+ sb->on_sanity_fail(sb, baa);
434
+}
435
+
436
+/*
437
+ * If two blame entries that are next to each other came from
438
+ * contiguous lines in the same origin (i.e. <commit, path> pair),
439
+ * merge them together.
440
+ */
441
+void blame_coalesce(struct blame_scoreboard *sb)
442
+{
443
+ struct blame_entry *ent, *next;
444
+
445
+ for (ent = sb->ent; ent && (next = ent->next); ent = next) {
446
+ if (ent->suspect == next->suspect &&
447
+ ent->s_lno + ent->num_lines == next->s_lno) {
448
+ ent->num_lines += next->num_lines;
449
+ ent->next = next->next;
450
+ blame_origin_decref(next->suspect);
451
+ free(next);
452
+ ent->score = 0;
453
+ next = ent; /* again */
454
+ }
455
+ }
456
+
457
+ if (sb->debug) /* sanity */
458
+ sanity_check_refcnt(sb);
459
+}
460
+
461
+/*
462
+ * Merge the given sorted list of blames into a preexisting origin.
463
+ * If there were no previous blames to that commit, it is entered into
464
+ * the commit priority queue of the score board.
465
+ */
466
+
467
+static void queue_blames(struct blame_scoreboard *sb, struct blame_origin *porigin,
468
+ struct blame_entry *sorted)
469
+{
470
+ if (porigin->suspects)
471
+ porigin->suspects = blame_merge(porigin->suspects, sorted);
472
+ else {
473
+ struct blame_origin *o;
474
+ for (o = porigin->commit->util; o; o = o->next) {
475
+ if (o->suspects) {
476
+ porigin->suspects = sorted;
477
+ return;
478
+ }
479
+ }
480
+ porigin->suspects = sorted;
481
+ prio_queue_put(&sb->commits, porigin->commit);
482
+ }
483
+}
484
+
485
+/*
486
+ * We have an origin -- check if the same path exists in the
487
+ * parent and return an origin structure to represent it.
488
+ */
489
+static struct blame_origin *find_origin(struct commit *parent,
490
+ struct blame_origin *origin)
491
+{
492
+ struct blame_origin *porigin;
493
+ struct diff_options diff_opts;
494
+ const char *paths[2];
495
+
496
+ /* First check any existing origins */
497
+ for (porigin = parent->util; porigin; porigin = porigin->next)
498
+ if (!strcmp(porigin->path, origin->path)) {
499
+ /*
500
+ * The same path between origin and its parent
501
+ * without renaming -- the most common case.
502
+ */
503
+ return blame_origin_incref (porigin);
504
+ }
505
+
506
+ /* See if the origin->path is different between parent
507
+ * and origin first. Most of the time they are the
508
+ * same and diff-tree is fairly efficient about this.
509
+ */
510
+ diff_setup(&diff_opts);
511
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
512
+ diff_opts.detect_rename = 0;
513
+ diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
514
+ paths[0] = origin->path;
515
+ paths[1] = NULL;
516
+
517
+ parse_pathspec(&diff_opts.pathspec,
518
+ PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
519
+ PATHSPEC_LITERAL_PATH, "", paths);
520
+ diff_setup_done(&diff_opts);
521
+
522
+ if (is_null_oid(&origin->commit->object.oid))
523
+ do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
524
+ else
525
+ diff_tree_sha1(parent->tree->object.oid.hash,
526
+ origin->commit->tree->object.oid.hash,
527
+ "", &diff_opts);
528
+ diffcore_std(&diff_opts);
529
+
530
+ if (!diff_queued_diff.nr) {
531
+ /* The path is the same as parent */
532
+ porigin = get_origin(parent, origin->path);
533
+ oidcpy(&porigin->blob_oid, &origin->blob_oid);
534
+ porigin->mode = origin->mode;
535
+ } else {
536
+ /*
537
+ * Since origin->path is a pathspec, if the parent
538
+ * commit had it as a directory, we will see a whole
539
+ * bunch of deletion of files in the directory that we
540
+ * do not care about.
541
+ */
542
+ int i;
543
+ struct diff_filepair *p = NULL;
544
+ for (i = 0; i < diff_queued_diff.nr; i++) {
545
+ const char *name;
546
+ p = diff_queued_diff.queue[i];
547
+ name = p->one->path ? p->one->path : p->two->path;
548
+ if (!strcmp(name, origin->path))
549
+ break;
550
+ }
551
+ if (!p)
552
+ die("internal error in blame::find_origin");
553
+ switch (p->status) {
554
+ default:
555
+ die("internal error in blame::find_origin (%c)",
556
+ p->status);
557
+ case 'M':
558
+ porigin = get_origin(parent, origin->path);
559
+ oidcpy(&porigin->blob_oid, &p->one->oid);
560
+ porigin->mode = p->one->mode;
561
+ break;
562
+ case 'A':
563
+ case 'T':
564
+ /* Did not exist in parent, or type changed */
565
+ break;
566
+ }
567
+ }
568
+ diff_flush(&diff_opts);
569
+ clear_pathspec(&diff_opts.pathspec);
570
+ return porigin;
571
+}
572
+
573
+/*
574
+ * We have an origin -- find the path that corresponds to it in its
575
+ * parent and return an origin structure to represent it.
576
+ */
577
+static struct blame_origin *find_rename(struct commit *parent,
578
+ struct blame_origin *origin)
579
+{
580
+ struct blame_origin *porigin = NULL;
581
+ struct diff_options diff_opts;
582
+ int i;
583
+
584
+ diff_setup(&diff_opts);
585
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
586
+ diff_opts.detect_rename = DIFF_DETECT_RENAME;
587
+ diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
588
+ diff_opts.single_follow = origin->path;
589
+ diff_setup_done(&diff_opts);
590
+
591
+ if (is_null_oid(&origin->commit->object.oid))
592
+ do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
593
+ else
594
+ diff_tree_sha1(parent->tree->object.oid.hash,
595
+ origin->commit->tree->object.oid.hash,
596
+ "", &diff_opts);
597
+ diffcore_std(&diff_opts);
598
+
599
+ for (i = 0; i < diff_queued_diff.nr; i++) {
600
+ struct diff_filepair *p = diff_queued_diff.queue[i];
601
+ if ((p->status == 'R' || p->status == 'C') &&
602
+ !strcmp(p->two->path, origin->path)) {
603
+ porigin = get_origin(parent, p->one->path);
604
+ oidcpy(&porigin->blob_oid, &p->one->oid);
605
+ porigin->mode = p->one->mode;
606
+ break;
607
+ }
608
+ }
609
+ diff_flush(&diff_opts);
610
+ clear_pathspec(&diff_opts.pathspec);
611
+ return porigin;
612
+}
613
+
614
+/*
615
+ * Append a new blame entry to a given output queue.
616
+ */
617
+static void add_blame_entry(struct blame_entry ***queue,
618
+ const struct blame_entry *src)
619
+{
620
+ struct blame_entry *e = xmalloc(sizeof(*e));
621
+ memcpy(e, src, sizeof(*e));
622
+ blame_origin_incref(e->suspect);
623
+
624
+ e->next = **queue;
625
+ **queue = e;
626
+ *queue = &e->next;
627
+}
628
+
629
+/*
630
+ * src typically is on-stack; we want to copy the information in it to
631
+ * a malloced blame_entry that gets added to the given queue. The
632
+ * origin of dst loses a refcnt.
633
+ */
634
+static void dup_entry(struct blame_entry ***queue,
635
+ struct blame_entry *dst, struct blame_entry *src)
636
+{
637
+ blame_origin_incref(src->suspect);
638
+ blame_origin_decref(dst->suspect);
639
+ memcpy(dst, src, sizeof(*src));
640
+ dst->next = **queue;
641
+ **queue = dst;
642
+ *queue = &dst->next;
643
+}
644
+
645
+const char *blame_nth_line(struct blame_scoreboard *sb, long lno)
646
+{
647
+ return sb->final_buf + sb->lineno[lno];
648
+}
649
+
650
+/*
651
+ * It is known that lines between tlno to same came from parent, and e
652
+ * has an overlap with that range. it also is known that parent's
653
+ * line plno corresponds to e's line tlno.
654
+ *
655
+ * <---- e ----->
656
+ * <------>
657
+ * <------------>
658
+ * <------------>
659
+ * <------------------>
660
+ *
661
+ * Split e into potentially three parts; before this chunk, the chunk
662
+ * to be blamed for the parent, and after that portion.
663
+ */
664
+static void split_overlap(struct blame_entry *split,
665
+ struct blame_entry *e,
666
+ int tlno, int plno, int same,
667
+ struct blame_origin *parent)
668
+{
669
+ int chunk_end_lno;
670
+ memset(split, 0, sizeof(struct blame_entry [3]));
671
+
672
+ if (e->s_lno < tlno) {
673
+ /* there is a pre-chunk part not blamed on parent */
674
+ split[0].suspect = blame_origin_incref(e->suspect);
675
+ split[0].lno = e->lno;
676
+ split[0].s_lno = e->s_lno;
677
+ split[0].num_lines = tlno - e->s_lno;
678
+ split[1].lno = e->lno + tlno - e->s_lno;
679
+ split[1].s_lno = plno;
680
+ }
681
+ else {
682
+ split[1].lno = e->lno;
683
+ split[1].s_lno = plno + (e->s_lno - tlno);
684
+ }
685
+
686
+ if (same < e->s_lno + e->num_lines) {
687
+ /* there is a post-chunk part not blamed on parent */
688
+ split[2].suspect = blame_origin_incref(e->suspect);
689
+ split[2].lno = e->lno + (same - e->s_lno);
690
+ split[2].s_lno = e->s_lno + (same - e->s_lno);
691
+ split[2].num_lines = e->s_lno + e->num_lines - same;
692
+ chunk_end_lno = split[2].lno;
693
+ }
694
+ else
695
+ chunk_end_lno = e->lno + e->num_lines;
696
+ split[1].num_lines = chunk_end_lno - split[1].lno;
697
+
698
+ /*
699
+ * if it turns out there is nothing to blame the parent for,
700
+ * forget about the splitting. !split[1].suspect signals this.
701
+ */
702
+ if (split[1].num_lines < 1)
703
+ return;
704
+ split[1].suspect = blame_origin_incref(parent);
705
+}
706
+
707
+/*
708
+ * split_overlap() divided an existing blame e into up to three parts
709
+ * in split. Any assigned blame is moved to queue to
710
+ * reflect the split.
711
+ */
712
+static void split_blame(struct blame_entry ***blamed,
713
+ struct blame_entry ***unblamed,
714
+ struct blame_entry *split,
715
+ struct blame_entry *e)
716
+{
717
+ if (split[0].suspect && split[2].suspect) {
718
+ /* The first part (reuse storage for the existing entry e) */
719
+ dup_entry(unblamed, e, &split[0]);
720
+
721
+ /* The last part -- me */
722
+ add_blame_entry(unblamed, &split[2]);
723
+
724
+ /* ... and the middle part -- parent */
725
+ add_blame_entry(blamed, &split[1]);
726
+ }
727
+ else if (!split[0].suspect && !split[2].suspect)
728
+ /*
729
+ * The parent covers the entire area; reuse storage for
730
+ * e and replace it with the parent.
731
+ */
732
+ dup_entry(blamed, e, &split[1]);
733
+ else if (split[0].suspect) {
734
+ /* me and then parent */
735
+ dup_entry(unblamed, e, &split[0]);
736
+ add_blame_entry(blamed, &split[1]);
737
+ }
738
+ else {
739
+ /* parent and then me */
740
+ dup_entry(blamed, e, &split[1]);
741
+ add_blame_entry(unblamed, &split[2]);
742
+ }
743
+}
744
+
745
+/*
746
+ * After splitting the blame, the origins used by the
747
+ * on-stack blame_entry should lose one refcnt each.
748
+ */
749
+static void decref_split(struct blame_entry *split)
750
+{
751
+ int i;
752
+
753
+ for (i = 0; i < 3; i++)
754
+ blame_origin_decref(split[i].suspect);
755
+}
756
+
757
+/*
758
+ * reverse_blame reverses the list given in head, appending tail.
759
+ * That allows us to build lists in reverse order, then reverse them
760
+ * afterwards. This can be faster than building the list in proper
761
+ * order right away. The reason is that building in proper order
762
+ * requires writing a link in the _previous_ element, while building
763
+ * in reverse order just requires placing the list head into the
764
+ * _current_ element.
765
+ */
766
+
767
+static struct blame_entry *reverse_blame(struct blame_entry *head,
768
+ struct blame_entry *tail)
769
+{
770
+ while (head) {
771
+ struct blame_entry *next = head->next;
772
+ head->next = tail;
773
+ tail = head;
774
+ head = next;
775
+ }
776
+ return tail;
777
+}
778
+
779
+/*
780
+ * Process one hunk from the patch between the current suspect for
781
+ * blame_entry e and its parent. This first blames any unfinished
782
+ * entries before the chunk (which is where target and parent start
783
+ * differing) on the parent, and then splits blame entries at the
784
+ * start and at the end of the difference region. Since use of -M and
785
+ * -C options may lead to overlapping/duplicate source line number
786
+ * ranges, all we can rely on from sorting/merging is the order of the
787
+ * first suspect line number.
788
+ */
789
+static void blame_chunk(struct blame_entry ***dstq, struct blame_entry ***srcq,
790
+ int tlno, int offset, int same,
791
+ struct blame_origin *parent)
792
+{
793
+ struct blame_entry *e = **srcq;
794
+ struct blame_entry *samep = NULL, *diffp = NULL;
795
+
796
+ while (e && e->s_lno < tlno) {
797
+ struct blame_entry *next = e->next;
798
+ /*
799
+ * current record starts before differing portion. If
800
+ * it reaches into it, we need to split it up and
801
+ * examine the second part separately.
802
+ */
803
+ if (e->s_lno + e->num_lines > tlno) {
804
+ /* Move second half to a new record */
805
+ int len = tlno - e->s_lno;
806
+ struct blame_entry *n = xcalloc(1, sizeof (struct blame_entry));
807
+ n->suspect = e->suspect;
808
+ n->lno = e->lno + len;
809
+ n->s_lno = e->s_lno + len;
810
+ n->num_lines = e->num_lines - len;
811
+ e->num_lines = len;
812
+ e->score = 0;
813
+ /* Push new record to diffp */
814
+ n->next = diffp;
815
+ diffp = n;
816
+ } else
817
+ blame_origin_decref(e->suspect);
818
+ /* Pass blame for everything before the differing
819
+ * chunk to the parent */
820
+ e->suspect = blame_origin_incref(parent);
821
+ e->s_lno += offset;
822
+ e->next = samep;
823
+ samep = e;
824
+ e = next;
825
+ }
826
+ /*
827
+ * As we don't know how much of a common stretch after this
828
+ * diff will occur, the currently blamed parts are all that we
829
+ * can assign to the parent for now.
830
+ */
831
+
832
+ if (samep) {
833
+ **dstq = reverse_blame(samep, **dstq);
834
+ *dstq = &samep->next;
835
+ }
836
+ /*
837
+ * Prepend the split off portions: everything after e starts
838
+ * after the blameable portion.
839
+ */
840
+ e = reverse_blame(diffp, e);
841
+
842
+ /*
843
+ * Now retain records on the target while parts are different
844
+ * from the parent.
845
+ */
846
+ samep = NULL;
847
+ diffp = NULL;
848
+ while (e && e->s_lno < same) {
849
+ struct blame_entry *next = e->next;
850
+
851
+ /*
852
+ * If current record extends into sameness, need to split.
853
+ */
854
+ if (e->s_lno + e->num_lines > same) {
855
+ /*
856
+ * Move second half to a new record to be
857
+ * processed by later chunks
858
+ */
859
+ int len = same - e->s_lno;
860
+ struct blame_entry *n = xcalloc(1, sizeof (struct blame_entry));
861
+ n->suspect = blame_origin_incref(e->suspect);
862
+ n->lno = e->lno + len;
863
+ n->s_lno = e->s_lno + len;
864
+ n->num_lines = e->num_lines - len;
865
+ e->num_lines = len;
866
+ e->score = 0;
867
+ /* Push new record to samep */
868
+ n->next = samep;
869
+ samep = n;
870
+ }
871
+ e->next = diffp;
872
+ diffp = e;
873
+ e = next;
874
+ }
875
+ **srcq = reverse_blame(diffp, reverse_blame(samep, e));
876
+ /* Move across elements that are in the unblamable portion */
877
+ if (diffp)
878
+ *srcq = &diffp->next;
879
+}
880
+
881
+struct blame_chunk_cb_data {
882
+ struct blame_origin *parent;
883
+ long offset;
884
+ struct blame_entry **dstq;
885
+ struct blame_entry **srcq;
886
+};
887
+
888
+/* diff chunks are from parent to target */
889
+static int blame_chunk_cb(long start_a, long count_a,
890
+ long start_b, long count_b, void *data)
891
+{
892
+ struct blame_chunk_cb_data *d = data;
893
+ if (start_a - start_b != d->offset)
894
+ die("internal error in blame::blame_chunk_cb");
895
+ blame_chunk(&d->dstq, &d->srcq, start_b, start_a - start_b,
896
+ start_b + count_b, d->parent);
897
+ d->offset = start_a + count_a - (start_b + count_b);
898
+ return 0;
899
+}
900
+
901
+/*
902
+ * We are looking at the origin 'target' and aiming to pass blame
903
+ * for the lines it is suspected to its parent. Run diff to find
904
+ * which lines came from parent and pass blame for them.
905
+ */
906
+static void pass_blame_to_parent(struct blame_scoreboard *sb,
907
+ struct blame_origin *target,
908
+ struct blame_origin *parent)
909
+{
910
+ mmfile_t file_p, file_o;
911
+ struct blame_chunk_cb_data d;
912
+ struct blame_entry *newdest = NULL;
913
+
914
+ if (!target->suspects)
915
+ return; /* nothing remains for this target */
916
+
917
+ d.parent = parent;
918
+ d.offset = 0;
919
+ d.dstq = &newdest; d.srcq = &target->suspects;
920
+
921
+ fill_origin_blob(&sb->revs->diffopt, parent, &file_p, &sb->num_read_blob);
922
+ fill_origin_blob(&sb->revs->diffopt, target, &file_o, &sb->num_read_blob);
923
+ sb->num_get_patch++;
924
+
925
+ if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d, sb->xdl_opts))
926
+ die("unable to generate diff (%s -> %s)",
927
+ oid_to_hex(&parent->commit->object.oid),
928
+ oid_to_hex(&target->commit->object.oid));
929
+ /* The rest are the same as the parent */
930
+ blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, INT_MAX, parent);
931
+ *d.dstq = NULL;
932
+ queue_blames(sb, parent, newdest);
933
+
934
+ return;
935
+}
936
+
937
+/*
938
+ * The lines in blame_entry after splitting blames many times can become
939
+ * very small and trivial, and at some point it becomes pointless to
940
+ * blame the parents. E.g. "\t\t}\n\t}\n\n" appears everywhere in any
941
+ * ordinary C program, and it is not worth to say it was copied from
942
+ * totally unrelated file in the parent.
943
+ *
944
+ * Compute how trivial the lines in the blame_entry are.
945
+ */
946
+unsigned blame_entry_score(struct blame_scoreboard *sb, struct blame_entry *e)
947
+{
948
+ unsigned score;
949
+ const char *cp, *ep;
950
+
951
+ if (e->score)
952
+ return e->score;
953
+
954
+ score = 1;
955
+ cp = blame_nth_line(sb, e->lno);
956
+ ep = blame_nth_line(sb, e->lno + e->num_lines);
957
+ while (cp < ep) {
958
+ unsigned ch = *((unsigned char *)cp);
959
+ if (isalnum(ch))
960
+ score++;
961
+ cp++;
962
+ }
963
+ e->score = score;
964
+ return score;
965
+}
966
+
967
+/*
968
+ * best_so_far[] and this[] are both a split of an existing blame_entry
969
+ * that passes blame to the parent. Maintain best_so_far the best split
970
+ * so far, by comparing this and best_so_far and copying this into
971
+ * bst_so_far as needed.
972
+ */
973
+static void copy_split_if_better(struct blame_scoreboard *sb,
974
+ struct blame_entry *best_so_far,
975
+ struct blame_entry *this)
976
+{
977
+ int i;
978
+
979
+ if (!this[1].suspect)
980
+ return;
981
+ if (best_so_far[1].suspect) {
982
+ if (blame_entry_score(sb, &this[1]) < blame_entry_score(sb, &best_so_far[1]))
983
+ return;
984
+ }
985
+
986
+ for (i = 0; i < 3; i++)
987
+ blame_origin_incref(this[i].suspect);
988
+ decref_split(best_so_far);
989
+ memcpy(best_so_far, this, sizeof(struct blame_entry [3]));
990
+}
991
+
992
+/*
993
+ * We are looking at a part of the final image represented by
994
+ * ent (tlno and same are offset by ent->s_lno).
995
+ * tlno is where we are looking at in the final image.
996
+ * up to (but not including) same match preimage.
997
+ * plno is where we are looking at in the preimage.
998
+ *
999
+ * <-------------- final image ---------------------->
1000
+ * <------ent------>
1001
+ * ^tlno ^same
1002
+ * <---------preimage----->
1003
+ * ^plno
1004
+ *
1005
+ * All line numbers are 0-based.
1006
+ */
1007
+static void handle_split(struct blame_scoreboard *sb,
1008
+ struct blame_entry *ent,
1009
+ int tlno, int plno, int same,
1010
+ struct blame_origin *parent,
1011
+ struct blame_entry *split)
1012
+{
1013
+ if (ent->num_lines <= tlno)
1014
+ return;
1015
+ if (tlno < same) {
1016
+ struct blame_entry this[3];
1017
+ tlno += ent->s_lno;
1018
+ same += ent->s_lno;
1019
+ split_overlap(this, ent, tlno, plno, same, parent);
1020
+ copy_split_if_better(sb, split, this);
1021
+ decref_split(this);
1022
+ }
1023
+}
1024
+
1025
+struct handle_split_cb_data {
1026
+ struct blame_scoreboard *sb;
1027
+ struct blame_entry *ent;
1028
+ struct blame_origin *parent;
1029
+ struct blame_entry *split;
1030
+ long plno;
1031
+ long tlno;
1032
+};
1033
+
1034
+static int handle_split_cb(long start_a, long count_a,
1035
+ long start_b, long count_b, void *data)
1036
+{
1037
+ struct handle_split_cb_data *d = data;
1038
+ handle_split(d->sb, d->ent, d->tlno, d->plno, start_b, d->parent,
1039
+ d->split);
1040
+ d->plno = start_a + count_a;
1041
+ d->tlno = start_b + count_b;
1042
+ return 0;
1043
+}
1044
+
1045
+/*
1046
+ * Find the lines from parent that are the same as ent so that
1047
+ * we can pass blames to it. file_p has the blob contents for
1048
+ * the parent.
1049
+ */
1050
+static void find_copy_in_blob(struct blame_scoreboard *sb,
1051
+ struct blame_entry *ent,
1052
+ struct blame_origin *parent,
1053
+ struct blame_entry *split,
1054
+ mmfile_t *file_p)
1055
+{
1056
+ const char *cp;
1057
+ mmfile_t file_o;
1058
+ struct handle_split_cb_data d;
1059
+
1060
+ memset(&d, 0, sizeof(d));
1061
+ d.sb = sb; d.ent = ent; d.parent = parent; d.split = split;
1062
+ /*
1063
+ * Prepare mmfile that contains only the lines in ent.
1064
+ */
1065
+ cp = blame_nth_line(sb, ent->lno);
1066
+ file_o.ptr = (char *) cp;
1067
+ file_o.size = blame_nth_line(sb, ent->lno + ent->num_lines) - cp;
1068
+
1069
+ /*
1070
+ * file_o is a part of final image we are annotating.
1071
+ * file_p partially may match that image.
1072
+ */
1073
+ memset(split, 0, sizeof(struct blame_entry [3]));
1074
+ if (diff_hunks(file_p, &file_o, handle_split_cb, &d, sb->xdl_opts))
1075
+ die("unable to generate diff (%s)",
1076
+ oid_to_hex(&parent->commit->object.oid));
1077
+ /* remainder, if any, all match the preimage */
1078
+ handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split);
1079
+}
1080
+
1081
+/* Move all blame entries from list *source that have a score smaller
1082
+ * than score_min to the front of list *small.
1083
+ * Returns a pointer to the link pointing to the old head of the small list.
1084
+ */
1085
+
1086
+static struct blame_entry **filter_small(struct blame_scoreboard *sb,
1087
+ struct blame_entry **small,
1088
+ struct blame_entry **source,
1089
+ unsigned score_min)
1090
+{
1091
+ struct blame_entry *p = *source;
1092
+ struct blame_entry *oldsmall = *small;
1093
+ while (p) {
1094
+ if (blame_entry_score(sb, p) <= score_min) {
1095
+ *small = p;
1096
+ small = &p->next;
1097
+ p = *small;
1098
+ } else {
1099
+ *source = p;
1100
+ source = &p->next;
1101
+ p = *source;
1102
+ }
1103
+ }
1104
+ *small = oldsmall;
1105
+ *source = NULL;
1106
+ return small;
1107
+}
1108
+
1109
+/*
1110
+ * See if lines currently target is suspected for can be attributed to
1111
+ * parent.
1112
+ */
1113
+static void find_move_in_parent(struct blame_scoreboard *sb,
1114
+ struct blame_entry ***blamed,
1115
+ struct blame_entry **toosmall,
1116
+ struct blame_origin *target,
1117
+ struct blame_origin *parent)
1118
+{
1119
+ struct blame_entry *e, split[3];
1120
+ struct blame_entry *unblamed = target->suspects;
1121
+ struct blame_entry *leftover = NULL;
1122
+ mmfile_t file_p;
1123
+
1124
+ if (!unblamed)
1125
+ return; /* nothing remains for this target */
1126
+
1127
+ fill_origin_blob(&sb->revs->diffopt, parent, &file_p, &sb->num_read_blob);
1128
+ if (!file_p.ptr)
1129
+ return;
1130
+
1131
+ /* At each iteration, unblamed has a NULL-terminated list of
1132
+ * entries that have not yet been tested for blame. leftover
1133
+ * contains the reversed list of entries that have been tested
1134
+ * without being assignable to the parent.
1135
+ */
1136
+ do {
1137
+ struct blame_entry **unblamedtail = &unblamed;
1138
+ struct blame_entry *next;
1139
+ for (e = unblamed; e; e = next) {
1140
+ next = e->next;
1141
+ find_copy_in_blob(sb, e, parent, split, &file_p);
1142
+ if (split[1].suspect &&
1143
+ sb->move_score < blame_entry_score(sb, &split[1])) {
1144
+ split_blame(blamed, &unblamedtail, split, e);
1145
+ } else {
1146
+ e->next = leftover;
1147
+ leftover = e;
1148
+ }
1149
+ decref_split(split);
1150
+ }
1151
+ *unblamedtail = NULL;
1152
+ toosmall = filter_small(sb, toosmall, &unblamed, sb->move_score);
1153
+ } while (unblamed);
1154
+ target->suspects = reverse_blame(leftover, NULL);
1155
+}
1156
+
1157
+struct blame_list {
1158
+ struct blame_entry *ent;
1159
+ struct blame_entry split[3];
1160
+};
1161
+
1162
+/*
1163
+ * Count the number of entries the target is suspected for,
1164
+ * and prepare a list of entry and the best split.
1165
+ */
1166
+static struct blame_list *setup_blame_list(struct blame_entry *unblamed,
1167
+ int *num_ents_p)
1168
+{
1169
+ struct blame_entry *e;
1170
+ int num_ents, i;
1171
+ struct blame_list *blame_list = NULL;
1172
+
1173
+ for (e = unblamed, num_ents = 0; e; e = e->next)
1174
+ num_ents++;
1175
+ if (num_ents) {
1176
+ blame_list = xcalloc(num_ents, sizeof(struct blame_list));
1177
+ for (e = unblamed, i = 0; e; e = e->next)
1178
+ blame_list[i++].ent = e;
1179
+ }
1180
+ *num_ents_p = num_ents;
1181
+ return blame_list;
1182
+}
1183
+
1184
+/*
1185
+ * For lines target is suspected for, see if we can find code movement
1186
+ * across file boundary from the parent commit. porigin is the path
1187
+ * in the parent we already tried.
1188
+ */
1189
+static void find_copy_in_parent(struct blame_scoreboard *sb,
1190
+ struct blame_entry ***blamed,
1191
+ struct blame_entry **toosmall,
1192
+ struct blame_origin *target,
1193
+ struct commit *parent,
1194
+ struct blame_origin *porigin,
1195
+ int opt)
1196
+{
1197
+ struct diff_options diff_opts;
1198
+ int i, j;
1199
+ struct blame_list *blame_list;
1200
+ int num_ents;
1201
+ struct blame_entry *unblamed = target->suspects;
1202
+ struct blame_entry *leftover = NULL;
1203
+
1204
+ if (!unblamed)
1205
+ return; /* nothing remains for this target */
1206
+
1207
+ diff_setup(&diff_opts);
1208
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
1209
+ diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
1210
+
1211
+ diff_setup_done(&diff_opts);
1212
+
1213
+ /* Try "find copies harder" on new path if requested;
1214
+ * we do not want to use diffcore_rename() actually to
1215
+ * match things up; find_copies_harder is set only to
1216
+ * force diff_tree_sha1() to feed all filepairs to diff_queue,
1217
+ * and this code needs to be after diff_setup_done(), which
1218
+ * usually makes find-copies-harder imply copy detection.
1219
+ */
1220
+ if ((opt & PICKAXE_BLAME_COPY_HARDEST)
1221
+ || ((opt & PICKAXE_BLAME_COPY_HARDER)
1222
+ && (!porigin || strcmp(target->path, porigin->path))))
1223
+ DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
1224
+
1225
+ if (is_null_oid(&target->commit->object.oid))
1226
+ do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
1227
+ else
1228
+ diff_tree_sha1(parent->tree->object.oid.hash,
1229
+ target->commit->tree->object.oid.hash,
1230
+ "", &diff_opts);
1231
+
1232
+ if (!DIFF_OPT_TST(&diff_opts, FIND_COPIES_HARDER))
1233
+ diffcore_std(&diff_opts);
1234
+
1235
+ do {
1236
+ struct blame_entry **unblamedtail = &unblamed;
1237
+ blame_list = setup_blame_list(unblamed, &num_ents);
1238
+
1239
+ for (i = 0; i < diff_queued_diff.nr; i++) {
1240
+ struct diff_filepair *p = diff_queued_diff.queue[i];
1241
+ struct blame_origin *norigin;
1242
+ mmfile_t file_p;
1243
+ struct blame_entry this[3];
1244
+
1245
+ if (!DIFF_FILE_VALID(p->one))
1246
+ continue; /* does not exist in parent */
1247
+ if (S_ISGITLINK(p->one->mode))
1248
+ continue; /* ignore git links */
1249
+ if (porigin && !strcmp(p->one->path, porigin->path))
1250
+ /* find_move already dealt with this path */
1251
+ continue;
1252
+
1253
+ norigin = get_origin(parent, p->one->path);
1254
+ oidcpy(&norigin->blob_oid, &p->one->oid);
1255
+ norigin->mode = p->one->mode;
1256
+ fill_origin_blob(&sb->revs->diffopt, norigin, &file_p, &sb->num_read_blob);
1257
+ if (!file_p.ptr)
1258
+ continue;
1259
+
1260
+ for (j = 0; j < num_ents; j++) {
1261
+ find_copy_in_blob(sb, blame_list[j].ent,
1262
+ norigin, this, &file_p);
1263
+ copy_split_if_better(sb, blame_list[j].split,
1264
+ this);
1265
+ decref_split(this);
1266
+ }
1267
+ blame_origin_decref(norigin);
1268
+ }
1269
+
1270
+ for (j = 0; j < num_ents; j++) {
1271
+ struct blame_entry *split = blame_list[j].split;
1272
+ if (split[1].suspect &&
1273
+ sb->copy_score < blame_entry_score(sb, &split[1])) {
1274
+ split_blame(blamed, &unblamedtail, split,
1275
+ blame_list[j].ent);
1276
+ } else {
1277
+ blame_list[j].ent->next = leftover;
1278
+ leftover = blame_list[j].ent;
1279
+ }
1280
+ decref_split(split);
1281
+ }
1282
+ free(blame_list);
1283
+ *unblamedtail = NULL;
1284
+ toosmall = filter_small(sb, toosmall, &unblamed, sb->copy_score);
1285
+ } while (unblamed);
1286
+ target->suspects = reverse_blame(leftover, NULL);
1287
+ diff_flush(&diff_opts);
1288
+ clear_pathspec(&diff_opts.pathspec);
1289
+}
1290
+
1291
+/*
1292
+ * The blobs of origin and porigin exactly match, so everything
1293
+ * origin is suspected for can be blamed on the parent.
1294
+ */
1295
+static void pass_whole_blame(struct blame_scoreboard *sb,
1296
+ struct blame_origin *origin, struct blame_origin *porigin)
1297
+{
1298
+ struct blame_entry *e, *suspects;
1299
+
1300
+ if (!porigin->file.ptr && origin->file.ptr) {
1301
+ /* Steal its file */
1302
+ porigin->file = origin->file;
1303
+ origin->file.ptr = NULL;
1304
+ }
1305
+ suspects = origin->suspects;
1306
+ origin->suspects = NULL;
1307
+ for (e = suspects; e; e = e->next) {
1308
+ blame_origin_incref(porigin);
1309
+ blame_origin_decref(e->suspect);
1310
+ e->suspect = porigin;
1311
+ }
1312
+ queue_blames(sb, porigin, suspects);
1313
+}
1314
+
1315
+/*
1316
+ * We pass blame from the current commit to its parents. We keep saying
1317
+ * "parent" (and "porigin"), but what we mean is to find scapegoat to
1318
+ * exonerate ourselves.
1319
+ */
1320
+static struct commit_list *first_scapegoat(struct rev_info *revs, struct commit *commit,
1321
+ int reverse)
1322
+{
1323
+ if (!reverse) {
1324
+ if (revs->first_parent_only &&
1325
+ commit->parents &&
1326
+ commit->parents->next) {
1327
+ free_commit_list(commit->parents->next);
1328
+ commit->parents->next = NULL;
1329
+ }
1330
+ return commit->parents;
1331
+ }
1332
+ return lookup_decoration(&revs->children, &commit->object);
1333
+}
1334
+
1335
+static int num_scapegoats(struct rev_info *revs, struct commit *commit, int reverse)
1336
+{
1337
+ struct commit_list *l = first_scapegoat(revs, commit, reverse);
1338
+ return commit_list_count(l);
1339
+}
1340
+
1341
+/* Distribute collected unsorted blames to the respected sorted lists
1342
+ * in the various origins.
1343
+ */
1344
+static void distribute_blame(struct blame_scoreboard *sb, struct blame_entry *blamed)
1345
+{
1346
+ blamed = llist_mergesort(blamed, get_next_blame, set_next_blame,
1347
+ compare_blame_suspect);
1348
+ while (blamed)
1349
+ {
1350
+ struct blame_origin *porigin = blamed->suspect;
1351
+ struct blame_entry *suspects = NULL;
1352
+ do {
1353
+ struct blame_entry *next = blamed->next;
1354
+ blamed->next = suspects;
1355
+ suspects = blamed;
1356
+ blamed = next;
1357
+ } while (blamed && blamed->suspect == porigin);
1358
+ suspects = reverse_blame(suspects, NULL);
1359
+ queue_blames(sb, porigin, suspects);
1360
+ }
1361
+}
1362
+
1363
+#define MAXSG 16
1364
+
1365
+static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin, int opt)
1366
+{
1367
+ struct rev_info *revs = sb->revs;
1368
+ int i, pass, num_sg;
1369
+ struct commit *commit = origin->commit;
1370
+ struct commit_list *sg;
1371
+ struct blame_origin *sg_buf[MAXSG];
1372
+ struct blame_origin *porigin, **sg_origin = sg_buf;
1373
+ struct blame_entry *toosmall = NULL;
1374
+ struct blame_entry *blames, **blametail = &blames;
1375
+
1376
+ num_sg = num_scapegoats(revs, commit, sb->reverse);
1377
+ if (!num_sg)
1378
+ goto finish;
1379
+ else if (num_sg < ARRAY_SIZE(sg_buf))
1380
+ memset(sg_buf, 0, sizeof(sg_buf));
1381
+ else
1382
+ sg_origin = xcalloc(num_sg, sizeof(*sg_origin));
1383
+
1384
+ /*
1385
+ * The first pass looks for unrenamed path to optimize for
1386
+ * common cases, then we look for renames in the second pass.
1387
+ */
1388
+ for (pass = 0; pass < 2 - sb->no_whole_file_rename; pass++) {
1389
+ struct blame_origin *(*find)(struct commit *, struct blame_origin *);
1390
+ find = pass ? find_rename : find_origin;
1391
+
1392
+ for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
1393
+ i < num_sg && sg;
1394
+ sg = sg->next, i++) {
1395
+ struct commit *p = sg->item;
1396
+ int j, same;
1397
+
1398
+ if (sg_origin[i])
1399
+ continue;
1400
+ if (parse_commit(p))
1401
+ continue;
1402
+ porigin = find(p, origin);
1403
+ if (!porigin)
1404
+ continue;
1405
+ if (!oidcmp(&porigin->blob_oid, &origin->blob_oid)) {
1406
+ pass_whole_blame(sb, origin, porigin);
1407
+ blame_origin_decref(porigin);
1408
+ goto finish;
1409
+ }
1410
+ for (j = same = 0; j < i; j++)
1411
+ if (sg_origin[j] &&
1412
+ !oidcmp(&sg_origin[j]->blob_oid, &porigin->blob_oid)) {
1413
+ same = 1;
1414
+ break;
1415
+ }
1416
+ if (!same)
1417
+ sg_origin[i] = porigin;
1418
+ else
1419
+ blame_origin_decref(porigin);
1420
+ }
1421
+ }
1422
+
1423
+ sb->num_commits++;
1424
+ for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
1425
+ i < num_sg && sg;
1426
+ sg = sg->next, i++) {
1427
+ struct blame_origin *porigin = sg_origin[i];
1428
+ if (!porigin)
1429
+ continue;
1430
+ if (!origin->previous) {
1431
+ blame_origin_incref(porigin);
1432
+ origin->previous = porigin;
1433
+ }
1434
+ pass_blame_to_parent(sb, origin, porigin);
1435
+ if (!origin->suspects)
1436
+ goto finish;
1437
+ }
1438
+
1439
+ /*
1440
+ * Optionally find moves in parents' files.
1441
+ */
1442
+ if (opt & PICKAXE_BLAME_MOVE) {
1443
+ filter_small(sb, &toosmall, &origin->suspects, sb->move_score);
1444
+ if (origin->suspects) {
1445
+ for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
1446
+ i < num_sg && sg;
1447
+ sg = sg->next, i++) {
1448
+ struct blame_origin *porigin = sg_origin[i];
1449
+ if (!porigin)
1450
+ continue;
1451
+ find_move_in_parent(sb, &blametail, &toosmall, origin, porigin);
1452
+ if (!origin->suspects)
1453
+ break;
1454
+ }
1455
+ }
1456
+ }
1457
+
1458
+ /*
1459
+ * Optionally find copies from parents' files.
1460
+ */
1461
+ if (opt & PICKAXE_BLAME_COPY) {
1462
+ if (sb->copy_score > sb->move_score)
1463
+ filter_small(sb, &toosmall, &origin->suspects, sb->copy_score);
1464
+ else if (sb->copy_score < sb->move_score) {
1465
+ origin->suspects = blame_merge(origin->suspects, toosmall);
1466
+ toosmall = NULL;
1467
+ filter_small(sb, &toosmall, &origin->suspects, sb->copy_score);
1468
+ }
1469
+ if (!origin->suspects)
1470
+ goto finish;
1471
+
1472
+ for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
1473
+ i < num_sg && sg;
1474
+ sg = sg->next, i++) {
1475
+ struct blame_origin *porigin = sg_origin[i];
1476
+ find_copy_in_parent(sb, &blametail, &toosmall,
1477
+ origin, sg->item, porigin, opt);
1478
+ if (!origin->suspects)
1479
+ goto finish;
1480
+ }
1481
+ }
1482
+
1483
+finish:
1484
+ *blametail = NULL;
1485
+ distribute_blame(sb, blames);
1486
+ /*
1487
+ * prepend toosmall to origin->suspects
1488
+ *
1489
+ * There is no point in sorting: this ends up on a big
1490
+ * unsorted list in the caller anyway.
1491
+ */
1492
+ if (toosmall) {
1493
+ struct blame_entry **tail = &toosmall;
1494
+ while (*tail)
1495
+ tail = &(*tail)->next;
1496
+ *tail = origin->suspects;
1497
+ origin->suspects = toosmall;
1498
+ }
1499
+ for (i = 0; i < num_sg; i++) {
1500
+ if (sg_origin[i]) {
1501
+ drop_origin_blob(sg_origin[i]);
1502
+ blame_origin_decref(sg_origin[i]);
1503
+ }
1504
+ }
1505
+ drop_origin_blob(origin);
1506
+ if (sg_buf != sg_origin)
1507
+ free(sg_origin);
1508
+}
1509
+
1510
+/*
1511
+ * The main loop -- while we have blobs with lines whose true origin
1512
+ * is still unknown, pick one blob, and allow its lines to pass blames
1513
+ * to its parents. */
1514
+void assign_blame(struct blame_scoreboard *sb, int opt)
1515
+{
1516
+ struct rev_info *revs = sb->revs;
1517
+ struct commit *commit = prio_queue_get(&sb->commits);
1518
+
1519
+ while (commit) {
1520
+ struct blame_entry *ent;
1521
+ struct blame_origin *suspect = commit->util;
1522
+
1523
+ /* find one suspect to break down */
1524
+ while (suspect && !suspect->suspects)
1525
+ suspect = suspect->next;
1526
+
1527
+ if (!suspect) {
1528
+ commit = prio_queue_get(&sb->commits);
1529
+ continue;
1530
+ }
1531
+
1532
+ assert(commit == suspect->commit);
1533
+
1534
+ /*
1535
+ * We will use this suspect later in the loop,
1536
+ * so hold onto it in the meantime.
1537
+ */
1538
+ blame_origin_incref(suspect);
1539
+ parse_commit(commit);
1540
+ if (sb->reverse ||
1541
+ (!(commit->object.flags & UNINTERESTING) &&
1542
+ !(revs->max_age != -1 && commit->date < revs->max_age)))
1543
+ pass_blame(sb, suspect, opt);
1544
+ else {
1545
+ commit->object.flags |= UNINTERESTING;
1546
+ if (commit->object.parsed)
1547
+ mark_parents_uninteresting(commit);
1548
+ }
1549
+ /* treat root commit as boundary */
1550
+ if (!commit->parents && !sb->show_root)
1551
+ commit->object.flags |= UNINTERESTING;
1552
+
1553
+ /* Take responsibility for the remaining entries */
1554
+ ent = suspect->suspects;
1555
+ if (ent) {
1556
+ suspect->guilty = 1;
1557
+ for (;;) {
1558
+ struct blame_entry *next = ent->next;
1559
+ if (sb->found_guilty_entry)
1560
+ sb->found_guilty_entry(ent, sb->found_guilty_entry_data);
1561
+ if (next) {
1562
+ ent = next;
1563
+ continue;
1564
+ }
1565
+ ent->next = sb->ent;
1566
+ sb->ent = suspect->suspects;
1567
+ suspect->suspects = NULL;
1568
+ break;
1569
+ }
1570
+ }
1571
+ blame_origin_decref(suspect);
1572
+
1573
+ if (sb->debug) /* sanity */
1574
+ sanity_check_refcnt(sb);
1575
+ }
1576
+}
blame.h
+11
@@ -8,6 +8,11 @@
8
#include "prio-queue.h"
9
#include "diff.h"
10
11
+#define PICKAXE_BLAME_MOVE 01
12
+#define PICKAXE_BLAME_COPY 02
13
+#define PICKAXE_BLAME_COPY_HARDER 04
14
+#define PICKAXE_BLAME_COPY_HARDEST 010
15
+
16
/*
17
* One blob in a commit that is being suspected
18
*/
@@ -157,4 +162,10 @@ extern struct blame_origin *get_origin(struct commit *commit, const char *path);
162
163
extern struct commit *fake_working_tree_commit(struct diff_options *opt, const char *path, const char *contents_from);
164
165
+extern void blame_coalesce(struct blame_scoreboard *sb);
166
+extern void blame_sort_final(struct blame_scoreboard *sb);
167
+extern unsigned blame_entry_score(struct blame_scoreboard *sb, struct blame_entry *e);
168
+extern void assign_blame(struct blame_scoreboard *sb, int opt);
169
+extern const char *blame_nth_line(struct blame_scoreboard *sb, long lno);
170
+
171
#endif /* BLAME_H */
builtin/blame.c
-1318
@@ -12,13 +12,10 @@
12
#include "tag.h"
13
#include "tree-walk.h"
14
#include "diff.h"
15
-#include "diffcore.h"
15
#include "revision.h"
16
#include "quote.h"
18
-#include "xdiff-interface.h"
17
#include "string-list.h"
18
#include "mailmap.h"
21
-#include "mergesort.h"
19
#include "parse-options.h"
20
#include "prio-queue.h"
21
#include "utf8.h"
@@ -61,11 +58,6 @@ static struct string_list mailmap = STRING_LIST_INIT_NODUP;
58
#define DEBUG 0
59
#endif
60
64
-#define PICKAXE_BLAME_MOVE 01
65
-#define PICKAXE_BLAME_COPY 02
66
-#define PICKAXE_BLAME_COPY_HARDER 04
67
-#define PICKAXE_BLAME_COPY_HARDEST 010
68
-
61
static unsigned blame_move_score;
62
static unsigned blame_copy_score;
63
#define BLAME_DEFAULT_MOVE_SCORE 20
@@ -80,143 +72,6 @@ struct progress_info {
72
int blamed_lines;
73
};
74
83
-static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
84
- xdl_emit_hunk_consume_func_t hunk_func, void *cb_data, int xdl_opts)
85
-{
86
- xpparam_t xpp = {0};
87
- xdemitconf_t xecfg = {0};
88
- xdemitcb_t ecb = {NULL};
89
-
90
- xpp.flags = xdl_opts;
91
- xecfg.hunk_func = hunk_func;
92
- ecb.priv = cb_data;
93
- return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
94
-}
95
-
96
-/*
97
- * Given an origin, prepare mmfile_t structure to be used by the
98
- * diff machinery
99
- */
100
-static void fill_origin_blob(struct diff_options *opt,
101
- struct blame_origin *o, mmfile_t *file, int *num_read_blob)
102
-{
103
- if (!o->file.ptr) {
104
- enum object_type type;
105
- unsigned long file_size;
106
-
107
- (*num_read_blob)++;
108
- if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
109
- textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size))
110
- ;
111
- else
112
- file->ptr = read_sha1_file(o->blob_oid.hash, &type,
113
- &file_size);
114
- file->size = file_size;
115
-
116
- if (!file->ptr)
117
- die("Cannot read blob %s for path %s",
118
- oid_to_hex(&o->blob_oid),
119
- o->path);
120
- o->file = *file;
121
- }
122
- else
123
- *file = o->file;
124
-}
125
-
126
-static void drop_origin_blob(struct blame_origin *o)
127
-{
128
- if (o->file.ptr) {
129
- free(o->file.ptr);
130
- o->file.ptr = NULL;
131
- }
132
-}
133
-
134
-/*
135
- * Any merge of blames happens on lists of blames that arrived via
136
- * different parents in a single suspect. In this case, we want to
137
- * sort according to the suspect line numbers as opposed to the final
138
- * image line numbers. The function body is somewhat longish because
139
- * it avoids unnecessary writes.
140
- */
141
-
142
-static struct blame_entry *blame_merge(struct blame_entry *list1,
143
- struct blame_entry *list2)
144
-{
145
- struct blame_entry *p1 = list1, *p2 = list2,
146
- **tail = &list1;
147
-
148
- if (!p1)
149
- return p2;
150
- if (!p2)
151
- return p1;
152
-
153
- if (p1->s_lno <= p2->s_lno) {
154
- do {
155
- tail = &p1->next;
156
- if ((p1 = *tail) == NULL) {
157
- *tail = p2;
158
- return list1;
159
- }
160
- } while (p1->s_lno <= p2->s_lno);
161
- }
162
- for (;;) {
163
- *tail = p2;
164
- do {
165
- tail = &p2->next;
166
- if ((p2 = *tail) == NULL) {
167
- *tail = p1;
168
- return list1;
169
- }
170
- } while (p1->s_lno > p2->s_lno);
171
- *tail = p1;
172
- do {
173
- tail = &p1->next;
174
- if ((p1 = *tail) == NULL) {
175
- *tail = p2;
176
- return list1;
177
- }
178
- } while (p1->s_lno <= p2->s_lno);
179
- }
180
-}
181
-
182
-static void *get_next_blame(const void *p)
183
-{
184
- return ((struct blame_entry *)p)->next;
185
-}
186
-
187
-static void set_next_blame(void *p1, void *p2)
188
-{
189
- ((struct blame_entry *)p1)->next = p2;
190
-}
191
-
192
-/*
193
- * Final image line numbers are all different, so we don't need a
194
- * three-way comparison here.
195
- */
196
-
197
-static int compare_blame_final(const void *p1, const void *p2)
198
-{
199
- return ((struct blame_entry *)p1)->lno > ((struct blame_entry *)p2)->lno
200
- ? 1 : -1;
201
-}
202
-
203
-static int compare_blame_suspect(const void *p1, const void *p2)
204
-{
205
- const struct blame_entry *s1 = p1, *s2 = p2;
206
- /*
207
- * to allow for collating suspects, we sort according to the
208
- * respective pointer value as the primary sorting criterion.
209
- * The actual relation is pretty unimportant as long as it
210
- * establishes a total order. Comparing as integers gives us
211
- * that.
212
- */
213
- if (s1->suspect != s2->suspect)
214
- return (intptr_t)s1->suspect > (intptr_t)s2->suspect ? 1 : -1;
215
- if (s1->s_lno == s2->s_lno)
216
- return 0;
217
- return s1->s_lno > s2->s_lno ? 1 : -1;
218
-}
219
-
75
static int compare_commits_by_reverse_commit_date(const void *a,
76
const void *b,
77
void *c)
@@ -224,63 +79,6 @@ static int compare_commits_by_reverse_commit_date(const void *a,
79
return -compare_commits_by_commit_date(a, b, c);
80
}
81
227
-static void blame_sort_final(struct blame_scoreboard *sb)
228
-{
229
- sb->ent = llist_mergesort(sb->ent, get_next_blame, set_next_blame,
230
- compare_blame_final);
231
-}
232
-
233
-static void sanity_check_refcnt(struct blame_scoreboard *);
234
-
235
-/*
236
- * If two blame entries that are next to each other came from
237
- * contiguous lines in the same origin (i.e. <commit, path> pair),
238
- * merge them together.
239
- */
240
-static void blame_coalesce(struct blame_scoreboard *sb)
241
-{
242
- struct blame_entry *ent, *next;
243
-
244
- for (ent = sb->ent; ent && (next = ent->next); ent = next) {
245
- if (ent->suspect == next->suspect &&
246
- ent->s_lno + ent->num_lines == next->s_lno) {
247
- ent->num_lines += next->num_lines;
248
- ent->next = next->next;
249
- blame_origin_decref(next->suspect);
250
- free(next);
251
- ent->score = 0;
252
- next = ent; /* again */
253
- }
254
- }
255
-
256
- if (sb->debug) /* sanity */
257
- sanity_check_refcnt(sb);
258
-}
259
-
260
-/*
261
- * Merge the given sorted list of blames into a preexisting origin.
262
- * If there were no previous blames to that commit, it is entered into
263
- * the commit priority queue of the score board.
264
- */
265
-
266
-static void queue_blames(struct blame_scoreboard *sb, struct blame_origin *porigin,
267
- struct blame_entry *sorted)
268
-{
269
- if (porigin->suspects)
270
- porigin->suspects = blame_merge(porigin->suspects, sorted);
271
- else {
272
- struct blame_origin *o;
273
- for (o = porigin->commit->util; o; o = o->next) {
274
- if (o->suspects) {
275
- porigin->suspects = sorted;
276
- return;
277
- }
278
- }
279
- porigin->suspects = sorted;
280
- prio_queue_put(&sb->commits, porigin->commit);
281
- }
282
-}
283
-
82
/*
83
* Fill the blob_sha1 field of an origin if it hasn't, so that later
84
* call to fill_origin_blob() can use it to locate the data. blob_sha1
@@ -307,1036 +105,11 @@ static int fill_blob_sha1_and_mode(struct blame_origin *origin)
105
return -1;
106
}
107
310
-/*
311
- * We have an origin -- check if the same path exists in the
312
- * parent and return an origin structure to represent it.
313
- */
314
-static struct blame_origin *find_origin(struct commit *parent,
315
- struct blame_origin *origin)
316
-{
317
- struct blame_origin *porigin;
318
- struct diff_options diff_opts;
319
- const char *paths[2];
320
-
321
- /* First check any existing origins */
322
- for (porigin = parent->util; porigin; porigin = porigin->next)
323
- if (!strcmp(porigin->path, origin->path)) {
324
- /*
325
- * The same path between origin and its parent
326
- * without renaming -- the most common case.
327
- */
328
- return blame_origin_incref (porigin);
329
- }
330
-
331
- /* See if the origin->path is different between parent
332
- * and origin first. Most of the time they are the
333
- * same and diff-tree is fairly efficient about this.
334
- */
335
- diff_setup(&diff_opts);
336
- DIFF_OPT_SET(&diff_opts, RECURSIVE);
337
- diff_opts.detect_rename = 0;
338
- diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
339
- paths[0] = origin->path;
340
- paths[1] = NULL;
341
-
342
- parse_pathspec(&diff_opts.pathspec,
343
- PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
344
- PATHSPEC_LITERAL_PATH, "", paths);
345
- diff_setup_done(&diff_opts);
346
-
347
- if (is_null_oid(&origin->commit->object.oid))
348
- do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
349
- else
350
- diff_tree_sha1(parent->tree->object.oid.hash,
351
- origin->commit->tree->object.oid.hash,
352
- "", &diff_opts);
353
- diffcore_std(&diff_opts);
354
-
355
- if (!diff_queued_diff.nr) {
356
- /* The path is the same as parent */
357
- porigin = get_origin(parent, origin->path);
358
- oidcpy(&porigin->blob_oid, &origin->blob_oid);
359
- porigin->mode = origin->mode;
360
- } else {
361
- /*
362
- * Since origin->path is a pathspec, if the parent
363
- * commit had it as a directory, we will see a whole
364
- * bunch of deletion of files in the directory that we
365
- * do not care about.
366
- */
367
- int i;
368
- struct diff_filepair *p = NULL;
369
- for (i = 0; i < diff_queued_diff.nr; i++) {
370
- const char *name;
371
- p = diff_queued_diff.queue[i];
372
- name = p->one->path ? p->one->path : p->two->path;
373
- if (!strcmp(name, origin->path))
374
- break;
375
- }
376
- if (!p)
377
- die("internal error in blame::find_origin");
378
- switch (p->status) {
379
- default:
380
- die("internal error in blame::find_origin (%c)",
381
- p->status);
382
- case 'M':
383
- porigin = get_origin(parent, origin->path);
384
- oidcpy(&porigin->blob_oid, &p->one->oid);
385
- porigin->mode = p->one->mode;
386
- break;
387
- case 'A':
388
- case 'T':
389
- /* Did not exist in parent, or type changed */
390
- break;
391
- }
392
- }
393
- diff_flush(&diff_opts);
394
- clear_pathspec(&diff_opts.pathspec);
395
- return porigin;
396
-}
397
-
398
-/*
399
- * We have an origin -- find the path that corresponds to it in its
400
- * parent and return an origin structure to represent it.
401
- */
402
-static struct blame_origin *find_rename(struct commit *parent,
403
- struct blame_origin *origin)
404
-{
405
- struct blame_origin *porigin = NULL;
406
- struct diff_options diff_opts;
407
- int i;
408
-
409
- diff_setup(&diff_opts);
410
- DIFF_OPT_SET(&diff_opts, RECURSIVE);
411
- diff_opts.detect_rename = DIFF_DETECT_RENAME;
412
- diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
413
- diff_opts.single_follow = origin->path;
414
- diff_setup_done(&diff_opts);
415
-
416
- if (is_null_oid(&origin->commit->object.oid))
417
- do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
418
- else
419
- diff_tree_sha1(parent->tree->object.oid.hash,
420
- origin->commit->tree->object.oid.hash,
421
- "", &diff_opts);
422
- diffcore_std(&diff_opts);
423
-
424
- for (i = 0; i < diff_queued_diff.nr; i++) {
425
- struct diff_filepair *p = diff_queued_diff.queue[i];
426
- if ((p->status == 'R' || p->status == 'C') &&
427
- !strcmp(p->two->path, origin->path)) {
428
- porigin = get_origin(parent, p->one->path);
429
- oidcpy(&porigin->blob_oid, &p->one->oid);
430
- porigin->mode = p->one->mode;
431
- break;
432
- }
433
- }
434
- diff_flush(&diff_opts);
435
- clear_pathspec(&diff_opts.pathspec);
436
- return porigin;
437
-}
438
-
439
-/*
440
- * Append a new blame entry to a given output queue.
441
- */
442
-static void add_blame_entry(struct blame_entry ***queue,
443
- const struct blame_entry *src)
444
-{
445
- struct blame_entry *e = xmalloc(sizeof(*e));
446
- memcpy(e, src, sizeof(*e));
447
- blame_origin_incref(e->suspect);
448
-
449
- e->next = **queue;
450
- **queue = e;
451
- *queue = &e->next;
452
-}
453
-
454
-/*
455
- * src typically is on-stack; we want to copy the information in it to
456
- * a malloced blame_entry that gets added to the given queue. The
457
- * origin of dst loses a refcnt.
458
- */
459
-static void dup_entry(struct blame_entry ***queue,
460
- struct blame_entry *dst, struct blame_entry *src)
461
-{
462
- blame_origin_incref(src->suspect);
463
- blame_origin_decref(dst->suspect);
464
- memcpy(dst, src, sizeof(*src));
465
- dst->next = **queue;
466
- **queue = dst;
467
- *queue = &dst->next;
468
-}
469
-
470
-static const char *blame_nth_line(struct blame_scoreboard *sb, long lno)
471
-{
472
- return sb->final_buf + sb->lineno[lno];
473
-}
474
-
108
static const char *nth_line_cb(void *data, long lno)
109
{
110
return blame_nth_line((struct blame_scoreboard *)data, lno);
111
}
112
480
-/*
481
- * It is known that lines between tlno to same came from parent, and e
482
- * has an overlap with that range. it also is known that parent's
483
- * line plno corresponds to e's line tlno.
484
- *
485
- * <---- e ----->
486
- * <------>
487
- * <------------>
488
- * <------------>
489
- * <------------------>
490
- *
491
- * Split e into potentially three parts; before this chunk, the chunk
492
- * to be blamed for the parent, and after that portion.
493
- */
494
-static void split_overlap(struct blame_entry *split,
495
- struct blame_entry *e,
496
- int tlno, int plno, int same,
497
- struct blame_origin *parent)
498
-{
499
- int chunk_end_lno;
500
- memset(split, 0, sizeof(struct blame_entry [3]));
501
-
502
- if (e->s_lno < tlno) {
503
- /* there is a pre-chunk part not blamed on parent */
504
- split[0].suspect = blame_origin_incref(e->suspect);
505
- split[0].lno = e->lno;
506
- split[0].s_lno = e->s_lno;
507
- split[0].num_lines = tlno - e->s_lno;
508
- split[1].lno = e->lno + tlno - e->s_lno;
509
- split[1].s_lno = plno;
510
- }
511
- else {
512
- split[1].lno = e->lno;
513
- split[1].s_lno = plno + (e->s_lno - tlno);
514
- }
515
-
516
- if (same < e->s_lno + e->num_lines) {
517
- /* there is a post-chunk part not blamed on parent */
518
- split[2].suspect = blame_origin_incref(e->suspect);
519
- split[2].lno = e->lno + (same - e->s_lno);
520
- split[2].s_lno = e->s_lno + (same - e->s_lno);
521
- split[2].num_lines = e->s_lno + e->num_lines - same;
522
- chunk_end_lno = split[2].lno;
523
- }
524
- else
525
- chunk_end_lno = e->lno + e->num_lines;
526
- split[1].num_lines = chunk_end_lno - split[1].lno;
527
-
528
- /*
529
- * if it turns out there is nothing to blame the parent for,
530
- * forget about the splitting. !split[1].suspect signals this.
531
- */
532
- if (split[1].num_lines < 1)
533
- return;
534
- split[1].suspect = blame_origin_incref(parent);
535
-}
536
-
537
-/*
538
- * split_overlap() divided an existing blame e into up to three parts
539
- * in split. Any assigned blame is moved to queue to
540
- * reflect the split.
541
- */
542
-static void split_blame(struct blame_entry ***blamed,
543
- struct blame_entry ***unblamed,
544
- struct blame_entry *split,
545
- struct blame_entry *e)
546
-{
547
- if (split[0].suspect && split[2].suspect) {
548
- /* The first part (reuse storage for the existing entry e) */
549
- dup_entry(unblamed, e, &split[0]);
550
-
551
- /* The last part -- me */
552
- add_blame_entry(unblamed, &split[2]);
553
-
554
- /* ... and the middle part -- parent */
555
- add_blame_entry(blamed, &split[1]);
556
- }
557
- else if (!split[0].suspect && !split[2].suspect)
558
- /*
559
- * The parent covers the entire area; reuse storage for
560
- * e and replace it with the parent.
561
- */
562
- dup_entry(blamed, e, &split[1]);
563
- else if (split[0].suspect) {
564
- /* me and then parent */
565
- dup_entry(unblamed, e, &split[0]);
566
- add_blame_entry(blamed, &split[1]);
567
- }
568
- else {
569
- /* parent and then me */
570
- dup_entry(blamed, e, &split[1]);
571
- add_blame_entry(unblamed, &split[2]);
572
- }
573
-}
574
-
575
-/*
576
- * After splitting the blame, the origins used by the
577
- * on-stack blame_entry should lose one refcnt each.
578
- */
579
-static void decref_split(struct blame_entry *split)
580
-{
581
- int i;
582
-
583
- for (i = 0; i < 3; i++)
584
- blame_origin_decref(split[i].suspect);
585
-}
586
-
587
-/*
588
- * reverse_blame reverses the list given in head, appending tail.
589
- * That allows us to build lists in reverse order, then reverse them
590
- * afterwards. This can be faster than building the list in proper
591
- * order right away. The reason is that building in proper order
592
- * requires writing a link in the _previous_ element, while building
593
- * in reverse order just requires placing the list head into the
594
- * _current_ element.
595
- */
596
-
597
-static struct blame_entry *reverse_blame(struct blame_entry *head,
598
- struct blame_entry *tail)
599
-{
600
- while (head) {
601
- struct blame_entry *next = head->next;
602
- head->next = tail;
603
- tail = head;
604
- head = next;
605
- }
606
- return tail;
607
-}
608
-
609
-/*
610
- * Process one hunk from the patch between the current suspect for
611
- * blame_entry e and its parent. This first blames any unfinished
612
- * entries before the chunk (which is where target and parent start
613
- * differing) on the parent, and then splits blame entries at the
614
- * start and at the end of the difference region. Since use of -M and
615
- * -C options may lead to overlapping/duplicate source line number
616
- * ranges, all we can rely on from sorting/merging is the order of the
617
- * first suspect line number.
618
- */
619
-static void blame_chunk(struct blame_entry ***dstq, struct blame_entry ***srcq,
620
- int tlno, int offset, int same,
621
- struct blame_origin *parent)
622
-{
623
- struct blame_entry *e = **srcq;
624
- struct blame_entry *samep = NULL, *diffp = NULL;
625
-
626
- while (e && e->s_lno < tlno) {
627
- struct blame_entry *next = e->next;
628
- /*
629
- * current record starts before differing portion. If
630
- * it reaches into it, we need to split it up and
631
- * examine the second part separately.
632
- */
633
- if (e->s_lno + e->num_lines > tlno) {
634
- /* Move second half to a new record */
635
- int len = tlno - e->s_lno;
636
- struct blame_entry *n = xcalloc(1, sizeof (struct blame_entry));
637
- n->suspect = e->suspect;
638
- n->lno = e->lno + len;
639
- n->s_lno = e->s_lno + len;
640
- n->num_lines = e->num_lines - len;
641
- e->num_lines = len;
642
- e->score = 0;
643
- /* Push new record to diffp */
644
- n->next = diffp;
645
- diffp = n;
646
- } else
647
- blame_origin_decref(e->suspect);
648
- /* Pass blame for everything before the differing
649
- * chunk to the parent */
650
- e->suspect = blame_origin_incref(parent);
651
- e->s_lno += offset;
652
- e->next = samep;
653
- samep = e;
654
- e = next;
655
- }
656
- /*
657
- * As we don't know how much of a common stretch after this
658
- * diff will occur, the currently blamed parts are all that we
659
- * can assign to the parent for now.
660
- */
661
-
662
- if (samep) {
663
- **dstq = reverse_blame(samep, **dstq);
664
- *dstq = &samep->next;
665
- }
666
- /*
667
- * Prepend the split off portions: everything after e starts
668
- * after the blameable portion.
669
- */
670
- e = reverse_blame(diffp, e);
671
-
672
- /*
673
- * Now retain records on the target while parts are different
674
- * from the parent.
675
- */
676
- samep = NULL;
677
- diffp = NULL;
678
- while (e && e->s_lno < same) {
679
- struct blame_entry *next = e->next;
680
-
681
- /*
682
- * If current record extends into sameness, need to split.
683
- */
684
- if (e->s_lno + e->num_lines > same) {
685
- /*
686
- * Move second half to a new record to be
687
- * processed by later chunks
688
- */
689
- int len = same - e->s_lno;
690
- struct blame_entry *n = xcalloc(1, sizeof (struct blame_entry));
691
- n->suspect = blame_origin_incref(e->suspect);
692
- n->lno = e->lno + len;
693
- n->s_lno = e->s_lno + len;
694
- n->num_lines = e->num_lines - len;
695
- e->num_lines = len;
696
- e->score = 0;
697
- /* Push new record to samep */
698
- n->next = samep;
699
- samep = n;
700
- }
701
- e->next = diffp;
702
- diffp = e;
703
- e = next;
704
- }
705
- **srcq = reverse_blame(diffp, reverse_blame(samep, e));
706
- /* Move across elements that are in the unblamable portion */
707
- if (diffp)
708
- *srcq = &diffp->next;
709
-}
710
-
711
-struct blame_chunk_cb_data {
712
- struct blame_origin *parent;
713
- long offset;
714
- struct blame_entry **dstq;
715
- struct blame_entry **srcq;
716
-};
717
-
718
-/* diff chunks are from parent to target */
719
-static int blame_chunk_cb(long start_a, long count_a,
720
- long start_b, long count_b, void *data)
721
-{
722
- struct blame_chunk_cb_data *d = data;
723
- if (start_a - start_b != d->offset)
724
- die("internal error in blame::blame_chunk_cb");
725
- blame_chunk(&d->dstq, &d->srcq, start_b, start_a - start_b,
726
- start_b + count_b, d->parent);
727
- d->offset = start_a + count_a - (start_b + count_b);
728
- return 0;
729
-}
730
-
731
-/*
732
- * We are looking at the origin 'target' and aiming to pass blame
733
- * for the lines it is suspected to its parent. Run diff to find
734
- * which lines came from parent and pass blame for them.
735
- */
736
-static void pass_blame_to_parent(struct blame_scoreboard *sb,
737
- struct blame_origin *target,
738
- struct blame_origin *parent)
739
-{
740
- mmfile_t file_p, file_o;
741
- struct blame_chunk_cb_data d;
742
- struct blame_entry *newdest = NULL;
743
-
744
- if (!target->suspects)
745
- return; /* nothing remains for this target */
746
-
747
- d.parent = parent;
748
- d.offset = 0;
749
- d.dstq = &newdest; d.srcq = &target->suspects;
750
-
751
- fill_origin_blob(&sb->revs->diffopt, parent, &file_p, &sb->num_read_blob);
752
- fill_origin_blob(&sb->revs->diffopt, target, &file_o, &sb->num_read_blob);
753
- sb->num_get_patch++;
754
-
755
- if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d, sb->xdl_opts))
756
- die("unable to generate diff (%s -> %s)",
757
- oid_to_hex(&parent->commit->object.oid),
758
- oid_to_hex(&target->commit->object.oid));
759
- /* The rest are the same as the parent */
760
- blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, INT_MAX, parent);
761
- *d.dstq = NULL;
762
- queue_blames(sb, parent, newdest);
763
-
764
- return;
765
-}
766
-
767
-/*
768
- * The lines in blame_entry after splitting blames many times can become
769
- * very small and trivial, and at some point it becomes pointless to
770
- * blame the parents. E.g. "\t\t}\n\t}\n\n" appears everywhere in any
771
- * ordinary C program, and it is not worth to say it was copied from
772
- * totally unrelated file in the parent.
773
- *
774
- * Compute how trivial the lines in the blame_entry are.
775
- */
776
-static unsigned blame_entry_score(struct blame_scoreboard *sb, struct blame_entry *e)
777
-{
778
- unsigned score;
779
- const char *cp, *ep;
780
-
781
- if (e->score)
782
- return e->score;
783
-
784
- score = 1;
785
- cp = blame_nth_line(sb, e->lno);
786
- ep = blame_nth_line(sb, e->lno + e->num_lines);
787
- while (cp < ep) {
788
- unsigned ch = *((unsigned char *)cp);
789
- if (isalnum(ch))
790
- score++;
791
- cp++;
792
- }
793
- e->score = score;
794
- return score;
795
-}
796
-
797
-/*
798
- * best_so_far[] and this[] are both a split of an existing blame_entry
799
- * that passes blame to the parent. Maintain best_so_far the best split
800
- * so far, by comparing this and best_so_far and copying this into
801
- * bst_so_far as needed.
802
- */
803
-static void copy_split_if_better(struct blame_scoreboard *sb,
804
- struct blame_entry *best_so_far,
805
- struct blame_entry *this)
806
-{
807
- int i;
808
-
809
- if (!this[1].suspect)
810
- return;
811
- if (best_so_far[1].suspect) {
812
- if (blame_entry_score(sb, &this[1]) < blame_entry_score(sb, &best_so_far[1]))
813
- return;
814
- }
815
-
816
- for (i = 0; i < 3; i++)
817
- blame_origin_incref(this[i].suspect);
818
- decref_split(best_so_far);
819
- memcpy(best_so_far, this, sizeof(struct blame_entry [3]));
820
-}
821
-
822
-/*
823
- * We are looking at a part of the final image represented by
824
- * ent (tlno and same are offset by ent->s_lno).
825
- * tlno is where we are looking at in the final image.
826
- * up to (but not including) same match preimage.
827
- * plno is where we are looking at in the preimage.
828
- *
829
- * <-------------- final image ---------------------->
830
- * <------ent------>
831
- * ^tlno ^same
832
- * <---------preimage----->
833
- * ^plno
834
- *
835
- * All line numbers are 0-based.
836
- */
837
-static void handle_split(struct blame_scoreboard *sb,
838
- struct blame_entry *ent,
839
- int tlno, int plno, int same,
840
- struct blame_origin *parent,
841
- struct blame_entry *split)
842
-{
843
- if (ent->num_lines <= tlno)
844
- return;
845
- if (tlno < same) {
846
- struct blame_entry this[3];
847
- tlno += ent->s_lno;
848
- same += ent->s_lno;
849
- split_overlap(this, ent, tlno, plno, same, parent);
850
- copy_split_if_better(sb, split, this);
851
- decref_split(this);
852
- }
853
-}
854
-
855
-struct handle_split_cb_data {
856
- struct blame_scoreboard *sb;
857
- struct blame_entry *ent;
858
- struct blame_origin *parent;
859
- struct blame_entry *split;
860
- long plno;
861
- long tlno;
862
-};
863
-
864
-static int handle_split_cb(long start_a, long count_a,
865
- long start_b, long count_b, void *data)
866
-{
867
- struct handle_split_cb_data *d = data;
868
- handle_split(d->sb, d->ent, d->tlno, d->plno, start_b, d->parent,
869
- d->split);
870
- d->plno = start_a + count_a;
871
- d->tlno = start_b + count_b;
872
- return 0;
873
-}
874
-
875
-/*
876
- * Find the lines from parent that are the same as ent so that
877
- * we can pass blames to it. file_p has the blob contents for
878
- * the parent.
879
- */
880
-static void find_copy_in_blob(struct blame_scoreboard *sb,
881
- struct blame_entry *ent,
882
- struct blame_origin *parent,
883
- struct blame_entry *split,
884
- mmfile_t *file_p)
885
-{
886
- const char *cp;
887
- mmfile_t file_o;
888
- struct handle_split_cb_data d;
889
-
890
- memset(&d, 0, sizeof(d));
891
- d.sb = sb; d.ent = ent; d.parent = parent; d.split = split;
892
- /*
893
- * Prepare mmfile that contains only the lines in ent.
894
- */
895
- cp = blame_nth_line(sb, ent->lno);
896
- file_o.ptr = (char *) cp;
897
- file_o.size = blame_nth_line(sb, ent->lno + ent->num_lines) - cp;
898
-
899
- /*
900
- * file_o is a part of final image we are annotating.
901
- * file_p partially may match that image.
902
- */
903
- memset(split, 0, sizeof(struct blame_entry [3]));
904
- if (diff_hunks(file_p, &file_o, handle_split_cb, &d, sb->xdl_opts))
905
- die("unable to generate diff (%s)",
906
- oid_to_hex(&parent->commit->object.oid));
907
- /* remainder, if any, all match the preimage */
908
- handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split);
909
-}
910
-
911
-/* Move all blame entries from list *source that have a score smaller
912
- * than score_min to the front of list *small.
913
- * Returns a pointer to the link pointing to the old head of the small list.
914
- */
915
-
916
-static struct blame_entry **filter_small(struct blame_scoreboard *sb,
917
- struct blame_entry **small,
918
- struct blame_entry **source,
919
- unsigned score_min)
920
-{
921
- struct blame_entry *p = *source;
922
- struct blame_entry *oldsmall = *small;
923
- while (p) {
924
- if (blame_entry_score(sb, p) <= score_min) {
925
- *small = p;
926
- small = &p->next;
927
- p = *small;
928
- } else {
929
- *source = p;
930
- source = &p->next;
931
- p = *source;
932
- }
933
- }
934
- *small = oldsmall;
935
- *source = NULL;
936
- return small;
937
-}
938
-
939
-/*
940
- * See if lines currently target is suspected for can be attributed to
941
- * parent.
942
- */
943
-static void find_move_in_parent(struct blame_scoreboard *sb,
944
- struct blame_entry ***blamed,
945
- struct blame_entry **toosmall,
946
- struct blame_origin *target,
947
- struct blame_origin *parent)
948
-{
949
- struct blame_entry *e, split[3];
950
- struct blame_entry *unblamed = target->suspects;
951
- struct blame_entry *leftover = NULL;
952
- mmfile_t file_p;
953
-
954
- if (!unblamed)
955
- return; /* nothing remains for this target */
956
-
957
- fill_origin_blob(&sb->revs->diffopt, parent, &file_p, &sb->num_read_blob);
958
- if (!file_p.ptr)
959
- return;
960
-
961
- /* At each iteration, unblamed has a NULL-terminated list of
962
- * entries that have not yet been tested for blame. leftover
963
- * contains the reversed list of entries that have been tested
964
- * without being assignable to the parent.
965
- */
966
- do {
967
- struct blame_entry **unblamedtail = &unblamed;
968
- struct blame_entry *next;
969
- for (e = unblamed; e; e = next) {
970
- next = e->next;
971
- find_copy_in_blob(sb, e, parent, split, &file_p);
972
- if (split[1].suspect &&
973
- sb->move_score < blame_entry_score(sb, &split[1])) {
974
- split_blame(blamed, &unblamedtail, split, e);
975
- } else {
976
- e->next = leftover;
977
- leftover = e;
978
- }
979
- decref_split(split);
980
- }
981
- *unblamedtail = NULL;
982
- toosmall = filter_small(sb, toosmall, &unblamed, sb->move_score);
983
- } while (unblamed);
984
- target->suspects = reverse_blame(leftover, NULL);
985
-}
986
-
987
-struct blame_list {
988
- struct blame_entry *ent;
989
- struct blame_entry split[3];
990
-};
991
-
992
-/*
993
- * Count the number of entries the target is suspected for,
994
- * and prepare a list of entry and the best split.
995
- */
996
-static struct blame_list *setup_blame_list(struct blame_entry *unblamed,
997
- int *num_ents_p)
998
-{
999
- struct blame_entry *e;
1000
- int num_ents, i;
1001
- struct blame_list *blame_list = NULL;
1002
-
1003
- for (e = unblamed, num_ents = 0; e; e = e->next)
1004
- num_ents++;
1005
- if (num_ents) {
1006
- blame_list = xcalloc(num_ents, sizeof(struct blame_list));
1007
- for (e = unblamed, i = 0; e; e = e->next)
1008
- blame_list[i++].ent = e;
1009
- }
1010
- *num_ents_p = num_ents;
1011
- return blame_list;
1012
-}
1013
-
1014
-/*
1015
- * For lines target is suspected for, see if we can find code movement
1016
- * across file boundary from the parent commit. porigin is the path
1017
- * in the parent we already tried.
1018
- */
1019
-static void find_copy_in_parent(struct blame_scoreboard *sb,
1020
- struct blame_entry ***blamed,
1021
- struct blame_entry **toosmall,
1022
- struct blame_origin *target,
1023
- struct commit *parent,
1024
- struct blame_origin *porigin,
1025
- int opt)
1026
-{
1027
- struct diff_options diff_opts;
1028
- int i, j;
1029
- struct blame_list *blame_list;
1030
- int num_ents;
1031
- struct blame_entry *unblamed = target->suspects;
1032
- struct blame_entry *leftover = NULL;
1033
-
1034
- if (!unblamed)
1035
- return; /* nothing remains for this target */
1036
-
1037
- diff_setup(&diff_opts);
1038
- DIFF_OPT_SET(&diff_opts, RECURSIVE);
1039
- diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
1040
-
1041
- diff_setup_done(&diff_opts);
1042
-
1043
- /* Try "find copies harder" on new path if requested;
1044
- * we do not want to use diffcore_rename() actually to
1045
- * match things up; find_copies_harder is set only to
1046
- * force diff_tree_sha1() to feed all filepairs to diff_queue,
1047
- * and this code needs to be after diff_setup_done(), which
1048
- * usually makes find-copies-harder imply copy detection.
1049
- */
1050
- if ((opt & PICKAXE_BLAME_COPY_HARDEST)
1051
- || ((opt & PICKAXE_BLAME_COPY_HARDER)
1052
- && (!porigin || strcmp(target->path, porigin->path))))
1053
- DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
1054
-
1055
- if (is_null_oid(&target->commit->object.oid))
1056
- do_diff_cache(parent->tree->object.oid.hash, &diff_opts);
1057
- else
1058
- diff_tree_sha1(parent->tree->object.oid.hash,
1059
- target->commit->tree->object.oid.hash,
1060
- "", &diff_opts);
1061
-
1062
- if (!DIFF_OPT_TST(&diff_opts, FIND_COPIES_HARDER))
1063
- diffcore_std(&diff_opts);
1064
-
1065
- do {
1066
- struct blame_entry **unblamedtail = &unblamed;
1067
- blame_list = setup_blame_list(unblamed, &num_ents);
1068
-
1069
- for (i = 0; i < diff_queued_diff.nr; i++) {
1070
- struct diff_filepair *p = diff_queued_diff.queue[i];
1071
- struct blame_origin *norigin;
1072
- mmfile_t file_p;
1073
- struct blame_entry this[3];
1074
-
1075
- if (!DIFF_FILE_VALID(p->one))
1076
- continue; /* does not exist in parent */
1077
- if (S_ISGITLINK(p->one->mode))
1078
- continue; /* ignore git links */
1079
- if (porigin && !strcmp(p->one->path, porigin->path))
1080
- /* find_move already dealt with this path */
1081
- continue;
1082
-
1083
- norigin = get_origin(parent, p->one->path);
1084
- oidcpy(&norigin->blob_oid, &p->one->oid);
1085
- norigin->mode = p->one->mode;
1086
- fill_origin_blob(&sb->revs->diffopt, norigin, &file_p, &sb->num_read_blob);
1087
- if (!file_p.ptr)
1088
- continue;
1089
-
1090
- for (j = 0; j < num_ents; j++) {
1091
- find_copy_in_blob(sb, blame_list[j].ent,
1092
- norigin, this, &file_p);
1093
- copy_split_if_better(sb, blame_list[j].split,
1094
- this);
1095
- decref_split(this);
1096
- }
1097
- blame_origin_decref(norigin);
1098
- }
1099
-
1100
- for (j = 0; j < num_ents; j++) {
1101
- struct blame_entry *split = blame_list[j].split;
1102
- if (split[1].suspect &&
1103
- sb->copy_score < blame_entry_score(sb, &split[1])) {
1104
- split_blame(blamed, &unblamedtail, split,
1105
- blame_list[j].ent);
1106
- } else {
1107
- blame_list[j].ent->next = leftover;
1108
- leftover = blame_list[j].ent;
1109
- }
1110
- decref_split(split);
1111
- }
1112
- free(blame_list);
1113
- *unblamedtail = NULL;
1114
- toosmall = filter_small(sb, toosmall, &unblamed, sb->copy_score);
1115
- } while (unblamed);
1116
- target->suspects = reverse_blame(leftover, NULL);
1117
- diff_flush(&diff_opts);
1118
- clear_pathspec(&diff_opts.pathspec);
1119
-}
1120
-
1121
-/*
1122
- * The blobs of origin and porigin exactly match, so everything
1123
- * origin is suspected for can be blamed on the parent.
1124
- */
1125
-static void pass_whole_blame(struct blame_scoreboard *sb,
1126
- struct blame_origin *origin, struct blame_origin *porigin)
1127
-{
1128
- struct blame_entry *e, *suspects;
1129
-
1130
- if (!porigin->file.ptr && origin->file.ptr) {
1131
- /* Steal its file */
1132
- porigin->file = origin->file;
1133
- origin->file.ptr = NULL;
1134
- }
1135
- suspects = origin->suspects;
1136
- origin->suspects = NULL;
1137
- for (e = suspects; e; e = e->next) {
1138
- blame_origin_incref(porigin);
1139
- blame_origin_decref(e->suspect);
1140
- e->suspect = porigin;
1141
- }
1142
- queue_blames(sb, porigin, suspects);
1143
-}
1144
-
1145
-/*
1146
- * We pass blame from the current commit to its parents. We keep saying
1147
- * "parent" (and "porigin"), but what we mean is to find scapegoat to
1148
- * exonerate ourselves.
1149
- */
1150
-static struct commit_list *first_scapegoat(struct rev_info *revs, struct commit *commit,
1151
- int reverse)
1152
-{
1153
- if (!reverse) {
1154
- if (revs->first_parent_only &&
1155
- commit->parents &&
1156
- commit->parents->next) {
1157
- free_commit_list(commit->parents->next);
1158
- commit->parents->next = NULL;
1159
- }
1160
- return commit->parents;
1161
- }
1162
- return lookup_decoration(&revs->children, &commit->object);
1163
-}
1164
-
1165
-static int num_scapegoats(struct rev_info *revs, struct commit *commit, int reverse)
1166
-{
1167
- struct commit_list *l = first_scapegoat(revs, commit, reverse);
1168
- return commit_list_count(l);
1169
-}
1170
-
1171
-/* Distribute collected unsorted blames to the respected sorted lists
1172
- * in the various origins.
1173
- */
1174
-static void distribute_blame(struct blame_scoreboard *sb, struct blame_entry *blamed)
1175
-{
1176
- blamed = llist_mergesort(blamed, get_next_blame, set_next_blame,
1177
- compare_blame_suspect);
1178
- while (blamed)
1179
- {
1180
- struct blame_origin *porigin = blamed->suspect;
1181
- struct blame_entry *suspects = NULL;
1182
- do {
1183
- struct blame_entry *next = blamed->next;
1184
- blamed->next = suspects;
1185
- suspects = blamed;
1186
- blamed = next;
1187
- } while (blamed && blamed->suspect == porigin);
1188
- suspects = reverse_blame(suspects, NULL);
1189
- queue_blames(sb, porigin, suspects);
1190
- }
1191
-}
1192
-
1193
-#define MAXSG 16
1194
-
1195
-static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin, int opt)
1196
-{
1197
- struct rev_info *revs = sb->revs;
1198
- int i, pass, num_sg;
1199
- struct commit *commit = origin->commit;
1200
- struct commit_list *sg;
1201
- struct blame_origin *sg_buf[MAXSG];
1202
- struct blame_origin *porigin, **sg_origin = sg_buf;
1203
- struct blame_entry *toosmall = NULL;
1204
- struct blame_entry *blames, **blametail = &blames;
1205
-
1206
- num_sg = num_scapegoats(revs, commit, sb->reverse);
1207
- if (!num_sg)
1208
- goto finish;
1209
- else if (num_sg < ARRAY_SIZE(sg_buf))
1210
- memset(sg_buf, 0, sizeof(sg_buf));
1211
- else
1212
- sg_origin = xcalloc(num_sg, sizeof(*sg_origin));
1213
-
1214
- /*
1215
- * The first pass looks for unrenamed path to optimize for
1216
- * common cases, then we look for renames in the second pass.
1217
- */
1218
- for (pass = 0; pass < 2 - sb->no_whole_file_rename; pass++) {
1219
- struct blame_origin *(*find)(struct commit *, struct blame_origin *);
1220
- find = pass ? find_rename : find_origin;
1221
-
1222
- for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
1223
- i < num_sg && sg;
1224
- sg = sg->next, i++) {
1225
- struct commit *p = sg->item;
1226
- int j, same;
1227
-
1228
- if (sg_origin[i])
1229
- continue;
1230
- if (parse_commit(p))
1231
- continue;
1232
- porigin = find(p, origin);
1233
- if (!porigin)
1234
- continue;
1235
- if (!oidcmp(&porigin->blob_oid, &origin->blob_oid)) {
1236
- pass_whole_blame(sb, origin, porigin);
1237
- blame_origin_decref(porigin);
1238
- goto finish;
1239
- }
1240
- for (j = same = 0; j < i; j++)
1241
- if (sg_origin[j] &&
1242
- !oidcmp(&sg_origin[j]->blob_oid, &porigin->blob_oid)) {
1243
- same = 1;
1244
- break;
1245
- }
1246
- if (!same)
1247
- sg_origin[i] = porigin;
1248
- else
1249
- blame_origin_decref(porigin);
1250
- }
1251
- }
1252
-
1253
- sb->num_commits++;
1254
- for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
1255
- i < num_sg && sg;
1256
- sg = sg->next, i++) {
1257
- struct blame_origin *porigin = sg_origin[i];
1258
- if (!porigin)
1259
- continue;
1260
- if (!origin->previous) {
1261
- blame_origin_incref(porigin);
1262
- origin->previous = porigin;
1263
- }
1264
- pass_blame_to_parent(sb, origin, porigin);
1265
- if (!origin->suspects)
1266
- goto finish;
1267
- }
1268
-
1269
- /*
1270
- * Optionally find moves in parents' files.
1271
- */
1272
- if (opt & PICKAXE_BLAME_MOVE) {
1273
- filter_small(sb, &toosmall, &origin->suspects, sb->move_score);
1274
- if (origin->suspects) {
1275
- for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
1276
- i < num_sg && sg;
1277
- sg = sg->next, i++) {
1278
- struct blame_origin *porigin = sg_origin[i];
1279
- if (!porigin)
1280
- continue;
1281
- find_move_in_parent(sb, &blametail, &toosmall, origin, porigin);
1282
- if (!origin->suspects)
1283
- break;
1284
- }
1285
- }
1286
- }
1287
-
1288
- /*
1289
- * Optionally find copies from parents' files.
1290
- */
1291
- if (opt & PICKAXE_BLAME_COPY) {
1292
- if (sb->copy_score > sb->move_score)
1293
- filter_small(sb, &toosmall, &origin->suspects, sb->copy_score);
1294
- else if (sb->copy_score < sb->move_score) {
1295
- origin->suspects = blame_merge(origin->suspects, toosmall);
1296
- toosmall = NULL;
1297
- filter_small(sb, &toosmall, &origin->suspects, sb->copy_score);
1298
- }
1299
- if (!origin->suspects)
1300
- goto finish;
1301
-
1302
- for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
1303
- i < num_sg && sg;
1304
- sg = sg->next, i++) {
1305
- struct blame_origin *porigin = sg_origin[i];
1306
- find_copy_in_parent(sb, &blametail, &toosmall,
1307
- origin, sg->item, porigin, opt);
1308
- if (!origin->suspects)
1309
- goto finish;
1310
- }
1311
- }
1312
-
1313
-finish:
1314
- *blametail = NULL;
1315
- distribute_blame(sb, blames);
1316
- /*
1317
- * prepend toosmall to origin->suspects
1318
- *
1319
- * There is no point in sorting: this ends up on a big
1320
- * unsorted list in the caller anyway.
1321
- */
1322
- if (toosmall) {
1323
- struct blame_entry **tail = &toosmall;
1324
- while (*tail)
1325
- tail = &(*tail)->next;
1326
- *tail = origin->suspects;
1327
- origin->suspects = toosmall;
1328
- }
1329
- for (i = 0; i < num_sg; i++) {
1330
- if (sg_origin[i]) {
1331
- drop_origin_blob(sg_origin[i]);
1332
- blame_origin_decref(sg_origin[i]);
1333
- }
1334
- }
1335
- drop_origin_blob(origin);
1336
- if (sg_buf != sg_origin)
1337
- free(sg_origin);
1338
-}
1339
-
113
/*
114
* Information on commits, used for output.
115
*/
@@ -1546,74 +319,6 @@ static void found_guilty_entry(struct blame_entry *ent, void *data)
319
display_progress(pi->progress, pi->blamed_lines);
320
}
321
1549
-/*
1550
- * The main loop -- while we have blobs with lines whose true origin
1551
- * is still unknown, pick one blob, and allow its lines to pass blames
1552
- * to its parents. */
1553
-static void assign_blame(struct blame_scoreboard *sb, int opt)
1554
-{
1555
- struct rev_info *revs = sb->revs;
1556
- struct commit *commit = prio_queue_get(&sb->commits);
1557
-
1558
- while (commit) {
1559
- struct blame_entry *ent;
1560
- struct blame_origin *suspect = commit->util;
1561
-
1562
- /* find one suspect to break down */
1563
- while (suspect && !suspect->suspects)
1564
- suspect = suspect->next;
1565
-
1566
- if (!suspect) {
1567
- commit = prio_queue_get(&sb->commits);
1568
- continue;
1569
- }
1570
-
1571
- assert(commit == suspect->commit);
1572
-
1573
- /*
1574
- * We will use this suspect later in the loop,
1575
- * so hold onto it in the meantime.
1576
- */
1577
- blame_origin_incref(suspect);
1578
- parse_commit(commit);
1579
- if (sb->reverse ||
1580
- (!(commit->object.flags & UNINTERESTING) &&
1581
- !(revs->max_age != -1 && commit->date < revs->max_age)))
1582
- pass_blame(sb, suspect, opt);
1583
- else {
1584
- commit->object.flags |= UNINTERESTING;
1585
- if (commit->object.parsed)
1586
- mark_parents_uninteresting(commit);
1587
- }
1588
- /* treat root commit as boundary */
1589
- if (!commit->parents && !sb->show_root)
1590
- commit->object.flags |= UNINTERESTING;
1591
-
1592
- /* Take responsibility for the remaining entries */
1593
- ent = suspect->suspects;
1594
- if (ent) {
1595
- suspect->guilty = 1;
1596
- for (;;) {
1597
- struct blame_entry *next = ent->next;
1598
- if (sb->found_guilty_entry)
1599
- sb->found_guilty_entry(ent, sb->found_guilty_entry_data);
1600
- if (next) {
1601
- ent = next;
1602
- continue;
1603
- }
1604
- ent->next = sb->ent;
1605
- sb->ent = suspect->suspects;
1606
- suspect->suspects = NULL;
1607
- break;
1608
- }
1609
- }
1610
- blame_origin_decref(suspect);
1611
-
1612
- if (sb->debug) /* sanity */
1613
- sanity_check_refcnt(sb);
1614
- }
1615
-}
1616
-
322
static const char *format_time(timestamp_t time, const char *tz_str,
323
int show_raw_time)
324
{
@@ -1927,29 +632,6 @@ static void find_alignment(struct blame_scoreboard *sb, int *option)
632
abbrev = auto_abbrev + 1;
633
}
634
1930
-/*
1931
- * For debugging -- origin is refcounted, and this asserts that
1932
- * we do not underflow.
1933
- */
1934
-static void sanity_check_refcnt(struct blame_scoreboard *sb)
1935
-{
1936
- int baa = 0;
1937
- struct blame_entry *ent;
1938
-
1939
- for (ent = sb->ent; ent; ent = ent->next) {
1940
- /* Nobody should have zero or negative refcnt */
1941
- if (ent->suspect->refcnt <= 0) {
1942
- fprintf(stderr, "%s in %s has negative refcnt %d\n",
1943
- ent->suspect->path,
1944
- oid_to_hex(&ent->suspect->commit->object.oid),
1945
- ent->suspect->refcnt);
1946
- baa = 1;
1947
- }
1948
- }
1949
- if (baa)
1950
- sb->on_sanity_fail(sb, baa);
1951
-}
1952
-
635
static void sanity_check_on_fail(struct blame_scoreboard *sb, int baa)
636
{
637
int opt = OUTPUT_SHOW_SCORE | OUTPUT_SHOW_NUMBER | OUTPUT_SHOW_NAME;