Skip to content

Commit ba51d2f

Browse files
r1walzgitster
authored andcommitted
rebase -i: add --ignore-whitespace flag
There are two backends available for rebasing, viz, the am and the interactive. Naturally, there shall be some features that are implemented in one but not in the other. One such flag is --ignore-whitespace which indicates merge mechanism to treat lines with only whitespace changes as unchanged. Wire the interactive rebase to also understand the --ignore-whitespace flag by translating it to -Xignore-space-change. Signed-off-by: Rohit Ashiwal <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b0a3186 commit ba51d2f

File tree

4 files changed

+90
-7
lines changed

4 files changed

+90
-7
lines changed

Documentation/git-rebase.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,16 @@ If either <upstream> or --root is given on the command line, then the
371371
default is `--no-fork-point`, otherwise the default is `--fork-point`.
372372

373373
--ignore-whitespace::
374+
Behaves differently depending on which backend is selected.
375+
+
376+
'am' backend: When applying a patch, ignore changes in whitespace in
377+
context lines if necessary.
378+
+
379+
'interactive' backend: Treat lines with only whitespace changes as
380+
unchanged for the sake of a three-way merge.
381+
374382
--whitespace=<option>::
375-
These flag are passed to the 'git apply' program
383+
This flag is passed to the 'git apply' program
376384
(see linkgit:git-apply[1]) that applies the patch.
377385
+
378386
See also INCOMPATIBLE OPTIONS below.
@@ -520,7 +528,6 @@ The following options:
520528
* --committer-date-is-author-date
521529
* --ignore-date
522530
* --whitespace
523-
* --ignore-whitespace
524531
* -C
525532

526533
are incompatible with the following options:
@@ -543,6 +550,7 @@ In addition, the following pairs of options are incompatible:
543550
* --preserve-merges and --interactive
544551
* --preserve-merges and --signoff
545552
* --preserve-merges and --rebase-merges
553+
* --preserve-merges and --ignore-whitespace
546554
* --rebase-merges and --strategy
547555
* --rebase-merges and --strategy-option
548556

