From: Junio C Hamano Date: Tue, 3 Oct 2017 06:42:49 +0000 (+0900) Subject: Merge branch 'sb/diff-color-move' X-Git-Tag: v2.15.0-rc0~16 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/98c57ea6f00282ed6ab245cf6842972b07c5a6fd?ds=inline;hp=-c Merge branch 'sb/diff-color-move' The output from "git diff --summary" was broken in a recent topic that has been merged to 'master' and lost a LF after reporting of mode change. This has been fixed. * sb/diff-color-move: diff: correct newline in summary for renamed files --- 98c57ea6f00282ed6ab245cf6842972b07c5a6fd diff --combined diff.c index 4da0714cb5,0c604726c0..69f03570ad --- a/diff.c +++ b/diff.c @@@ -21,7 -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 @@@ -358,6 -357,9 +358,6 @@@ int git_diff_ui_config(const char *var return 0; } - if (git_color_config(var, value, cb) < 0) - return -1; - return git_diff_basic_config(var, value, cb); } @@@ -402,6 -404,9 +402,6 @@@ int git_diff_basic_config(const char *v 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; @@@ -459,9 -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; @@@ -469,6 -476,7 +469,6 @@@ 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; @@@ -853,38 -861,6 +853,38 @@@ static int shrink_potential_moved_block 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, @@@ -920,13 -896,20 +920,13 @@@ } 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; @@@ -956,17 -939,11 +956,17 @@@ } 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); } @@@ -1414,7 -1391,7 +1414,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; } @@@ -1541,7 -1518,7 +1541,7 @@@ static void emit_rewrite_diff(const cha struct diff_words_buffer { mmfile_t text; - long alloc; + unsigned long alloc; struct diff_words_orig { const char *begin, *end; } *orig; @@@ -1994,6 -1971,8 +1994,6 @@@ static unsigned long sane_truncate_line unsigned long allot; size_t l = len; - if (ecb->truncate) - return ecb->truncate(line, len); cp = line; allot = l; while (0 < l) { @@@ -2583,7 -2562,6 +2583,7 @@@ static void show_stats(struct diffstat_ } 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) @@@ -2839,7 -2817,7 +2839,7 @@@ static void show_dirstat_by_line(struc * 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; @@@ -3721,6 -3699,7 +3721,6 @@@ static void prep_temp_blob(const char * const struct object_id *oid, int mode) { - int fd; struct strbuf buf = STRBUF_INIT; struct strbuf template = STRBUF_INIT; char *path_dup = xstrdup(path); @@@ -3730,18 -3709,18 +3730,18 @@@ 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); @@@ -4009,7 -3988,7 +4009,7 @@@ static void diff_fill_oid_info(struct d } 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); } } @@@ -5272,6 -5251,7 +5272,7 @@@ static void show_mode_change(struct dif strbuf_addch(&sb, ' '); quote_c_style(p->two->path, &sb, NULL, 0); } + strbuf_addch(&sb, '\n'); emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY, sb.buf, sb.len, 0); strbuf_release(&sb); @@@ -5289,7 -5269,6 +5290,7 @@@ static void show_rename_copy(struct dif 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) @@@ -5315,7 -5294,6 +5316,7 @@@ 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;