rebase: add a config option for --no-fork-point
Some users (myself included) would prefer to have this feature off by default because it can silently drop commits. Signed-off-by: Alex Henrie <alexhenrie24@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Alex Henrie committed
Feb 23, 2021 at 00:18 UTC
2803d800d2268cde4b932fab38dffe6712d86d16
3 files changed
+61
-17
Documentation/config/rebase.txt
+3
@@ -68,3 +68,6 @@ rebase.rescheduleFailedExec::
68
Automatically reschedule `exec` commands that failed. This only makes
69
sense in interactive mode (or when an `--exec` option was provided).
70
This is the same as specifying the `--reschedule-failed-exec` option.
71
+
72
+rebase.forkPoint::
73
+ If set to false set `--no-fork-point` option by default.
builtin/rebase.c
+13
-7
@@ -102,6 +102,7 @@ struct rebase_options {
102
int reschedule_failed_exec;
103
int use_legacy_rebase;
104
int reapply_cherry_picks;
105
+ int fork_point;
106
};
107
108
#define REBASE_OPTIONS_INIT { \
@@ -111,7 +112,8 @@ struct rebase_options {
112
.default_backend = "merge", \
113
.flags = REBASE_NO_QUIET, \
114
.git_am_opts = STRVEC_INIT, \
114
- .git_format_patch_opt = STRBUF_INIT \
115
+ .git_format_patch_opt = STRBUF_INIT, \
116
+ .fork_point = -1, \
117
}
118
119
static struct replay_opts get_replay_opts(const struct rebase_options *opts)
@@ -1095,6 +1097,11 @@ static int rebase_config(const char *var, const char *value, void *data)
1097
return 0;
1098
}
1099
1100
+ if (!strcmp(var, "rebase.forkpoint")) {
1101
+ opts->fork_point = git_config_bool(var, value) ? -1 : 0;
1102
+ return 0;
1103
+ }
1104
+
1105
if (!strcmp(var, "rebase.usebuiltin")) {
1106
opts->use_legacy_rebase = !git_config_bool(var, value);
1107
return 0;
@@ -1306,7 +1313,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1313
const char *gpg_sign = NULL;
1314
struct string_list exec = STRING_LIST_INIT_NODUP;
1315
const char *rebase_merges = NULL;
1309
- int fork_point = -1;
1316
struct string_list strategy_options = STRING_LIST_INIT_NODUP;
1317
struct object_id squash_onto;
1318
char *squash_onto_name = NULL;
@@ -1406,7 +1412,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1412
N_("mode"),
1413
N_("try to rebase merges instead of skipping them"),
1414
PARSE_OPT_OPTARG, NULL, (intptr_t)""},
1409
- OPT_BOOL(0, "fork-point", &fork_point,
1415
+ OPT_BOOL(0, "fork-point", &options.fork_point,
1416
N_("use 'merge-base --fork-point' to refine upstream")),
1417
OPT_STRING('s', "strategy", &options.strategy,
1418
N_("strategy"), N_("use the given merge strategy")),
@@ -1494,7 +1500,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1500
die(_("cannot combine '--keep-base' with '--root'"));
1501
}
1502
1497
- if (options.root && fork_point > 0)
1503
+ if (options.root && options.fork_point > 0)
1504
die(_("cannot combine '--root' with '--fork-point'"));
1505
1506
if (action != ACTION_NONE && !in_progress)
@@ -1840,8 +1846,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1846
NULL);
1847
if (!options.upstream_name)
1848
error_on_missing_default_upstream();
1843
- if (fork_point < 0)
1844
- fork_point = 1;
1849
+ if (options.fork_point < 0)
1850
+ options.fork_point = 1;
1851
} else {
1852
options.upstream_name = argv[0];
1853
argc--;
@@ -1945,7 +1951,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1951
} else
1952
BUG("unexpected number of arguments left to parse");
1953
1948
- if (fork_point > 0) {
1954
+ if (options.fork_point > 0) {
1955
struct commit *head =
1956
lookup_commit_reference(the_repository,
1957
&options.orig_head);
t/t3431-rebase-fork-point.sh
+45
-10
@@ -26,19 +26,23 @@ test_expect_success setup '
26
test_commit G
27
'
28
29
+do_test_rebase () {
30
+ expected="$1" &&
31
+ shift &&
32
+ git checkout master &&
33
+ git reset --hard E &&
34
+ git checkout side &&
35
+ git reset --hard G &&
36
+ git rebase $* &&
37
+ test_write_lines $expected >expect &&
38
+ git log --pretty=%s >actual &&
39
+ test_cmp expect actual
40
+}
41
+
42
test_rebase () {
43
expected="$1" &&
44
shift &&
32
- test_expect_success "git rebase $*" "
33
- git checkout master &&
34
- git reset --hard E &&
35
- git checkout side &&
36
- git reset --hard G &&
37
- git rebase $* &&
38
- test_write_lines $expected >expect &&
39
- git log --pretty=%s >actual &&
40
- test_cmp expect actual
41
- "
45
+ test_expect_success "git rebase $*" "do_test_rebase '$expected' $*"
46
}
47
48
test_rebase 'G F E D B A'
@@ -74,4 +78,35 @@ test_expect_success 'git rebase --fork-point with ambigous refname' '
78
test_must_fail git rebase --fork-point --onto D one
79
'
80
81
+test_expect_success '--fork-point and --root both given' '
82
+ test_must_fail git rebase --fork-point --root 2>err &&
83
+ test_i18ngrep "cannot combine" err
84
+'
85
+
86
+test_expect_success 'rebase.forkPoint set to false' '
87
+ test_config rebase.forkPoint false &&
88
+ do_test_rebase "G F C E D B A"
89
+'
90
+
91
+test_expect_success 'rebase.forkPoint set to false and then to true' '
92
+ test_config_global rebase.forkPoint false &&
93
+ test_config rebase.forkPoint true &&
94
+ do_test_rebase "G F E D B A"
95
+'
96
+
97
+test_expect_success 'rebase.forkPoint set to false and command line says --fork-point' '
98
+ test_config rebase.forkPoint false &&
99
+ do_test_rebase "G F E D B A" --fork-point
100
+'
101
+
102
+test_expect_success 'rebase.forkPoint set to true and command line says --no-fork-point' '
103
+ test_config rebase.forkPoint true &&
104
+ do_test_rebase "G F C E D B A" --no-fork-point
105
+'
106
+
107
+test_expect_success 'rebase.forkPoint set to true and --root given' '
108
+ test_config rebase.forkPoint true &&
109
+ git rebase --root
110
+'
111
+
112
test_done