rebase: provide better error message for apply options vs. merge config
When config which selects the merge backend (currently, rebase.autosquash=true or rebase.updateRefs=true) conflicts with other options on the command line (such as --whitespace=fix), make the error message specifically call out the config option and specify how to override that config option on the command line. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Elijah Newren committed
Jan 25, 2023 at 04:03 UTC
eddfcd8eced9b9f840491064b35a3956f959fd12
3 files changed
+46
-7
Documentation/git-rebase.txt
+1
-1
@@ -648,7 +648,7 @@ are incompatible with the following options:
648
* --merge
649
* --strategy
650
* --strategy-option
651
- * --[no-]autosquash
651
+ * --autosquash
652
* --rebase-merges
653
* --interactive
654
* --exec
builtin/rebase.c
+21
-6
@@ -122,6 +122,8 @@ struct rebase_options {
122
int reapply_cherry_picks;
123
int fork_point;
124
int update_refs;
125
+ int config_autosquash;
126
+ int config_update_refs;
127
};
128
129
#define REBASE_OPTIONS_INIT { \
@@ -136,6 +138,10 @@ struct rebase_options {
138
.fork_point = -1, \
139
.reapply_cherry_picks = -1, \
140
.allow_empty_message = 1, \
141
+ .autosquash = -1, \
142
+ .config_autosquash = -1, \
143
+ .update_refs = -1, \
144
+ .config_update_refs = -1, \
145
}
146
147
static struct replay_opts get_replay_opts(const struct rebase_options *opts)
@@ -778,7 +784,7 @@ static int rebase_config(const char *var, const char *value, void *data)
784
}
785
786
if (!strcmp(var, "rebase.autosquash")) {
781
- opts->autosquash = git_config_bool(var, value);
787
+ opts->config_autosquash = git_config_bool(var, value);
788
return 0;
789
}
790
@@ -795,7 +801,7 @@ static int rebase_config(const char *var, const char *value, void *data)
801
}
802
803
if (!strcmp(var, "rebase.updaterefs")) {
798
- opts->update_refs = git_config_bool(var, value);
804
+ opts->config_update_refs = git_config_bool(var, value);
805
return 0;
806
}
807
@@ -1366,7 +1372,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1372
if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||
1373
(options.action != ACTION_NONE) ||
1374
(options.exec.nr > 0) ||
1369
- options.autosquash) {
1375
+ (options.autosquash == -1 && options.config_autosquash == 1) ||
1376
+ options.autosquash == 1) {
1377
allow_preemptive_ff = 0;
1378
}
1379
if (options.committer_date_is_author_date || options.ignore_date)
@@ -1499,20 +1506,28 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1506
if (strcmp(options.git_am_opts.v[i], "-q"))
1507
break;
1508
1502
- if (i >= 0) {
1509
+ if (i >= 0 || options.type == REBASE_APPLY) {
1510
if (is_merge(&options))
1511
die(_("apply options and merge options "
1512
"cannot be used together"));
1513
+ else if (options.autosquash == -1 && options.config_autosquash == 1)
1514
+ die(_("apply options are incompatible with rebase.autosquash. Consider adding --no-autosquash"));
1515
+ else if (options.update_refs == -1 && options.config_update_refs == 1)
1516
+ die(_("apply options are incompatible with rebase.updateRefs. Consider adding --no-update-refs"));
1517
else
1518
options.type = REBASE_APPLY;
1519
}
1520
}
1521
1511
- if (options.update_refs)
1522
+ if (options.update_refs == 1)
1523
imply_merge(&options, "--update-refs");
1524
+ options.update_refs = (options.update_refs >= 0) ? options.update_refs :
1525
+ ((options.config_update_refs >= 0) ? options.config_update_refs : 0);
1526
1514
- if (options.autosquash)
1527
+ if (options.autosquash == 1)
1528
imply_merge(&options, "--autosquash");
1529
+ options.autosquash = (options.autosquash >= 0) ? options.autosquash :
1530
+ ((options.config_autosquash >= 0) ? options.config_autosquash : 0);
1531
1532
if (options.type == REBASE_UNSPECIFIED) {
1533
if (!strcmp(options.default_backend, "merge"))
t/t3422-rebase-incompatible-options.sh
+24
@@ -94,6 +94,30 @@ test_rebase_am_only () {
94
git checkout B^0 &&
95
test_must_fail git rebase $opt --root A
96
"
97
+
98
+ test_expect_success "$opt incompatible with rebase.autosquash" "
99
+ git checkout B^0 &&
100
+ test_must_fail git -c rebase.autosquash=true rebase $opt A 2>err &&
101
+ grep -e --no-autosquash err
102
+ "
103
+
104
+ test_expect_success "$opt incompatible with rebase.updateRefs" "
105
+ git checkout B^0 &&
106
+ test_must_fail git -c rebase.updateRefs=true rebase $opt A 2>err &&
107
+ grep -e --no-update-refs err
108
+ "
109
+
110
+ test_expect_success "$opt okay with overridden rebase.autosquash" "
111
+ test_when_finished \"git reset --hard B^0\" &&
112
+ git checkout B^0 &&
113
+ git -c rebase.autosquash=true rebase --no-autosquash $opt A
114
+ "
115
+
116
+ test_expect_success "$opt okay with overridden rebase.updateRefs" "
117
+ test_when_finished \"git reset --hard B^0\" &&
118
+ git checkout B^0 &&
119
+ git -c rebase.updateRefs=true rebase --no-update-refs $opt A
120
+ "
121
}
122
123
# Check options which imply --apply