builtin/rebase.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct rebase_options {
7979
int allow_rerere_autoupdate;
8080
int keep_empty;
8181
int autosquash;
82+
int ignore_whitespace;
8283
char *gpg_sign_opt;
8384
int autostash;
8485
char *cmd;
@@ -99,6 +100,7 @@ struct rebase_options {
99100

100101
static struct replay_opts get_replay_opts(const struct rebase_options *opts)
101102
{
103+
struct strbuf strategy_buf = STRBUF_INIT;
102104
struct replay_opts replay = REPLAY_OPTS_INIT;
103105

104106
replay.action = REPLAY_INTERACTIVE_REBASE;
@@ -114,9 +116,15 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
114116
replay.reschedule_failed_exec = opts->reschedule_failed_exec;
115117
replay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);
116118
replay.strategy = opts->strategy;
119+
117120
if (opts->strategy_opts)
118-
parse_strategy_opts(&replay, opts->strategy_opts);
121+
strbuf_addstr(&strategy_buf, opts->strategy_opts);
122+
if (opts->ignore_whitespace)
123+
strbuf_addstr(&strategy_buf, " --ignore-space-change");
124+
if (strategy_buf.len)
125+
parse_strategy_opts(&replay, strategy_buf.buf);
119126

127+
strbuf_release(&strategy_buf);
120128
return replay;
121129
}
122130

@@ -511,6 +519,8 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
511519
argc = parse_options(argc, argv, NULL, options,
512520
builtin_rebase_interactive_usage, PARSE_OPT_KEEP_ARGV0);
513521

522+
opts.strategy_opts = xstrdup_or_null(opts.strategy_opts);
523+
514524
if (!is_null_oid(&squash_onto))
515525
opts.squash_onto = &squash_onto;
516526

@@ -964,6 +974,8 @@ static int run_am(struct rebase_options *opts)
964974
am.git_cmd = 1;
965975
argv_array_push(&am.args, "am");
966976

977+
if (opts->ignore_whitespace)
978+
argv_array_push(&am.args, "--ignore-whitespace");
967979
if (opts->action && !strcmp("continue", opts->action)) {
968980
argv_array_push(&am.args, "--resolved");
969981
argv_array_pushf(&am.args, "--resolvemsg=%s", resolvemsg);
@@ -1412,16 +1424,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
14121424
PARSE_OPT_NOARG, NULL, REBASE_DIFFSTAT },
14131425
OPT_BOOL(0, "signoff", &options.signoff,
14141426
N_("add a Signed-off-by: line to each commit")),
1415-
OPT_PASSTHRU_ARGV(0, "ignore-whitespace", &options.git_am_opts,
1416-
NULL, N_("passed to 'git am'"),
1417-
PARSE_OPT_NOARG),
14181427
OPT_PASSTHRU_ARGV(0, "committer-date-is-author-date",
14191428
&options.git_am_opts, NULL,
14201429
N_("passed to 'git am'"), PARSE_OPT_NOARG),
14211430
OPT_PASSTHRU_ARGV(0, "ignore-date", &options.git_am_opts, NULL,
14221431
N_("passed to 'git am'"), PARSE_OPT_NOARG),
14231432
OPT_PASSTHRU_ARGV('C', NULL, &options.git_am_opts, N_("n"),
14241433
N_("passed to 'git apply'"), 0),
1434+
OPT_BOOL(0, "ignore-whitespace", &options.ignore_whitespace,
1435+
N_("ignore changes in whitespace")),
14251436
OPT_PASSTHRU_ARGV(0, "whitespace", &options.git_am_opts,
14261437
N_("action"), N_("passed to 'git apply'"), 0),
14271438
OPT_BIT('f', "force-rebase", &options.flags,

t/t3422-rebase-incompatible-options.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ test_rebase_am_only () {
6161
}
6262

6363
test_rebase_am_only --whitespace=fix
64-
test_rebase_am_only --ignore-whitespace
6564
test_rebase_am_only --committer-date-is-author-date
6665
test_rebase_am_only -C4
6766

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2019 Rohit Ashiwal
4+
#
5+
6+
test_description='tests to ensure compatibility between am and interactive backends'
7+
8+
. ./test-lib.sh
9+
10+
# This is a special case in which both am and interactive backends
11+
# provide the same output. It was done intentionally because
12+
# both the backends fall short of optimal behaviour.
13+
test_expect_success 'setup' '
14+
git checkout -b topic &&
15+
q_to_tab >file <<-\EOF &&
16+
line 1
17+
Qline 2
18+
line 3
19+
EOF
20+
git add file &&
21+
git commit -m "add file" &&
22+
cat >file <<-\EOF &&
23+
line 1
24+
new line 2
25+
line 3
26+
EOF
27+
git commit -am "update file" &&
28+
git tag side &&
29+
30+
git checkout --orphan master &&
31+
sed -e "s/^|//" >file <<-\EOF &&
32+
|line 1
33+
| line 2
34+
|line 3
35+
EOF
36+
git add file &&
37+
git commit -m "add file" &&
38+
git tag main
39+
'
40+
41+
test_expect_success '--ignore-whitespace works with am backend' '
42+
cat >expect <<-\EOF &&
43+
line 1
44+
new line 2
45+
line 3
46+
EOF
47+
test_must_fail git rebase main side &&
48+
git rebase --abort &&
49+
git rebase --ignore-whitespace main side &&
50+
test_cmp expect file
51+
'
52+
53+
test_expect_success '--ignore-whitespace works with interactive backend' '
54+
cat >expect <<-\EOF &&
55+
line 1
56+
new line 2
57+
line 3
58+
EOF
59+
test_must_fail git rebase --merge main side &&
60+
git rebase --abort &&
61+
git rebase --merge --ignore-whitespace main side &&
62+
test_cmp expect file
63+
'
64+
65+
test_done

0 commit comments

Comments
 (0)