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)
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");
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];
!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;
if(!filename)
usage(blame_usage);
- if(!commit)
+ if (commit && sha1_p)
+ usage(blame_usage);
+ else if(!commit)
commit = "HEAD";
if(prefix)
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);
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);