diff options
Diffstat (limited to 'builtin/blame.c')
-rw-r--r-- | builtin/blame.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/builtin/blame.c b/builtin/blame.c index 303e217ae9..6fd1a63fc7 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -6,6 +6,7 @@ */ #include "cache.h" +#include "refs.h" #include "builtin.h" #include "blob.h" #include "commit.h" @@ -26,13 +27,14 @@ #include "userdiff.h" #include "line-range.h" #include "line-log.h" +#include "dir.h" -static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file"); +static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"); static const char *blame_opt_usage[] = { blame_usage, "", - N_("[rev-opts] are documented in git-rev-list(1)"), + N_("<rev-opts> are documented in git-rev-list(1)"), NULL }; @@ -49,7 +51,7 @@ static int xdl_opts; static int abbrev = -1; static int no_whole_file_rename; -static enum date_mode blame_date_mode = DATE_ISO8601; +static struct date_mode blame_date_mode = { DATE_ISO8601 }; static size_t blame_date_width; static struct string_list mailmap; @@ -1826,7 +1828,7 @@ static const char *format_time(unsigned long time, const char *tz_str, size_t time_width; int tz; tz = atoi(tz_str); - time_str = show_date(time, tz, blame_date_mode); + time_str = show_date(time, tz, &blame_date_mode); strbuf_addstr(&time_buf, time_str); /* * Add space paddings to time_buf to display a fixed width @@ -2085,7 +2087,6 @@ static void find_alignment(struct scoreboard *sb, int *option) for (e = sb->ent; e; e = e->next) { struct origin *suspect = e->suspect; - struct commit_info ci; int num; if (compute_auto_abbrev) @@ -2096,6 +2097,7 @@ static void find_alignment(struct scoreboard *sb, int *option) if (longest_file < num) longest_file = num; if (!(suspect->commit->object.flags & METAINFO_SHOWN)) { + struct commit_info ci; suspect->commit->object.flags |= METAINFO_SHOWN; get_commit_info(suspect->commit, &ci, 1); if (*option & OUTPUT_SHOW_EMAIL) @@ -2104,6 +2106,7 @@ static void find_alignment(struct scoreboard *sb, int *option) num = utf8_strwidth(ci.author.buf); if (longest_author < num) longest_author = num; + commit_info_destroy(&ci); } num = e->s_lno + e->num_lines; if (longest_src_lines < num) @@ -2113,8 +2116,6 @@ static void find_alignment(struct scoreboard *sb, int *option) longest_dst_lines = num; if (largest_score < ent_score(sb, e)) largest_score = ent_score(sb, e); - - commit_info_destroy(&ci); } max_orig_digits = decimal_width(longest_src_lines); max_digits = decimal_width(longest_dst_lines); @@ -2152,16 +2153,6 @@ static void sanity_check_refcnt(struct scoreboard *sb) } } -/* - * Used for the command line parsing; check if the path exists - * in the working tree. - */ -static int has_string_in_work_tree(const char *path) -{ - struct stat st; - return !lstat(path, &st); -} - static unsigned parse_score(const char *arg) { char *end; @@ -2186,10 +2177,18 @@ static int git_blame_config(const char *var, const char *value, void *cb) blank_boundary = git_config_bool(var, value); return 0; } + if (!strcmp(var, "blame.showemail")) { + int *output_option = cb; + if (git_config_bool(var, value)) + *output_option |= OUTPUT_SHOW_EMAIL; + else + *output_option &= ~OUTPUT_SHOW_EMAIL; + return 0; + } if (!strcmp(var, "blame.date")) { if (!value) return config_error_nonbool(var); - blame_date_mode = parse_date_format(value); + parse_date_format(value, &blame_date_mode); return 0; } @@ -2228,20 +2227,19 @@ static struct commit_list **append_parent(struct commit_list **tail, const unsig static void append_merge_parents(struct commit_list **tail) { int merge_head; - const char *merge_head_file = git_path("MERGE_HEAD"); struct strbuf line = STRBUF_INIT; - merge_head = open(merge_head_file, O_RDONLY); + merge_head = open(git_path_merge_head(), O_RDONLY); if (merge_head < 0) { if (errno == ENOENT) return; - die("cannot open '%s' for reading", merge_head_file); + die("cannot open '%s' for reading", git_path_merge_head()); } while (!strbuf_getwholeline_fd(&line, merge_head, '\n')) { unsigned char sha1[20]; if (line.len < 40 || get_sha1_hex(line.buf, sha1)) - die("unknown line in '%s': %s", merge_head_file, line.buf); + die("unknown line in '%s': %s", git_path_merge_head(), line.buf); tail = append_parent(tail, sha1); } close(merge_head); @@ -2349,6 +2347,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, if (strbuf_read(&buf, 0, 0) < 0) die_errno("failed to read from stdin"); } + convert_to_git(path, buf.buf, buf.len, &buf, 0); origin->file.ptr = buf.buf; origin->file.size = buf.len; pretend_sha1_file(buf.buf, buf.len, OBJ_BLOB, origin->blob_sha1); @@ -2390,7 +2389,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt, return commit; } -static const char *prepare_final(struct scoreboard *sb) +static char *prepare_final(struct scoreboard *sb) { int i; const char *final_commit_name = NULL; @@ -2415,10 +2414,10 @@ static const char *prepare_final(struct scoreboard *sb) sb->final = (struct commit *) obj; final_commit_name = revs->pending.objects[i].name; } - return final_commit_name; + return xstrdup_or_null(final_commit_name); } -static const char *prepare_initial(struct scoreboard *sb) +static char *prepare_initial(struct scoreboard *sb) { int i; const char *final_commit_name = NULL; @@ -2445,7 +2444,7 @@ static const char *prepare_initial(struct scoreboard *sb) } if (!final_commit_name) die("No commit to dig down to?"); - return final_commit_name; + return xstrdup(final_commit_name); } static int blame_copy_callback(const struct option *option, const char *arg, int unset) @@ -2489,7 +2488,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) struct origin *o; struct blame_entry *ent = NULL; long dashdash_pos, lno; - const char *final_commit_name = NULL; + char *final_commit_name = NULL; enum object_type type; static struct string_list range_list; @@ -2529,7 +2528,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) unsigned int range_i; long anchor; - git_config(git_blame_config, NULL); + git_config(git_blame_config, &output_option); init_revisions(&revs, NULL); revs.date_mode = blame_date_mode; DIFF_OPT_SET(&revs.diffopt, ALLOW_TEXTCONV); @@ -2570,13 +2569,13 @@ parse_done: if (cmd_is_annotate) { output_option |= OUTPUT_ANNOTATE_COMPAT; - blame_date_mode = DATE_ISO8601; + blame_date_mode.type = DATE_ISO8601; } else { blame_date_mode = revs.date_mode; } /* The maximum width used to show the dates */ - switch (blame_date_mode) { + switch (blame_date_mode.type) { case DATE_RFC2822: blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700"); break; @@ -2601,10 +2600,12 @@ parse_done: fewer display columns. */ blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */ break; - case DATE_LOCAL: case DATE_NORMAL: blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700"); break; + case DATE_STRFTIME: + blame_date_width = strlen(show_date(0, 0, &blame_date_mode)) + 1; /* add the null */ + break; } blame_date_width -= 1; /* strip the null */ @@ -2656,14 +2657,14 @@ parse_done: if (argc < 2) usage_with_options(blame_opt_usage, options); path = add_prefix(prefix, argv[argc - 1]); - if (argc == 3 && !has_string_in_work_tree(path)) { /* (2b) */ + if (argc == 3 && !file_exists(path)) { /* (2b) */ path = add_prefix(prefix, argv[1]); argv[1] = argv[2]; } argv[argc - 1] = "--"; setup_work_tree(); - if (!has_string_in_work_tree(path)) + if (!file_exists(path)) die_errno("cannot stat path '%s'", path); } @@ -2786,6 +2787,8 @@ parse_done: assign_blame(&sb, opt); + free(final_commit_name); + if (incremental) return 0; |