summaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c66
1 files changed, 56 insertions, 10 deletions
diff --git a/diff.c b/diff.c
index 2253ec8802..4acccd9d7e 100644
--- a/diff.c
+++ b/diff.c
@@ -2233,14 +2233,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 +2507,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) {
@@ -4593,6 +4591,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 +4916,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 +5346,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 +5610,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),
@@ -6333,6 +6353,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 +6442,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 +6475,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 +6710,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();