Skip to content

Commit 767a4ca

Browse files
steadmongitster
authored andcommitted
sequencer: advise if skipping cherry-picked commit
Silently skipping commits when rebasing with --no-reapply-cherry-picks (currently the default behavior) can cause user confusion. Issue warnings when this happens, as well as advice on how to preserve the skipped commits. These warnings and advice are displayed only when using the (default) "merge" rebase backend. Update the git-rebase docs to mention the warnings and advice. Signed-off-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 2d755df commit 767a4ca

File tree

7 files changed

+38
-6
lines changed

7 files changed

+38
-6
lines changed

Documentation/config/advice.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ advice.*::
4444
Shown when linkgit:git-push[1] rejects a forced update of
4545
a branch when its remote-tracking ref has updates that we
4646
do not have locally.
47+
skippedCherryPicks::
48+
Shown when linkgit:git-rebase[1] skips a commit that has already
49+
been cherry-picked onto the upstream branch.
4750
statusAheadBehind::
4851
Shown when linkgit:git-status[1] computes the ahead/behind
4952
counts for a local ref compared to its remote tracking ref,

Documentation/git-rebase.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,10 @@ remain the checked-out branch.
7979

8080
If the upstream branch already contains a change you have made (e.g.,
8181
because you mailed a patch which was applied upstream), then that commit
82-
will be skipped. For example, running `git rebase master` on the
83-
following history (in which `A'` and `A` introduce the same set of changes,
84-
but have different committer information):
82+
will be skipped and warnings will be issued (if the `merge` backend is
83+
used). For example, running `git rebase master` on the following
84+
history (in which `A'` and `A` introduce the same set of changes, but
85+
have different committer information):
8586

8687
------------
8788
A---B---C topic
@@ -312,7 +313,10 @@ See also INCOMPATIBLE OPTIONS below.
312313
By default (or if `--no-reapply-cherry-picks` is given), these commits
313314
will be automatically dropped. Because this necessitates reading all
314315
upstream commits, this can be expensive in repos with a large number
315-
of upstream commits that need to be read.
316+
of upstream commits that need to be read. When using the `merge`
317+
backend, warnings will be issued for each dropped commit (unless
318+
`--quiet` is given). Advice will also be issued unless
319+
`advice.skippedCherryPicks` is set to false (see linkgit:git-config[1]).
316320
+
317321
`--reapply-cherry-picks` allows rebase to forgo reading all upstream
318322
commits, potentially improving performance.

advice.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ int advice_checkout_ambiguous_remote_branch_name = 1;
3434
int advice_submodule_alternate_error_strategy_die = 1;
3535
int advice_add_ignored_file = 1;
3636
int advice_add_empty_pathspec = 1;
37+
int advice_skipped_cherry_picks = 1;
3738

