aboutsummaryrefslogtreecommitdiffstats
path: root/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c113
1 files changed, 25 insertions, 88 deletions
diff --git a/diff.c b/diff.c
index 3d3e553a98..1898dd307d 100644
--- a/diff.c
+++ b/diff.c
@@ -358,6 +358,9 @@ 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);
}
@@ -459,7 +462,7 @@ 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];
struct emit_callback {
@@ -704,81 +707,14 @@ struct moved_entry {
struct moved_entry *next_line;
};
-static int next_byte(const char **cp, const char **endp,
- const struct diff_options *diffopt)
-{
- int retval;
-
- if (*cp > *endp)
- return -1;
-
- if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_CHANGE)) {
- while (*cp < *endp && isspace(**cp))
- (*cp)++;
- /*
- * After skipping a couple of whitespaces, we still have to
- * account for one space.
- */
- return (int)' ';
- }
-
- if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE)) {
- while (*cp < *endp && isspace(**cp))
- (*cp)++;
- /* return the first non-ws character via the usual below */
- }
-
- retval = (unsigned char)(**cp);
- (*cp)++;
- return retval;
-}
-
static int moved_entry_cmp(const struct diff_options *diffopt,
const struct moved_entry *a,
const struct moved_entry *b,
const void *keydata)
{
- const char *ap = a->es->line, *ae = a->es->line + a->es->len;
- const char *bp = b->es->line, *be = b->es->line + b->es->len;
-
- if (!(diffopt->xdl_opts & XDF_WHITESPACE_FLAGS))
- return a->es->len != b->es->len || memcmp(ap, bp, a->es->len);
-
- if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_AT_EOL)) {
- while (ae > ap && isspace(*ae))
- ae--;
- while (be > bp && isspace(*be))
- be--;
- }
-
- while (1) {
- int ca, cb;
- ca = next_byte(&ap, &ae, diffopt);
- cb = next_byte(&bp, &be, diffopt);
- if (ca != cb)
- return 1;
- if (ca < 0)
- return 0;
- }
-}
-
-static unsigned get_string_hash(struct emitted_diff_symbol *es, struct diff_options *o)
-{
- if (o->xdl_opts & XDF_WHITESPACE_FLAGS) {
- static struct strbuf sb = STRBUF_INIT;
- const char *ap = es->line, *ae = es->line + es->len;
- int c;
-
- strbuf_reset(&sb);
- while (ae > ap && isspace(*ae))
- ae--;
- while ((c = next_byte(&ap, &ae, o)) > 0)
- strbuf_addch(&sb, c);
-
- return memhash(sb.buf, sb.len);
- } else {
- return memhash(es->line, es->len);
- }
+ return !xdiff_compare_lines(a->es->line, a->es->len,
+ b->es->line, b->es->len,
+ diffopt->xdl_opts);
}
static struct moved_entry *prepare_entry(struct diff_options *o,
@@ -787,7 +723,7 @@ static struct moved_entry *prepare_entry(struct diff_options *o,
struct moved_entry *ret = xmalloc(sizeof(*ret));
struct emitted_diff_symbol *l = &o->emitted_symbols->buf[line_no];
- ret->ent.hash = get_string_hash(l, o);
+ ret->ent.hash = xdiff_hash_string(l->line, l->len, o->xdl_opts);
ret->es = l;
ret->next_line = NULL;
@@ -1414,7 +1350,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 +1477,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;
@@ -2583,6 +2519,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)
@@ -3608,14 +3545,12 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
int fd;
if (lstat(s->path, &st) < 0) {
- if (errno == ENOENT) {
- err_empty:
- err = -1;
- empty:
- s->data = (char *)"";
- s->size = 0;
- return err;
- }
+ err_empty:
+ err = -1;
+ empty:
+ s->data = (char *)"";
+ s->size = 0;
+ return err;
}
s->size = xsize_t(st.st_size);
if (!s->size)
@@ -3720,7 +3655,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);
@@ -3730,18 +3664,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);
@@ -5272,6 +5206,7 @@ static void show_mode_change(struct diff_options *opt, struct diff_filepair *p,
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,6 +5224,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)
@@ -5314,6 +5250,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;