X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-blame.c;h=fd6ca51eebb2234be429b47b572ae2f30592ff4e;hb=397f7c6371d309aa399bf32b773397f3c068d0c9;hp=cf74a926149668b7e67544aecd46a0e05d4f59d9;hpb=2c8f8b19d4f293edd78885880ed1a6166395ffdd;p=git.git diff --git a/builtin-blame.c b/builtin-blame.c index cf74a9261..fd6ca51ee 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -362,18 +362,28 @@ static struct origin *find_origin(struct scoreboard *sb, "", &diff_opts); diffcore_std(&diff_opts); - /* It is either one entry that says "modified", or "created", - * or nothing. - */ if (!diff_queued_diff.nr) { /* The path is the same as parent */ porigin = get_origin(sb, parent, origin->path); hashcpy(porigin->blob_sha1, origin->blob_sha1); - } - else if (diff_queued_diff.nr != 1) - die("internal error in blame::find_origin"); - else { - struct diff_filepair *p = diff_queued_diff.queue[0]; + } else { + /* + * Since origin->path is a pathspec, if the parent + * commit had it as a directory, we will see a whole + * bunch of deletion of files in the directory that we + * do not care about. + */ + int i; + struct diff_filepair *p = NULL; + for (i = 0; i < diff_queued_diff.nr; i++) { + const char *name; + p = diff_queued_diff.queue[i]; + name = p->one->path ? p->one->path : p->two->path; + if (!strcmp(name, origin->path)) + break; + } + if (!p) + die("internal error in blame::find_origin"); switch (p->status) { default: die("internal error in blame::find_origin (%c)", @@ -1998,23 +2008,23 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con if (contents_from) { if (stat(contents_from, &st) < 0) - die("Cannot stat %s", contents_from); + die_errno("Cannot stat '%s'", contents_from); read_from = contents_from; } else { if (lstat(path, &st) < 0) - die("Cannot lstat %s", path); + die_errno("Cannot lstat '%s'", path); read_from = path; } mode = canon_mode(st.st_mode); switch (st.st_mode & S_IFMT) { case S_IFREG: if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size) - die("cannot open or read %s", read_from); + die_errno("cannot open or read '%s'", read_from); break; case S_IFLNK: if (strbuf_readlink(&buf, read_from, st.st_size) < 0) - die("cannot readlink %s", read_from); + die_errno("cannot readlink '%s'", read_from); break; default: die("unsupported file type %s", read_from); @@ -2025,7 +2035,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con contents_from = "standard input"; mode = 0; if (strbuf_read(&buf, 0, 0) < 0) - die("read error %s from stdin", strerror(errno)); + die_errno("failed to read from stdin"); } convert_to_git(path, buf.buf, buf.len, &buf, 0); origin->file.ptr = buf.buf; @@ -2229,7 +2239,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) save_commit_buffer = 0; dashdash_pos = 0; - parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH | + parse_options_start(&ctx, argc, argv, prefix, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0); for (;;) { switch (parse_options_step(&ctx, options, blame_opt_usage)) { @@ -2251,8 +2261,7 @@ parse_done: argc = parse_options_end(&ctx); if (revs_file && read_ancestry(revs_file)) - die("reading graft file %s failed: %s", - revs_file, strerror(errno)); + die_errno("reading graft file '%s' failed", revs_file); if (cmd_is_annotate) { output_option |= OUTPUT_ANNOTATE_COMPAT; @@ -2340,7 +2349,7 @@ parse_done: setup_work_tree(); if (!has_string_in_work_tree(path)) - die("cannot stat path %s: %s", path, strerror(errno)); + die_errno("cannot stat path '%s'", path); } setup_revisions(argc, argv, &revs, NULL);