3839
static int advice_use_color = -1;
3940
static char advice_colors[][COLOR_MAXLEN] = {
@@ -96,6 +97,7 @@ static struct {
9697
{ "submoduleAlternateErrorStrategyDie", &advice_submodule_alternate_error_strategy_die },
9798
{ "addIgnoredFile", &advice_add_ignored_file },
9899
{ "addEmptyPathspec", &advice_add_empty_pathspec },
100+
{ "skippedCherryPicks", &advice_skipped_cherry_picks },
99101

100102
/* make this an alias for backward compatibility */
101103
{ "pushNonFastForward", &advice_push_update_rejected }
@@ -133,6 +135,7 @@ static struct {
133135
[ADVICE_RM_HINTS] = { "rmHints", 1 },
134136
[ADVICE_SEQUENCER_IN_USE] = { "sequencerInUse", 1 },
135137
[ADVICE_SET_UPSTREAM_FAILURE] = { "setUpstreamFailure", 1 },
138+
[ADVICE_SKIPPED_CHERRY_PICKS] = { "skippedCherryPicks", 1 },
136139
[ADVICE_STATUS_AHEAD_BEHIND_WARNING] = { "statusAheadBehindWarning", 1 },
137140
[ADVICE_STATUS_HINTS] = { "statusHints", 1 },
138141
[ADVICE_STATUS_U_OPTION] = { "statusUoption", 1 },

advice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern int advice_checkout_ambiguous_remote_branch_name;
3535
extern int advice_submodule_alternate_error_strategy_die;
3636
extern int advice_add_ignored_file;
3737
extern int advice_add_empty_pathspec;
38+
extern int advice_skipped_cherry_picks;
3839

3940
/*
4041
* To add a new advice, you need to:
@@ -75,6 +76,7 @@ extern int advice_add_empty_pathspec;
7576
ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE,
7677
ADVICE_UPDATE_SPARSE_PATH,
7778
ADVICE_WAITING_FOR_EDITOR,
79+
ADVICE_SKIPPED_CHERRY_PICKS,
7880
};
7981

8082
int git_default_advice_config(const char *var, const char *value);

builtin/rebase.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ static int run_sequencer_rebase(struct rebase_options *opts,
405405
flags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;
406406
flags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
407407
flags |= opts->reapply_cherry_picks ? TODO_LIST_REAPPLY_CHERRY_PICKS : 0;
408+
flags |= opts->flags & REBASE_NO_QUIET ? TODO_LIST_WARN_SKIPPED_CHERRY_PICKS : 0;
408409

409410
switch (command) {
410411
case ACTION_NONE: {

sequencer.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5099,6 +5099,7 @@ static int make_script_with_merges(struct pretty_print_context *pp,
50995099
int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
51005100
int rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;
51015101
int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;
5102+
int skipped_commit = 0;
51025103
struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;
51035104
struct strbuf label = STRBUF_INIT;
51045105
struct commit_list *commits = NULL, **tail = &commits, *iter;
@@ -5149,8 +5150,13 @@ static int make_script_with_merges(struct pretty_print_context *pp,
51495150
oidset_insert(&interesting, &commit->object.oid);
51505151

51515152
is_empty = is_original_commit_empty(commit);
5152-
if (!is_empty && (commit->object.flags & PATCHSAME))
5153+
if (!is_empty && (commit->object.flags & PATCHSAME)) {
5154+
if (flags & TODO_LIST_WARN_SKIPPED_CHERRY_PICKS)
5155+
warning(_("skipped previously applied commit %s"),
5156+
short_commit_name(commit));
5157+
skipped_commit = 1;
51535158
continue;
5159+
}
51545160
if (is_empty && !keep_empty)
51555161
continue;
51565162

@@ -5214,6 +5220,9 @@ static int make_script_with_merges(struct pretty_print_context *pp,
52145220
oidcpy(&entry->entry.oid, &commit->object.oid);
52155221
oidmap_put(&commit2todo, entry);
52165222
}
5223+
if (skipped_commit)
5224+
advise_if_enabled(ADVICE_SKIPPED_CHERRY_PICKS,
5225+
_("use --reapply-cherry-picks to include skipped commits"));
52175226

52185227
/*
52195228
* Second phase:
@@ -5334,6 +5343,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
53345343
const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick";
53355344
int rebase_merges = flags & TODO_LIST_REBASE_MERGES;
53365345
int reapply_cherry_picks = flags & TODO_LIST_REAPPLY_CHERRY_PICKS;
5346+
int skipped_commit = 0;
53375347

53385348
repo_init_revisions(r, &revs, NULL);
53395349
revs.verbose_header = 1;
@@ -5369,8 +5379,13 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
53695379
while ((commit = get_revision(&revs))) {
53705380
int is_empty = is_original_commit_empty(commit);
53715381

5372-
if (!is_empty && (commit->object.flags & PATCHSAME))
5382+
if (!is_empty && (commit->object.flags & PATCHSAME)) {
5383+
if (flags & TODO_LIST_WARN_SKIPPED_CHERRY_PICKS)
5384+
warning(_("skipped previously applied commit %s"),
5385+
short_commit_name(commit));
5386+
skipped_commit = 1;
53735387
continue;
5388+
}
53745389
if (is_empty && !keep_empty)
53755390
continue;
53765391
strbuf_addf(out, "%s %s ", insn,
@@ -5380,6 +5395,9 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
53805395
strbuf_addf(out, " %c empty", comment_line_char);
53815396
strbuf_addch(out, '\n');
53825397
}
5398+
if (skipped_commit)
5399+
advise_if_enabled(ADVICE_SKIPPED_CHERRY_PICKS,
5400+
_("use --reapply-cherry-picks to include skipped commits"));
53835401
return 0;
53845402
}
53855403

sequencer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ int sequencer_remove_state(struct replay_opts *opts);
156156
*/
157157
#define TODO_LIST_ROOT_WITH_ONTO (1U << 6)
158158
#define TODO_LIST_REAPPLY_CHERRY_PICKS (1U << 7)
159+
#define TODO_LIST_WARN_SKIPPED_CHERRY_PICKS (1U << 8)
159160

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

0 commit comments

Comments
 (0)