rebase -r: do not (re-)generate root commits with `--root` *and* `--onto`
When rebasing a complete commit history onto a given commit, it is pretty obvious that the root commits should be rebased on top of said given commit. To test this, let's kill two birds with one stone and add a test case to t3427-rebase-subtree.sh that not only demonstrates that this works, but also that `git rebase -r` works with merge strategies now. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Jul 31, 2019 at 08:18 UTC
e1fac531ea9f9dc710f6eeae37ea2b38dd5f9fae
4 files changed
+25
-3
builtin/rebase.c
+5
-2
@@ -62,7 +62,7 @@ struct rebase_options {
62
const char *onto_name;
63
const char *revisions;
64
const char *switch_to;
65
- int root;
65
+ int root, root_with_onto;
66
struct object_id *squash_onto;
67
struct commit *restrict_revision;
68
int dont_finish_rebase;
@@ -374,6 +374,7 @@ static int run_rebase_interactive(struct rebase_options *opts,
374
flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0;
375
flags |= opts->rebase_merges ? TODO_LIST_REBASE_MERGES : 0;
376
flags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;
377
+ flags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;
378
flags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
379
380
switch (command) {
@@ -1841,7 +1842,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1842
options.squash_onto = &squash_onto;
1843
options.onto_name = squash_onto_name =
1844
xstrdup(oid_to_hex(&squash_onto));
1844
- }
1845
+ } else
1846
+ options.root_with_onto = 1;
1847
+
1848
options.upstream_name = NULL;
1849
options.upstream = NULL;
1850
if (argc > 1)
sequencer.c
+3
-1
@@ -4440,6 +4440,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
4440
{
4441
int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
4442
int rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;
4443
+ int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;
4444
struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;
4445
struct strbuf label = STRBUF_INIT;
4446
struct commit_list *commits = NULL, **tail = &commits, *iter;
@@ -4606,7 +4607,8 @@ static int make_script_with_merges(struct pretty_print_context *pp,
4607
4608
if (!commit)
4609
strbuf_addf(out, "%s %s\n", cmd_reset,
4609
- rebase_cousins ? "onto" : "[new root]");
4610
+ rebase_cousins || root_with_onto ?
4611
+ "onto" : "[new root]");
4612
else {
4613
const char *to = NULL;
4614
sequencer.h
+6
@@ -142,6 +142,12 @@ int sequencer_remove_state(struct replay_opts *opts);
142
*/
143
#define TODO_LIST_REBASE_COUSINS (1U << 4)
144
#define TODO_LIST_APPEND_TODO_HELP (1U << 5)
145
+/*
146
+ * When generating a script that rebases merges with `--root` *and* with
147
+ * `--onto`, we do not want to re-generate the root commits.
148
+ */
149
+#define TODO_LIST_ROOT_WITH_ONTO (1U << 6)
150
+
151
152
int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
153
const char **argv, unsigned flags);
t/t3427-rebase-subtree.sh
+11
@@ -93,4 +93,15 @@ test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '
93
verbose test "$(commit_message HEAD)" = "Empty commit"
94
'
95
96
+test_expect_success 'Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' '
97
+ reset_rebase &&
98
+ git checkout -b rebase-merges-onto to-rebase &&
99
+ test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root &&
100
+ : first pick results in no changes &&
101
+ git rebase --continue &&
102
+ verbose test "$(commit_message HEAD~2)" = "master4" &&
103
+ verbose test "$(commit_message HEAD~)" = "files_subtree/master5" &&
104
+ verbose test "$(commit_message HEAD)" = "Empty commit"
105
+'
106
+
107
test_done