For instance, if you configured the `diff.algorithm` variable to a
non-default value and want to use the default one, then you
have to use `--diff-algorithm=default` option.
++
+If you explicitly choose a diff algorithm, it also bypasses
+`diff.<driver>.process` (see linkgit:gitattributes[5]).
to use this option with linkgit:git-log[1] and friends.
`--no-ext-diff`::
- Disallow external diff drivers.
+ Disallow external diff helpers, including
+ `diff.<driver>.command` and `diff.<driver>.process`
+ (see linkgit:gitattributes[5]).
`--textconv`::
`--no-textconv`::
diffs), whose protocol would have to be extended from a single old/new
pair to one comparison per merge parent.
-`--diff-algorithm` bypasses the process entirely, for every feature
-listed above. The whitespace-ignoring options (`-w`,
-`--ignore-space-change`, `--ignore-blank-lines`, and the like),
+`--no-ext-diff` and `--diff-algorithm` bypass the process entirely,
+for every feature listed above. The whitespace-ignoring options
+(`-w`, `--ignore-space-change`, `--ignore-blank-lines`, and the like),
`-I<regex>`, and `--anchored` also bypass it for the affected files:
the tool is never told about these options, so it could not honor
them, and Git falls back to the builtin diff, which does.
if (argc > 1)
die(_("unrecognized argument: %s"), argv[1]);
+ /*
+ * Disable diff.<driver>.process so that patches generated by
+ * format-patch are always based on the builtin diff algorithm
+ * and can be applied reliably.
+ */
+ rev.diffopt.flags.no_diff_process = 1;
+
if (rev.diffopt.output_format & DIFF_FORMAT_NAME)
die(_("--name-only does not make sense"));
if (rev.diffopt.output_format & DIFF_FORMAT_NAME_STATUS)
return 0;
}
+static int diff_opt_ext_diff(const struct option *opt,
+ const char *arg, int unset)
+{
+ struct diff_options *options = opt->value;
+
+ BUG_ON_OPT_ARG(arg);
+ options->flags.allow_external = !unset;
+ options->flags.no_diff_process = unset;
+ return 0;
+}
+
static int diff_opt_textconv(const struct option *opt,
const char *arg, int unset)
{
N_("exit with 1 if there were differences, 0 otherwise")),
OPT_BOOL(0, "quiet", &options->flags.quick,
N_("disable all output of the program")),
- OPT_BOOL(0, "ext-diff", &options->flags.allow_external,
- N_("allow an external diff helper to be executed")),
+ OPT_CALLBACK_F(0, "ext-diff", options, NULL,
+ N_("allow an external diff helper to be executed"),
+ PARSE_OPT_NOARG, diff_opt_ext_diff),
OPT_CALLBACK_F(0, "textconv", options, NULL,
N_("run external text conversion filters when comparing binary files"),
PARSE_OPT_NOARG, diff_opt_textconv),
*/
unsigned allow_external;
- /** Disables diff.<driver>.process. */
+ /**
+ * Disables diff.<driver>.process. Set by --no-ext-diff and by
+ * format-patch.
+ */
unsigned no_diff_process;
/**
test_path_is_missing backend.log
'
+test_expect_success 'diff process bypassed by --no-ext-diff' '
+ test_when_finished "rm -f backend.log" &&
+ git -c diff.cdiff.process="$BACKEND --log=backend.log" \
+ diff --no-ext-diff worddiff.c >actual &&
+ test_grep "return 999" actual &&
+ test_path_is_missing backend.log
+'
+
+test_expect_success 'diff process not used by format-patch' '
+ test_when_finished "rm -f backend.log" &&
+ git -c diff.cdiff.process="$BACKEND --log=backend.log" \
+ format-patch -1 --stdout -- logtest.c >actual &&
+ test_grep "return 2" actual &&
+ test_path_is_missing backend.log
+'
+
test_expect_success 'diff process bypassed under whitespace-ignoring flags' '
test_when_finished "rm -f backend.log" &&
printf "a\nb\nc\n" >wsbypass.c &&