summaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c82
1 files changed, 66 insertions, 16 deletions
diff --git a/diff.c b/diff.c
index 2253ec8802..52c791574b 100644
--- a/diff.c
+++ b/diff.c
@@ -2053,7 +2053,7 @@ static void fn_out_diff_words_aux(void *priv,
static int find_word_boundaries(mmfile_t *buffer, regex_t *word_regex,
int *begin, int *end)
{
- if (word_regex && *begin < buffer->size) {
+ while (word_regex && *begin < buffer->size) {
regmatch_t match[1];
if (!regexec_buf(word_regex, buffer->ptr + *begin,
buffer->size - *begin, 1, match, 0)) {
@@ -2061,9 +2061,13 @@ static int find_word_boundaries(mmfile_t *buffer, regex_t *word_regex,
'\n', match[0].rm_eo - match[0].rm_so);
*end = p ? p - buffer->ptr : match[0].rm_eo + *begin;
*begin += match[0].rm_so;
- return *begin >= *end;
+ if (*begin == *end)
+ (*begin)++;
+ else
+ return *begin > *end;
+ } else {
+ return -1;
}
- return -1;
}
/* find the next word */
@@ -2233,14 +2237,12 @@ static void init_diff_words_data(struct emit_callback *ecbdata,
struct diff_options *o = xmalloc(sizeof(struct diff_options));
memcpy(o, orig_opts, sizeof(struct diff_options));
- ecbdata->diff_words =
- xcalloc(1, sizeof(struct diff_words_data));
+ CALLOC_ARRAY(ecbdata->diff_words, 1);
ecbdata->diff_words->type = o->word_diff;
ecbdata->diff_words->opt = o;
if (orig_opts->emitted_symbols)
- o->emitted_symbols =
- xcalloc(1, sizeof(struct emitted_diff_symbols));
+ CALLOC_ARRAY(o->emitted_symbols, 1);
if (!o->word_regex)
o->word_regex = userdiff_word_regex(one, o->repo->index);
@@ -2509,7 +2511,7 @@ static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
const char *name_b)
{
struct diffstat_file *x;
- x = xcalloc(1, sizeof(*x));
+ CALLOC_ARRAY(x, 1);
ALLOC_GROW(diffstat->files, diffstat->nr + 1, diffstat->alloc);
diffstat->files[diffstat->nr++] = x;
if (name_b) {
@@ -4192,7 +4194,7 @@ static struct diff_tempfile *prepare_temp_file(struct repository *r,
die_errno("readlink(%s)", name);
prep_temp_blob(r->index, name, temp, sb.buf, sb.len,
(one->oid_valid ?
- &one->oid : &null_oid),
+ &one->oid : null_oid()),
(one->oid_valid ?
one->mode : S_IFLNK));
strbuf_release(&sb);
@@ -4201,7 +4203,7 @@ static struct diff_tempfile *prepare_temp_file(struct repository *r,
/* we can borrow from the file in the work tree */
temp->name = name;
if (!one->oid_valid)
- oid_to_hex_r(temp->hex, &null_oid);
+ oid_to_hex_r(temp->hex, null_oid());
else
oid_to_hex_r(temp->hex, &one->oid);
/* Even though we may sometimes borrow the
@@ -4593,6 +4595,9 @@ void repo_diff_setup(struct repository *r, struct diff_options *options)
options->orderfile = diff_order_file_cfg;
+ if (!options->flags.ignore_submodule_set)
+ options->flags.ignore_untracked_in_submodules = 1;
+
if (diff_no_prefix) {
options->a_prefix = options->b_prefix = "";
} else if (!diff_mnemonic_prefix) {
@@ -4915,7 +4920,7 @@ static int diff_opt_find_object(const struct option *option,
return error(_("unable to resolve '%s'"), arg);
if (!opt->objfind)
- opt->objfind = xcalloc(1, sizeof(*opt->objfind));
+ CALLOC_ARRAY(opt->objfind, 1);
opt->pickaxe_opts |= DIFF_PICKAXE_KIND_OBJFIND;
opt->flags.recursive = 1;
@@ -5345,6 +5350,19 @@ static int diff_opt_word_diff_regex(const struct option *opt,
return 0;
}
+static int diff_opt_rotate_to(const struct option *opt, const char *arg, int unset)
+{
+ struct diff_options *options = opt->value;
+
+ BUG_ON_OPT_NEG(unset);
+ if (!strcmp(opt->long_name, "skip-to"))
+ options->skip_instead_of_rotate = 1;
+ else
+ options->skip_instead_of_rotate = 0;
+ options->rotate_to = arg;
+ return 0;
+}
+
static void prep_parse_options(struct diff_options *options)
{
struct option parseopts[] = {
@@ -5596,6 +5614,12 @@ static void prep_parse_options(struct diff_options *options)
DIFF_PICKAXE_REGEX, PARSE_OPT_NONEG),
OPT_FILENAME('O', NULL, &options->orderfile,
N_("control the order in which files appear in the output")),
+ OPT_CALLBACK_F(0, "rotate-to", options, N_("<path>"),
+ N_("show the change in the specified path first"),
+ PARSE_OPT_NONEG, diff_opt_rotate_to),
+ OPT_CALLBACK_F(0, "skip-to", options, N_("<path>"),
+ N_("skip the output to the specified path"),
+ PARSE_OPT_NONEG, diff_opt_rotate_to),
OPT_CALLBACK_F(0, "find-object", options, N_("<object-id>"),
N_("look for differences that change the number of occurrences of the specified object"),
PARSE_OPT_NONEG, diff_opt_find_object),
@@ -6214,7 +6238,7 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
}
if (!stable)
- the_hash_algo->final_fn(oid->hash, &ctx);
+ the_hash_algo->final_oid_fn(oid, &ctx);
return 0;
}
@@ -6333,6 +6357,32 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
}
}
+static void diff_free_file(struct diff_options *options)
+{
+ if (options->close_file)
+ fclose(options->file);
+}
+
+static void diff_free_ignore_regex(struct diff_options *options)
+{
+ int i;
+
+ for (i = 0; i < options->ignore_regex_nr; i++) {
+ regfree(options->ignore_regex[i]);
+ free(options->ignore_regex[i]);
+ }
+ free(options->ignore_regex);
+}
+
+void diff_free(struct diff_options *options)
+{
+ if (options->no_free)
+ return;
+
+ diff_free_file(options);
+ diff_free_ignore_regex(options);
+}
+
void diff_flush(struct diff_options *options)
{
struct diff_queue_struct *q = &diff_queued_diff;
@@ -6396,8 +6446,7 @@ void diff_flush(struct diff_options *options)
* options->file to /dev/null should be safe, because we
* aren't supposed to produce any output anyway.
*/
- if (options->close_file)
- fclose(options->file);
+ diff_free_file(options);
options->file = xfopen("/dev/null", "w");
options->close_file = 1;
options->color_moved = 0;
@@ -6430,8 +6479,7 @@ void diff_flush(struct diff_options *options)
free_queue:
free(q->queue);
DIFF_QUEUE_CLEAR(q);
- if (options->close_file)
- fclose(options->file);
+ diff_free(options);
/*
* Report the content-level differences with HAS_CHANGES;
@@ -6666,6 +6714,8 @@ void diffcore_std(struct diff_options *options)
diffcore_pickaxe(options);
if (options->orderfile)
diffcore_order(options->orderfile);
+ if (options->rotate_to)
+ diffcore_rotate(options);
if (!options->found_follow)
/* See try_to_follow_renames() in tree-diff.c */
diff_resolve_rename_copy();