]> git.ipfire.org Git - thirdparty/git.git/blobdiff - builtin/blame.c
blame: simplify 'setup_blame_bloom_data' interface
[thirdparty/git.git] / builtin / blame.c
index eb513fbe60c34a6de505a9b99da0ff033f612622..6f7e32411a880d4cb3971ecf1c222a3a2b0da317 100644 (file)
@@ -27,6 +27,7 @@
 #include "object-store.h"
 #include "blame.h"
 #include "refs.h"
+#include "tag.h"
 
 static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>");
 
@@ -803,6 +804,28 @@ static int is_a_rev(const char *name)
        return OBJ_NONE < oid_object_info(the_repository, &oid, NULL);
 }
 
+static int peel_to_commit_oid(struct object_id *oid_ret, void *cbdata)
+{
+       struct repository *r = ((struct blame_scoreboard *)cbdata)->repo;
+       struct object_id oid;
+
+       oidcpy(&oid, oid_ret);
+       while (1) {
+               struct object *obj;
+               int kind = oid_object_info(r, &oid, NULL);
+               if (kind == OBJ_COMMIT) {
+                       oidcpy(oid_ret, &oid);
+                       return 0;
+               }
+               if (kind != OBJ_TAG)
+                       return -1;
+               obj = deref_tag(r, parse_object(r, &oid), NULL, 0);
+               if (!obj)
+                       return -1;
+               oidcpy(&oid, &obj->oid);
+       }
+}
+
 static void build_ignorelist(struct blame_scoreboard *sb,
                             struct string_list *ignore_revs_file_list,
                             struct string_list *ignore_rev_list)
@@ -815,10 +838,12 @@ static void build_ignorelist(struct blame_scoreboard *sb,
                if (!strcmp(i->string, ""))
                        oidset_clear(&sb->ignore_list);
                else
-                       oidset_parse_file(&sb->ignore_list, i->string);
+                       oidset_parse_file_carefully(&sb->ignore_list, i->string,
+                                                   peel_to_commit_oid, sb);
        }
        for_each_string_list_item(i, ignore_rev_list) {
-               if (get_oid_committish(i->string, &oid))
+               if (get_oid_committish(i->string, &oid) ||
+                   peel_to_commit_oid(&oid, sb))
                        die(_("cannot find revision %s to ignore"), i->string);
                oidset_insert(&sb->ignore_list, &oid);
        }
@@ -866,7 +891,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")),
                OPT_CALLBACK_F('C', NULL, &opt, N_("score"), N_("Find line copies within and across files"), PARSE_OPT_OPTARG, blame_copy_callback),
                OPT_CALLBACK_F('M', NULL, &opt, N_("score"), N_("Find line movements within and across files"), PARSE_OPT_OPTARG, blame_move_callback),
-               OPT_STRING_LIST('L', NULL, &range_list, N_("n,m"), N_("Process only line range n,m, counting from 1")),
+               OPT_STRING_LIST('L', NULL, &range_list, N_("range"),
+                               N_("Process only line range <start>,<end> or function :<funcname>")),
                OPT__ABBREV(&abbrev),
                OPT_END()
        };
@@ -1057,17 +1083,18 @@ parse_done:
        sb.contents_from = contents_from;
        sb.reverse = reverse;
        sb.repo = the_repository;
+       sb.path = path;
        build_ignorelist(&sb, &ignore_revs_file_list, &ignore_rev_list);
        string_list_clear(&ignore_revs_file_list, 0);
        string_list_clear(&ignore_rev_list, 0);
-       setup_scoreboard(&sb, path, &o);
+       setup_scoreboard(&sb, &o);
 
        /*
         * Changed-path Bloom filters are disabled when looking
         * for copies.
         */
        if (!(opt & PICKAXE_BLAME_COPY))
-               setup_blame_bloom_data(&sb, path);
+               setup_blame_bloom_data(&sb);
 
        lno = sb.num_lines;
 
@@ -1086,7 +1113,7 @@ parse_done:
                if ((!lno && (top || bottom)) || lno < bottom)
                        die(Q_("file %s has only %lu line",
                               "file %s has only %lu lines",
-                              lno), path, lno);
+                              lno), sb.path, lno);
                if (bottom < 1)
                        bottom = 1;
                if (top < 1 || lno < top)
@@ -1111,7 +1138,6 @@ parse_done:
        string_list_clear(&range_list, 0);
 
        sb.ent = NULL;
-       sb.path = path;
 
        if (blame_move_score)
                sb.move_score = blame_move_score;