blame: move no_whole_file_rename flag to scoreboard
[gitweb.git] / builtin / blame.c
index 643f847efeb7afe29152c5930f7c7940878c5b5e..90c643c7da671235ad51b563d93db7e5fa56b431 100644 (file)
@@ -125,7 +125,7 @@ struct progress_info {
 };
 
 static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
-                     xdl_emit_hunk_consume_func_t hunk_func, void *cb_data)
+                     xdl_emit_hunk_consume_func_t hunk_func, void *cb_data, int xdl_opts)
 {
        xpparam_t xpp = {0};
        xdemitconf_t xecfg = {0};
@@ -378,6 +378,15 @@ struct blame_scoreboard {
         */
        unsigned move_score;
        unsigned copy_score;
+
+       /* use this file's contents as the final image */
+       const char *contents_from;
+
+       /* flags */
+       int reverse;
+       int show_root;
+       int xdl_opts;
+       int no_whole_file_rename;
 };
 
 static void sanity_check_refcnt(struct blame_scoreboard *);
@@ -941,7 +950,7 @@ static void pass_blame_to_parent(struct blame_scoreboard *sb,
        fill_origin_blob(&sb->revs->diffopt, target, &file_o, &sb->num_read_blob);
        sb->num_get_patch++;
 
-       if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d))
+       if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d, sb->xdl_opts))
                die("unable to generate diff (%s -> %s)",
                    oid_to_hex(&parent->commit->object.oid),
                    oid_to_hex(&target->commit->object.oid));
@@ -1090,7 +1099,7 @@ static void find_copy_in_blob(struct blame_scoreboard *sb,
         * file_p partially may match that image.
         */
        memset(split, 0, sizeof(struct blame_entry [3]));
-       if (diff_hunks(file_p, &file_o, handle_split_cb, &d))
+       if (diff_hunks(file_p, &file_o, handle_split_cb, &d, sb->xdl_opts))
                die("unable to generate diff (%s)",
                    oid_to_hex(&parent->commit->object.oid));
        /* remainder, if any, all match the preimage */
@@ -1336,7 +1345,8 @@ static void pass_whole_blame(struct blame_scoreboard *sb,
  * "parent" (and "porigin"), but what we mean is to find scapegoat to
  * exonerate ourselves.
  */
-static struct commit_list *first_scapegoat(struct rev_info *revs, struct commit *commit)
+static struct commit_list *first_scapegoat(struct rev_info *revs, struct commit *commit,
+                                          int reverse)
 {
        if (!reverse) {
                if (revs->first_parent_only &&
@@ -1350,9 +1360,9 @@ static struct commit_list *first_scapegoat(struct rev_info *revs, struct commit
        return lookup_decoration(&revs->children, &commit->object);
 }
 
-static int num_scapegoats(struct rev_info *revs, struct commit *commit)
+static int num_scapegoats(struct rev_info *revs, struct commit *commit, int reverse)
 {
-       struct commit_list *l = first_scapegoat(revs, commit);
+       struct commit_list *l = first_scapegoat(revs, commit, reverse);
        return commit_list_count(l);
 }
 
@@ -1390,7 +1400,7 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin,
        struct blame_entry *toosmall = NULL;
        struct blame_entry *blames, **blametail = &blames;
 
-       num_sg = num_scapegoats(revs, commit);
+       num_sg = num_scapegoats(revs, commit, sb->reverse);
        if (!num_sg)
                goto finish;
        else if (num_sg < ARRAY_SIZE(sg_buf))
@@ -1402,11 +1412,11 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin,
         * The first pass looks for unrenamed path to optimize for
         * common cases, then we look for renames in the second pass.
         */
-       for (pass = 0; pass < 2 - no_whole_file_rename; pass++) {
+       for (pass = 0; pass < 2 - sb->no_whole_file_rename; pass++) {
                struct blame_origin *(*find)(struct commit *, struct blame_origin *);
                find = pass ? find_rename : find_origin;
 
-               for (i = 0, sg = first_scapegoat(revs, commit);
+               for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
                     i < num_sg && sg;
                     sg = sg->next, i++) {
                        struct commit *p = sg->item;
@@ -1438,7 +1448,7 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin,
        }
 
        sb->num_commits++;
-       for (i = 0, sg = first_scapegoat(revs, commit);
+       for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
             i < num_sg && sg;
             sg = sg->next, i++) {
                struct blame_origin *porigin = sg_origin[i];
@@ -1459,7 +1469,7 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin,
        if (opt & PICKAXE_BLAME_MOVE) {
                filter_small(sb, &toosmall, &origin->suspects, sb->move_score);
                if (origin->suspects) {
-                       for (i = 0, sg = first_scapegoat(revs, commit);
+                       for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
                             i < num_sg && sg;
                             sg = sg->next, i++) {
                                struct blame_origin *porigin = sg_origin[i];
@@ -1486,7 +1496,7 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin,
                if (!origin->suspects)
                        goto finish;
 
-               for (i = 0, sg = first_scapegoat(revs, commit);
+               for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
                     i < num_sg && sg;
                     sg = sg->next, i++) {
                        struct blame_origin *porigin = sg_origin[i];
@@ -1767,7 +1777,7 @@ static void assign_blame(struct blame_scoreboard *sb, int opt)
                 */
                blame_origin_incref(suspect);
                parse_commit(commit);
-               if (reverse ||
+               if (sb->reverse ||
                    (!(commit->object.flags & UNINTERESTING) &&
                     !(revs->max_age != -1 && commit->date < revs->max_age)))
                        pass_blame(sb, suspect, opt);
@@ -1777,7 +1787,7 @@ static void assign_blame(struct blame_scoreboard *sb, int opt)
                                mark_parents_uninteresting(commit);
                }
                /* treat root commit as boundary */
-               if (!commit->parents && !show_root)
+               if (!commit->parents && !sb->show_root)
                        commit->object.flags |= UNINTERESTING;
 
                /* Take responsibility for the remaining entries */
@@ -2735,6 +2745,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        sb.copy_score = BLAME_DEFAULT_COPY_SCORE;
 
        sb.revs = &revs;
+       sb.contents_from = contents_from;
+       sb.reverse = reverse;
        if (!reverse) {
                final_commit_name = prepare_final(&sb);
                sb.commits.compare = compare_commits_by_commit_date;
@@ -2876,6 +2888,10 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        if (blame_copy_score)
                sb.copy_score = blame_copy_score;
 
+       sb.show_root = show_root;
+       sb.xdl_opts = xdl_opts;
+       sb.no_whole_file_rename = no_whole_file_rename;
+
        read_mailmap(&mailmap, NULL);
 
        assign_blame(&sb, opt);