@@ -422,8 +422,23 @@ your branch contains commits which were dropped, this option can be used
with `--keep-base` in order to drop those commits from your branch.
--ignore-whitespace::
+ Ignore whitespace differences when trying to reconcile
+differences. Currently, each backend implements an approximation of
+this behavior:
++
+apply backend: When applying a patch, ignore changes in whitespace in
+context lines. Unfortunately, this means that if the "old" lines being
+replaced by the patch differ only in whitespace from the existing
+file, you will get a merge conflict instead of a successful patch
+application.
++
+merge backend: Treat lines with only whitespace changes as unchanged
+when merging. Unfortunately, this means that any patch hunks that were
+intended to modify whitespace and nothing else will be dropped, even
+if the other side had no changes that conflicted.
+
--whitespace=<option>::
- These flags are passed to the 'git apply' program
+ This flag is passed to the 'git apply' program
(see linkgit:git-apply[1]) that applies the patch.
Implies --apply.
+
@@ -572,7 +587,6 @@ The following options:
* --apply
* --committer-date-is-author-date
* --ignore-date
- * --ignore-whitespace
* --whitespace
* -C
@@ -598,6 +612,7 @@ In addition, the following pairs of options are incompatible:
* --preserve-merges and --signoff
* --preserve-merges and --rebase-merges
* --preserve-merges and --empty=
+ * --preserve-merges and --ignore-whitespace
* --keep-base and --onto
* --keep-base and --root
@@ -126,6 +126,7 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
replay.reschedule_failed_exec = opts->reschedule_failed_exec;
replay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);
replay.strategy = opts->strategy;
+
if (opts->strategy_opts)
parse_strategy_opts(&replay, opts->strategy_opts);
@@ -1466,6 +1467,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
struct strbuf revisions = STRBUF_INIT;
struct strbuf buf = STRBUF_INIT;
struct object_id merge_base;
+ int ignore_whitespace = 0;
enum action action = ACTION_NONE;
const char *gpg_sign = NULL;
struct string_list exec = STRING_LIST_INIT_NODUP;
@@ -1495,16 +1497,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
PARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },
OPT_BOOL(0, "signoff", &options.signoff,
N_("add a Signed-off-by: line to each commit")),
- OPT_PASSTHRU_ARGV(0, "ignore-whitespace", &options.git_am_opts,
- NULL, N_("passed to 'git am'"),
- PARSE_OPT_NOARG),
OPT_PASSTHRU_ARGV(0, "committer-date-is-author-date",
&options.git_am_opts, NULL,
N_("passed to 'git am'"), PARSE_OPT_NOARG),
OPT_PASSTHRU_ARGV(0, "ignore-date", &options.git_am_opts, NULL,
N_("passed to 'git am'"), PARSE_OPT_NOARG),
OPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_("n"),
N_("passed to 'git apply'"), 0),
+ OPT_BOOL(0, "ignore-whitespace", &ignore_whitespace,
+ N_("ignore changes in whitespace")),
OPT_PASSTHRU_ARGV(0, "whitespace", &options.git_am_opts,
N_("action"), N_("passed to 'git apply'"), 0),
OPT_BIT('f', "force-rebase", &options.flags,
@@ -1850,6 +1851,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
imply_merge(&options, "--rebase-merges");
}
+ if (options.type == REBASE_APPLY) {
+ if (ignore_whitespace)
+ argv_array_push(&options.git_am_opts,
+ "--ignore-whitespace");
+ } else {
+ /* REBASE_MERGE and PRESERVE_MERGES */
+ if (ignore_whitespace) {
+ string_list_append(&strategy_options,
+ "ignore-space-change");
+ }
+ }
+
if (strategy_options.nr) {
int i;
@@ -61,7 +61,6 @@ test_rebase_am_only () {
}
test_rebase_am_only --whitespace=fix
-test_rebase_am_only --ignore-whitespace
test_rebase_am_only --committer-date-is-author-date
test_rebase_am_only -C4
new file mode 100755
@@ -0,0 +1,60 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Rohit Ashiwal
+#
+
+test_description='tests to ensure compatibility between am and interactive backends'
+
+. ./test-lib.sh
+
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+# This is a special case in which both am and interactive backends
+# provide the same output. It was done intentionally because
+# both the backends fall short of optimal behaviour.
+test_expect_success 'setup' '
+ git checkout -b topic &&
+ test_write_lines "line 1" " line 2" "line 3" >file &&
+ git add file &&
+ git commit -m "add file" &&
+
+ test_write_lines "line 1" "new line 2" "line 3" >file &&
+ git commit -am "update file" &&
+ git tag side &&
+
+ git checkout --orphan master &&
+ test_write_lines "line 1" " line 2" "line 3" >file &&
+ git commit -am "add file" &&
+ git tag main
+'
+
+test_expect_success '--ignore-whitespace works with apply backend' '
+ test_must_fail git rebase --apply main side &&
+ git rebase --abort &&
+ git rebase --apply --ignore-whitespace main side &&
+ git diff --exit-code side
+'
+
+test_expect_success '--ignore-whitespace works with merge backend' '
+ test_must_fail git rebase --merge main side &&
+ git rebase --abort &&
+ git rebase --merge --ignore-whitespace main side &&
+ git diff --exit-code side
+'
+
+test_expect_success '--ignore-whitespace is remembered when continuing' '
+ (
+ set_fake_editor &&
+ FAKE_LINES="break 1" git rebase -i --ignore-whitespace \
+ main side &&
+ git rebase --continue
+ ) &&
+ git diff --exit-code side
+'
+
+# This must be the last test in this file
+test_expect_success '$EDITOR and friends are unchanged' '
+ test_editor_unchanged
+'
+
+test_done