rebase --keep-base: imply --reapply-cherry-picks
As --keep-base does not rebase the branch it is confusing if it removes commits that have been cherry-picked to the upstream branch. As --reapply-cherry-picks is not supported by the "apply" backend this commit ensures that cherry-picks are reapplied by forcing the upstream commit to match the onto commit unless --no-reapply-cherry-picks is given. Reported-by: Philippe Blain <levraiphilippeblain@gmail.com> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
d42c9ffa0f
commit
ce5238a690
@ -218,12 +218,14 @@ leave out at most one of A and B, in which case it defaults to HEAD.
|
||||
merge base of `<upstream>` and `<branch>`. Running
|
||||
`git rebase --keep-base <upstream> <branch>` is equivalent to
|
||||
running
|
||||
`git rebase --onto <upstream>...<branch> <upstream> <branch>`.
|
||||
`git rebase --reapply-cherry-picks --onto <upstream>...<branch> <upstream> <branch>`.
|
||||
+
|
||||
This option is useful in the case where one is developing a feature on
|
||||
top of an upstream branch. While the feature is being worked on, the
|
||||
upstream branch may advance and it may not be the best idea to keep
|
||||
rebasing on top of the upstream but to keep the base commit as-is.
|
||||
rebasing on top of the upstream but to keep the base commit as-is. As
|
||||
the base commit is unchanged this option implies `--reapply-cherry-picks`
|
||||
to avoid losing commits.
|
||||
+
|
||||
Although both this option and `--fork-point` find the merge base between
|
||||
`<upstream>` and `<branch>`, this option uses the merge base as the _starting
|
||||
@ -278,7 +280,8 @@ See also INCOMPATIBLE OPTIONS below.
|
||||
Note that commits which start empty are kept (unless `--no-keep-empty`
|
||||
is specified), and commits which are clean cherry-picks (as determined
|
||||
by `git log --cherry-mark ...`) are detected and dropped as a
|
||||
preliminary step (unless `--reapply-cherry-picks` is passed).
|
||||
preliminary step (unless `--reapply-cherry-picks` or `--keep-base` is
|
||||
passed).
|
||||
+
|
||||
See also INCOMPATIBLE OPTIONS below.
|
||||
|
||||
@ -311,13 +314,16 @@ See also INCOMPATIBLE OPTIONS below.
|
||||
upstream changes, the behavior towards them is controlled by
|
||||
the `--empty` flag.)
|
||||
+
|
||||
By default (or if `--no-reapply-cherry-picks` is given), these commits
|
||||
will be automatically dropped. Because this necessitates reading all
|
||||
upstream commits, this can be expensive in repos with a large number
|
||||
of upstream commits that need to be read. When using the 'merge'
|
||||
backend, warnings will be issued for each dropped commit (unless
|
||||
`--quiet` is given). Advice will also be issued unless
|
||||
`advice.skippedCherryPicks` is set to false (see linkgit:git-config[1]).
|
||||
|
||||
In the absence of `--keep-base` (or if `--no-reapply-cherry-picks` is
|
||||
given), these commits will be automatically dropped. Because this
|
||||
necessitates reading all upstream commits, this can be expensive in
|
||||
repositories with a large number of upstream commits that need to be
|
||||
read. When using the 'merge' backend, warnings will be issued for each
|
||||
dropped commit (unless `--quiet` is given). Advice will also be issued
|
||||
unless `advice.skippedCherryPicks` is set to false (see
|
||||
linkgit:git-config[1]).
|
||||
|
||||
+
|
||||
`--reapply-cherry-picks` allows rebase to forgo reading all upstream
|
||||
commits, potentially improving performance.
|
||||
|
@ -1171,6 +1171,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
prepare_repo_settings(the_repository);
|
||||
the_repository->settings.command_requires_full_index = 0;
|
||||
|
||||
options.reapply_cherry_picks = -1;
|
||||
options.allow_empty_message = 1;
|
||||
git_config(rebase_config, &options);
|
||||
/* options.gpg_sign_opt will be either "-S" or NULL */
|
||||
@ -1230,6 +1231,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
if (options.root)
|
||||
die(_("options '%s' and '%s' cannot be used together"), "--keep-base", "--root");
|
||||
}
|
||||
/*
|
||||
* --keep-base defaults to --reapply-cherry-picks to avoid losing
|
||||
* commits when using this option.
|
||||
*/
|
||||
if (options.reapply_cherry_picks < 0)
|
||||
options.reapply_cherry_picks = keep_base;
|
||||
|
||||
if (options.root && options.fork_point > 0)
|
||||
die(_("options '%s' and '%s' cannot be used together"), "--root", "--fork-point");
|
||||
@ -1406,7 +1413,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
if (options.empty != EMPTY_UNSPECIFIED)
|
||||
imply_merge(&options, "--empty");
|
||||
|
||||
if (options.reapply_cherry_picks)
|
||||
/*
|
||||
* --keep-base implements --reapply-cherry-picks by altering upstream so
|
||||
* it works with both backends.
|
||||
*/
|
||||
if (options.reapply_cherry_picks && !keep_base)
|
||||
imply_merge(&options, "--reapply-cherry-picks");
|
||||
|
||||
if (gpg_sign)
|
||||
@ -1672,6 +1683,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
||||
fill_branch_base(&options, &branch_base);
|
||||
}
|
||||
|
||||
if (keep_base && options.reapply_cherry_picks)
|
||||
options.upstream = options.onto;
|
||||
|
||||
if (options.fork_point > 0)
|
||||
options.restrict_revision =
|
||||
get_fork_point(options.upstream_name, options.orig_head);
|
||||
|
@ -199,6 +199,27 @@ test_expect_success 'rebase --keep-base requires a single merge base' '
|
||||
grep "need exactly one merge base with branch" err
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --keep-base keeps cherry picks' '
|
||||
git checkout -f -B main E &&
|
||||
git cherry-pick F &&
|
||||
(
|
||||
set_fake_editor &&
|
||||
EXPECT_COUNT=2 git rebase -i --keep-base HEAD G
|
||||
) &&
|
||||
test_cmp_rev HEAD G
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --keep-base --no-reapply-cherry-picks' '
|
||||
git checkout -f -B main E &&
|
||||
git cherry-pick F &&
|
||||
(
|
||||
set_fake_editor &&
|
||||
EXPECT_COUNT=1 git rebase -i --keep-base \
|
||||
--no-reapply-cherry-picks HEAD G
|
||||
) &&
|
||||
test_cmp_rev HEAD^ C
|
||||
'
|
||||
|
||||
# This must be the last test in this file
|
||||
test_expect_success '$EDITOR and friends are unchanged' '
|
||||
test_editor_unchanged
|
||||
|
Loading…
Reference in New Issue
Block a user