diff options
Diffstat (limited to 'diff.c')
-rw-r--r-- | diff.c | 83 |
1 files changed, 53 insertions, 30 deletions
@@ -21,6 +21,7 @@ #include "string-list.h" #include "argv-array.h" #include "graph.h" +#include "packfile.h" #ifdef NO_FAST_WORKING_DIRECTORY #define FAST_WORKING_DIRECTORY 0 @@ -357,9 +358,6 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) return 0; } - if (git_color_config(var, value, cb) < 0) - return -1; - return git_diff_basic_config(var, value, cb); } @@ -404,9 +402,6 @@ int git_diff_basic_config(const char *var, const char *value, void *cb) return 0; } - if (starts_with(var, "submodule.")) - return parse_submodule_config_option(var, value); - if (git_diff_heuristic_config(var, value, cb) < 0) return -1; @@ -464,11 +459,9 @@ static struct diff_tempfile { * If this diff_tempfile instance refers to a temporary file, * this tempfile object is used to manage its lifetime. */ - struct tempfile tempfile; + struct tempfile *tempfile; } diff_temp[2]; -typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len); - struct emit_callback { int color_diff; unsigned ws_rule; @@ -476,7 +469,6 @@ struct emit_callback { int blank_at_eof_in_postimage; int lno_in_preimage; int lno_in_postimage; - sane_truncate_fn truncate; const char **label_path; struct diff_words_data *diff_words; struct diff_options *opt; @@ -863,6 +855,38 @@ static int shrink_potential_moved_blocks(struct moved_entry **pmb, return rp + 1; } +/* + * If o->color_moved is COLOR_MOVED_PLAIN, this function does nothing. + * + * Otherwise, if the last block has fewer alphanumeric characters than + * COLOR_MOVED_MIN_ALNUM_COUNT, unset DIFF_SYMBOL_MOVED_LINE on all lines in + * that block. + * + * The last block consists of the (n - block_length)'th line up to but not + * including the nth line. + * + * NEEDSWORK: This uses the same heuristic as blame_entry_score() in blame.c. + * Think of a way to unify them. + */ +static void adjust_last_block(struct diff_options *o, int n, int block_length) +{ + int i, alnum_count = 0; + if (o->color_moved == COLOR_MOVED_PLAIN) + return; + for (i = 1; i < block_length + 1; i++) { + const char *c = o->emitted_symbols->buf[n - i].line; + for (; *c; c++) { + if (!isalnum(*c)) + continue; + alnum_count++; + if (alnum_count >= COLOR_MOVED_MIN_ALNUM_COUNT) + return; + } + } + for (i = 1; i < block_length + 1; i++) + o->emitted_symbols->buf[n - i].flags &= ~DIFF_SYMBOL_MOVED_LINE; +} + /* Find blocks of moved code, delegate actual coloring decision to helper */ static void mark_color_as_moved(struct diff_options *o, struct hashmap *add_lines, @@ -898,20 +922,13 @@ static void mark_color_as_moved(struct diff_options *o, } if (!match) { - if (block_length < COLOR_MOVED_MIN_BLOCK_LENGTH && - o->color_moved != COLOR_MOVED_PLAIN) { - for (i = 0; i < block_length + 1; i++) { - l = &o->emitted_symbols->buf[n - i]; - l->flags &= ~DIFF_SYMBOL_MOVED_LINE; - } - } + adjust_last_block(o, n, block_length); pmb_nr = 0; block_length = 0; continue; } l->flags |= DIFF_SYMBOL_MOVED_LINE; - block_length++; if (o->color_moved == COLOR_MOVED_PLAIN) continue; @@ -941,11 +958,17 @@ static void mark_color_as_moved(struct diff_options *o, } flipped_block = (flipped_block + 1) % 2; + + adjust_last_block(o, n, block_length); + block_length = 0; } + block_length++; + if (flipped_block) l->flags |= DIFF_SYMBOL_MOVED_LINE_ALT; } + adjust_last_block(o, n, block_length); free(pmb); } @@ -1393,7 +1416,7 @@ static void remove_tempfile(void) { int i; for (i = 0; i < ARRAY_SIZE(diff_temp); i++) { - if (is_tempfile_active(&diff_temp[i].tempfile)) + if (is_tempfile_active(diff_temp[i].tempfile)) delete_tempfile(&diff_temp[i].tempfile); diff_temp[i].name = NULL; } @@ -1520,7 +1543,7 @@ static void emit_rewrite_diff(const char *name_a, struct diff_words_buffer { mmfile_t text; - long alloc; + unsigned long alloc; struct diff_words_orig { const char *begin, *end; } *orig; @@ -1973,8 +1996,6 @@ static unsigned long sane_truncate_line(struct emit_callback *ecb, char *line, u unsigned long allot; size_t l = len; - if (ecb->truncate) - return ecb->truncate(line, len); cp = line; allot = l; while (0 < l) { @@ -2564,6 +2585,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options) } print_stat_summary_inserts_deletes(options, total_files, adds, dels); + strbuf_release(&out); } static void show_shortstats(struct diffstat_t *data, struct diff_options *options) @@ -2819,7 +2841,7 @@ static void show_dirstat_by_line(struct diffstat_t *data, struct diff_options *o * bytes per "line". * This is stupid and ugly, but very cheap... */ - damage = (damage + 63) / 64; + damage = DIV_ROUND_UP(damage, 64); ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc); dir.files[dir.nr].name = file->name; dir.files[dir.nr].changed = damage; @@ -3701,7 +3723,6 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp, const struct object_id *oid, int mode) { - int fd; struct strbuf buf = STRBUF_INIT; struct strbuf template = STRBUF_INIT; char *path_dup = xstrdup(path); @@ -3711,18 +3732,18 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp, strbuf_addstr(&template, "XXXXXX_"); strbuf_addstr(&template, base); - fd = mks_tempfile_ts(&temp->tempfile, template.buf, strlen(base) + 1); - if (fd < 0) + temp->tempfile = mks_tempfile_ts(template.buf, strlen(base) + 1); + if (!temp->tempfile) die_errno("unable to create temp-file"); if (convert_to_working_tree(path, (const char *)blob, (size_t)size, &buf)) { blob = buf.buf; size = buf.len; } - if (write_in_full(fd, blob, size) != size) + if (write_in_full(temp->tempfile->fd, blob, size) < 0 || + close_tempfile_gently(temp->tempfile)) die_errno("unable to write temp-file"); - close_tempfile(&temp->tempfile); - temp->name = get_tempfile_path(&temp->tempfile); + temp->name = get_tempfile_path(temp->tempfile); oid_to_hex_r(temp->hex, oid); xsnprintf(temp->mode, sizeof(temp->mode), "%06o", mode); strbuf_release(&buf); @@ -3990,7 +4011,7 @@ static void diff_fill_oid_info(struct diff_filespec *one) } if (lstat(one->path, &st) < 0) die_errno("stat '%s'", one->path); - if (index_path(one->oid.hash, one->path, &st, 0)) + if (index_path(&one->oid, one->path, &st, 0)) die("cannot hash %s", one->path); } } @@ -5271,6 +5292,7 @@ static void show_rename_copy(struct diff_options *opt, const char *renamecopy, emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY, sb.buf, sb.len, 0); show_mode_change(opt, p, 0); + strbuf_release(&sb); } static void diff_summary(struct diff_options *opt, struct diff_filepair *p) @@ -5296,6 +5318,7 @@ static void diff_summary(struct diff_options *opt, struct diff_filepair *p) strbuf_addf(&sb, " (%d%%)\n", similarity_index(p)); emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY, sb.buf, sb.len, 0); + strbuf_release(&sb); } show_mode_change(opt, p, !p->score); break; |