blame: create scoreboard setup function

Create function that completes setting up blame_scoreboard structure. 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 d0d0ef1f67c1549aa1eab55c9a4ec1c2c34fccaa
1 file changed +101 -89
builtin/blame.c
+101 -89
@@ -2544,6 +2544,105 @@ void init_scoreboard(struct blame_scoreboard *sb)
2544 sb->copy_score = BLAME_DEFAULT_COPY_SCORE;
2545 }
2546
2547 +void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blame_origin **orig)
2548 +{
2549 + const char *final_commit_name = NULL;
2550 + struct blame_origin *o;
2551 + struct commit *final_commit = NULL;
2552 + enum object_type type;
2553 +
2554 + if (sb->reverse && sb->contents_from)
2555 + die(_("--contents and --reverse do not blend well."));
2556 +
2557 + if (!sb->reverse) {
2558 + sb->final = find_single_final(sb->revs, &final_commit_name);
2559 + sb->commits.compare = compare_commits_by_commit_date;
2560 + } else {
2561 + sb->final = find_single_initial(sb->revs, &final_commit_name);
2562 + sb->commits.compare = compare_commits_by_reverse_commit_date;
2563 + }
2564 +
2565 + if (sb->final && sb->contents_from)
2566 + die(_("cannot use --contents with final commit object name"));
2567 +
2568 + if (sb->reverse && sb->revs->first_parent_only)
2569 + sb->revs->children.name = NULL;
2570 +
2571 + if (!sb->final) {
2572 + /*
2573 + * "--not A B -- path" without anything positive;
2574 + * do not default to HEAD, but use the working tree
2575 + * or "--contents".
2576 + */
2577 + setup_work_tree();
2578 + sb->final = fake_working_tree_commit(&sb->revs->diffopt,
2579 + path, sb->contents_from);
2580 + add_pending_object(sb->revs, &(sb->final->object), ":");
2581 + }
2582 +
2583 + if (sb->reverse && sb->revs->first_parent_only) {
2584 + final_commit = find_single_final(sb->revs, NULL);
2585 + if (!final_commit)
2586 + die(_("--reverse and --first-parent together require specified latest commit"));
2587 + }
2588 +
2589 + /*
2590 + * If we have bottom, this will mark the ancestors of the
2591 + * bottom commits we would reach while traversing as
2592 + * uninteresting.
2593 + */
2594 + if (prepare_revision_walk(sb->revs))
2595 + die(_("revision walk setup failed"));
2596 +
2597 + if (sb->reverse && sb->revs->first_parent_only) {
2598 + struct commit *c = final_commit;
2599 +
2600 + sb->revs->children.name = "children";
2601 + while (c->parents &&
2602 + oidcmp(&c->object.oid, &sb->final->object.oid)) {
2603 + struct commit_list *l = xcalloc(1, sizeof(*l));
2604 +
2605 + l->item = c;
2606 + if (add_decoration(&sb->revs->children,
2607 + &c->parents->item->object, l))
2608 + die("BUG: not unique item in first-parent chain");
2609 + c = c->parents->item;
2610 + }
2611 +
2612 + if (oidcmp(&c->object.oid, &sb->final->object.oid))
2613 + die(_("--reverse --first-parent together require range along first-parent chain"));
2614 + }
2615 +
2616 + if (is_null_oid(&sb->final->object.oid)) {
2617 + o = sb->final->util;
2618 + sb->final_buf = xmemdupz(o->file.ptr, o->file.size);
2619 + sb->final_buf_size = o->file.size;
2620 + }
2621 + else {
2622 + o = get_origin(sb->final, path);
2623 + if (fill_blob_sha1_and_mode(o))
2624 + die(_("no such path %s in %s"), path, final_commit_name);
2625 +
2626 + if (DIFF_OPT_TST(&sb->revs->diffopt, ALLOW_TEXTCONV) &&
2627 + textconv_object(path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf,
2628 + &sb->final_buf_size))
2629 + ;
2630 + else
2631 + sb->final_buf = read_sha1_file(o->blob_oid.hash, &type,
2632 + &sb->final_buf_size);
2633 +
2634 + if (!sb->final_buf)
2635 + die(_("cannot read blob %s for path %s"),
2636 + oid_to_hex(&o->blob_oid),
2637 + path);
2638 + }
2639 + sb->num_read_blob++;
2640 + prepare_lines(sb);
2641 +
2642 + if (orig)
2643 + *orig = o;
2644 +}
2645 +
2646 int cmd_blame(int argc, const char **argv, const char *prefix)
2647 {
2648 struct rev_info revs;
@@ -2552,9 +2651,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
2651 struct blame_origin *o;
2652 struct blame_entry *ent = NULL;
2653 long dashdash_pos, lno;
2555 - const char *final_commit_name = NULL;
2556 - enum object_type type;
2557 - struct commit *final_commit = NULL;
2654 struct progress_info pi = { NULL, 0 };
2655
2656 struct string_list range_list = STRING_LIST_INIT_NODUP;
@@ -2759,92 +2855,8 @@ parse_done:
2855 sb.revs = &revs;
2856 sb.contents_from = contents_from;
2857 sb.reverse = reverse;
2762 -
2763 - if (!reverse) {
2764 - sb.final = find_single_final(&revs, &final_commit_name);
2765 - sb.commits.compare = compare_commits_by_commit_date;
2766 - }
2767 - else if (contents_from)
2768 - die(_("--contents and --reverse do not blend well."));
2769 - else {
2770 - sb.final = find_single_initial(&revs, &final_commit_name);
2771 - sb.commits.compare = compare_commits_by_reverse_commit_date;
2772 - if (revs.first_parent_only)
2773 - revs.children.name = NULL;
2774 - }
2775 -
2776 - if (!sb.final) {
2777 - /*
2778 - * "--not A B -- path" without anything positive;
2779 - * do not default to HEAD, but use the working tree
2780 - * or "--contents".
2781 - */
2782 - setup_work_tree();
2783 - sb.final = fake_working_tree_commit(&sb.revs->diffopt,
2784 - path, contents_from);
2785 - add_pending_object(&revs, &(sb.final->object), ":");
2786 - }
2787 - else if (contents_from)
2788 - die(_("cannot use --contents with final commit object name"));
2789 -
2790 - if (reverse && revs.first_parent_only) {
2791 - final_commit = find_single_final(sb.revs, NULL);
2792 - if (!final_commit)
2793 - die(_("--reverse and --first-parent together require specified latest commit"));
2794 - }
2795 -
2796 - /*
2797 - * If we have bottom, this will mark the ancestors of the
2798 - * bottom commits we would reach while traversing as
2799 - * uninteresting.
2800 - */
2801 - if (prepare_revision_walk(&revs))
2802 - die(_("revision walk setup failed"));
2803 -
2804 - if (reverse && revs.first_parent_only) {
2805 - struct commit *c = final_commit;
2806 -
2807 - sb.revs->children.name = "children";
2808 - while (c->parents &&
2809 - oidcmp(&c->object.oid, &sb.final->object.oid)) {
2810 - struct commit_list *l = xcalloc(1, sizeof(*l));
2811 -
2812 - l->item = c;
2813 - if (add_decoration(&sb.revs->children,
2814 - &c->parents->item->object, l))
2815 - die("BUG: not unique item in first-parent chain");
2816 - c = c->parents->item;
2817 - }
2818 -
2819 - if (oidcmp(&c->object.oid, &sb.final->object.oid))
2820 - die(_("--reverse --first-parent together require range along first-parent chain"));
2821 - }
2822 -
2823 - if (is_null_oid(&sb.final->object.oid)) {
2824 - o = sb.final->util;
2825 - sb.final_buf = xmemdupz(o->file.ptr, o->file.size);
2826 - sb.final_buf_size = o->file.size;
2827 - }
2828 - else {
2829 - o = get_origin(sb.final, path);
2830 - if (fill_blob_sha1_and_mode(o))
2831 - die(_("no such path %s in %s"), path, final_commit_name);
2832 -
2833 - if (DIFF_OPT_TST(&sb.revs->diffopt, ALLOW_TEXTCONV) &&
2834 - textconv_object(path, o->mode, &o->blob_oid, 1, (char **) &sb.final_buf,
2835 - &sb.final_buf_size))
2836 - ;
2837 - else
2838 - sb.final_buf = read_sha1_file(o->blob_oid.hash, &type,
2839 - &sb.final_buf_size);
2840 -
2841 - if (!sb.final_buf)
2842 - die(_("cannot read blob %s for path %s"),
2843 - oid_to_hex(&o->blob_oid),
2844 - path);
2845 - }
2846 - sb.num_read_blob++;
2847 - lno = prepare_lines(&sb);
2858 + setup_scoreboard(&sb, path, &o);
2859 + lno = sb.num_lines;
2860
2861 if (lno && !range_list.nr)
2862 string_list_append(&range_list, "1");