X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=blame.c;h=88bfec262f741a80ee4aac6ef19d7cf359559464;hb=fb6a9f93d39e4e5fdb83673a927f71a34e9fb7c0;hp=1ee0d323ca7d5397c95f0d55f2279d2ca5dc0c8f;hpb=9cda21defb0ad18f50b4dcea9f027f75a15131fd;p=git.git diff --git a/blame.c b/blame.c index 1ee0d323..88bfec26 100644 --- a/blame.c +++ b/blame.c @@ -149,7 +149,7 @@ static void free_patch(struct patch *p) free(p); } -static int get_blob_sha1_internal(unsigned char *sha1, const char *base, +static int get_blob_sha1_internal(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage); @@ -178,7 +178,7 @@ static int get_blob_sha1(struct tree *t, const char *pathname, return 0; } -static int get_blob_sha1_internal(unsigned char *sha1, const char *base, +static int get_blob_sha1_internal(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage) { @@ -508,25 +508,33 @@ static void process_commits(struct rev_info *rev, const char *path, static int compare_tree_path(struct rev_info* revs, struct commit* c1, struct commit* c2) { + int ret; const char* paths[2]; struct util_info* util = c2->object.util; paths[0] = util->pathname; paths[1] = NULL; - diff_tree_setup_paths(get_pathspec(revs->prefix, paths)); - return rev_compare_tree(c1->tree, c2->tree); + diff_tree_setup_paths(get_pathspec(revs->prefix, paths), + &revs->pruning); + ret = rev_compare_tree(revs, c1->tree, c2->tree); + diff_tree_release_paths(&revs->pruning); + return ret; } static int same_tree_as_empty_path(struct rev_info *revs, struct tree* t1, const char* path) { + int ret; const char* paths[2]; paths[0] = path; paths[1] = NULL; - diff_tree_setup_paths(get_pathspec(revs->prefix, paths)); - return rev_same_tree_as_empty(t1); + diff_tree_setup_paths(get_pathspec(revs->prefix, paths), + &revs->pruning); + ret = rev_same_tree_as_empty(revs, t1); + diff_tree_release_paths(&revs->pruning); + return ret; } static const char* find_rename(struct commit* commit, struct commit* parent) @@ -546,7 +554,7 @@ static const char* find_rename(struct commit* commit, struct commit* parent) diff_opts.recursive = 1; diff_opts.detect_rename = DIFF_DETECT_RENAME; paths[0] = NULL; - diff_tree_setup_paths(paths); + diff_tree_setup_paths(paths, &diff_opts); if (diff_setup_done(&diff_opts) < 0) die("diff_setup_done failed"); @@ -703,11 +711,30 @@ static void* topo_getter(struct commit* c) return util->topo_data; } +static int read_ancestry(const char *graft_file, + unsigned char **start_sha1) +{ + FILE *fp = fopen(graft_file, "r"); + char buf[1024]; + if (!fp) + return -1; + while (fgets(buf, sizeof(buf), fp)) { + /* The format is just "Commit Parent1 Parent2 ...\n" */ + int len = strlen(buf); + struct commit_graft *graft = read_graft_line(buf, len); + register_commit_graft(graft, 0); + if (!*start_sha1) + *start_sha1 = graft->sha1; + } + fclose(fp); + return 0; +} + int main(int argc, const char **argv) { int i; struct commit *initial = NULL; - unsigned char sha1[20]; + unsigned char sha1[20], *sha1_p = NULL; const char *filename = NULL, *commit = NULL; char filename_buf[256]; @@ -741,6 +768,14 @@ int main(int argc, const char **argv) !strcmp(argv[i], "--compability")) { compability = 1; continue; + } else if(!strcmp(argv[i], "-S")) { + if (i + 1 < argc && + !read_ancestry(argv[i + 1], &sha1_p)) { + compability = 1; + i++; + continue; + } + usage(blame_usage); } else if(!strcmp(argv[i], "--")) { options = 0; continue; @@ -762,7 +797,9 @@ int main(int argc, const char **argv) if(!filename) usage(blame_usage); - if(!commit) + if (commit && sha1_p) + usage(blame_usage); + else if(!commit) commit = "HEAD"; if(prefix) @@ -771,9 +808,12 @@ int main(int argc, const char **argv) strcpy(filename_buf, filename); filename = filename_buf; - if (get_sha1(commit, sha1)) - die("get_sha1 failed, commit '%s' not found", commit); - start_commit = lookup_commit_reference(sha1); + if (!sha1_p) { + if (get_sha1(commit, sha1)) + die("get_sha1 failed, commit '%s' not found", commit); + sha1_p = sha1; + } + start_commit = lookup_commit_reference(sha1_p); get_util(start_commit)->pathname = filename; if (fill_util_info(start_commit)) { printf("%s not found in %s\n", filename, commit); @@ -787,13 +827,14 @@ int main(int argc, const char **argv) rev.prune_fn = simplify_commit; rev.topo_setter = topo_setter; rev.topo_getter = topo_getter; + rev.parents = 1; rev.limited = 1; commit_list_insert(start_commit, &rev.commits); args[0] = filename; args[1] = NULL; - diff_tree_setup_paths(args); + diff_tree_setup_paths(args, &rev.pruning); prepare_revision_walk(&rev); process_commits(&rev, filename, &initial);