Skip to content

Commit e1fac53

Browse files
dschogitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a63f990 commit e1fac53

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

builtin/rebase.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ struct rebase_options {
6262
const char *onto_name;
6363
const char *revisions;
6464
const char *switch_to;
65-
int root;
65+
int root, root_with_onto;
6666
struct object_id *squash_onto;
6767
struct commit *restrict_revision;
6868
int dont_finish_rebase;
@@ -374,6 +374,7 @@ static int run_rebase_interactive(struct rebase_options *opts,
374374
flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0;
375375
flags |= opts->rebase_merges ? TODO_LIST_REBASE_MERGES : 0;
376376
flags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;
377+
flags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;
377378
flags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
378379

379380
switch (command) {
@@ -1841,7 +1842,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
18411842
options.squash_onto = &squash_onto;
18421843
options.onto_name = squash_onto_name =
18431844
xstrdup(oid_to_hex(&squash_onto));
1844-
}
1845+
} else
1846+
options.root_with_onto = 1;
1847+
18451848
options.upstream_name = NULL;
18461849
options.upstream = NULL;
18471850
if (argc > 1)

sequencer.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4440,6 +4440,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
44404440
{
44414441
int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
44424442
int rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;
4443+
int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;
44434444
struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;
44444445
struct strbuf label = STRBUF_INIT;
44454446
struct commit_list *commits = NULL, **tail = &commits, *iter;
@@ -4606,7 +4607,8 @@ static int make_script_with_merges(struct pretty_print_context *pp,
46064607

46074608
if (!commit)
46084609
strbuf_addf(out, "%s %s\n", cmd_reset,
4609-
rebase_cousins ? "onto" : "[new root]");
4610+
rebase_cousins || root_with_onto ?
4611+
"onto" : "[new root]");
46104612
else {
46114613
const char *to = NULL;
46124614

sequencer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,12 @@ int sequencer_remove_state(struct replay_opts *opts);
142142
*/
143143
#define TODO_LIST_REBASE_COUSINS (1U << 4)
144144
#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+
145151

146152
int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
147153
const char **argv, unsigned flags);

t/t3427-rebase-subtree.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,15 @@ test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' '
9393
verbose test "$(commit_message HEAD)" = "Empty commit"
9494
'
9595

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+
96107
test_done

0 commit comments

Comments
 (0)