Skip to content

Commit 7f13334

Browse files
jrngitster
authored andcommitted
revert: pass around rev-list args in already-parsed form
Since 7e2bfd3 (revert: allow cherry-picking more than one commit, 2010-07-02), the pick/revert machinery has kept track of the set of commits to be cherry-picked or reverted using commit_argc and commit_argv variables, storing the corresponding command-line parameters. Future callers as other commands are built in (am, rebase, sequencer) may find it easier to pass rev-list options to this machinery in already-parsed form. Teach cmd_cherry_pick and cmd_revert to parse the rev-list arguments in advance and pass the commit set to pick_revisions() as a rev_info structure. Original patch by Jonathan, tweaks and test from Ram. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Improved-by: Ramkumar Ramachandra <artagnon@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 093a309 commit 7f13334

2 files changed

Lines changed: 34 additions & 24 deletions

File tree

builtin/revert.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,14 @@ struct replay_opts {
6060
int allow_rerere_auto;
6161

6262
int mainline;
63-
int commit_argc;
64-
const char **commit_argv;
6563

6664
/* Merge strategy */
6765
const char *strategy;
6866
const char **xopts;
6967
size_t xopts_nr, xopts_alloc;
68+
69+
/* Only used by REPLAY_NONE */
70+
struct rev_info *revs;
7071
};
7172

7273
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
@@ -169,9 +170,9 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
169170
die(_("program error"));
170171
}
171172

172-
opts->commit_argc = parse_options(argc, argv, NULL, options, usage_str,
173-
PARSE_OPT_KEEP_ARGV0 |
174-
PARSE_OPT_KEEP_UNKNOWN);
173+
argc = parse_options(argc, argv, NULL, options, usage_str,
174+
PARSE_OPT_KEEP_ARGV0 |
175+
PARSE_OPT_KEEP_UNKNOWN);
175176

176177
/* Check for incompatible subcommands */
177178
verify_opt_mutually_compatible(me,
@@ -213,17 +214,27 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
213214
NULL);
214215
}
215216

216-
else if (opts->commit_argc < 2)
217-
usage_with_options(usage_str, options);
218-
219217
if (opts->allow_ff)
220218
verify_opt_compatible(me, "--ff",
221219
"--signoff", opts->signoff,
222220
"--no-commit", opts->no_commit,
223221
"-x", opts->record_origin,
224222
"--edit", opts->edit,
225223
NULL);
226-
opts->commit_argv = argv;
224+
225+
if (opts->subcommand != REPLAY_NONE) {
226+
opts->revs = NULL;
227+
} else {
228+
opts->revs = xmalloc(sizeof(*opts->revs));
229+
init_revisions(opts->revs, NULL);
230+
opts->revs->no_walk = 1;
231+
if (argc < 2)
232+
usage_with_options(usage_str, options);
233+
argc = setup_revisions(argc, argv, opts->revs, NULL);
234+
}
235+
236+
if (argc > 1)
237+
usage_with_options(usage_str, options);
227238
}
228239

229240
struct commit_message {
@@ -631,23 +642,15 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
631642
return res;
632643
}
633644

634-
static void prepare_revs(struct rev_info *revs, struct replay_opts *opts)
645+
static void prepare_revs(struct replay_opts *opts)
635646
{
636-
int argc;
637-
638-
init_revisions(revs, NULL);
639-
revs->no_walk = 1;
640647
if (opts->action != REVERT)
641-
revs->reverse = 1;
648+
opts->revs->reverse ^= 1;
642649

643-
argc = setup_revisions(opts->commit_argc, opts->commit_argv, revs, NULL);
644-
if (argc > 1)
645-
usage(*revert_or_cherry_pick_usage(opts));
646-
647-
if (prepare_revision_walk(revs))
650+
if (prepare_revision_walk(opts->revs))
648651
die(_("revision walk setup failed"));
649652

650-
if (!revs->commits)
653+
if (!opts->revs->commits)
651654
die(_("empty commit set passed"));
652655
}
653656

@@ -844,14 +847,13 @@ static void read_populate_opts(struct replay_opts **opts_ptr)
844847
static void walk_revs_populate_todo(struct commit_list **todo_list,
845848
struct replay_opts *opts)
846849
{
847-
struct rev_info revs;
848850
struct commit *commit;
849851
struct commit_list **next;
850852

851-
prepare_revs(&revs, opts);
853+
prepare_revs(opts);
852854

853855
next = todo_list;
854-
while ((commit = get_revision(&revs)))
856+
while ((commit = get_revision(opts->revs)))
855857
next = commit_list_append(commit, next);
856858
}
857859

@@ -1075,6 +1077,9 @@ static int pick_revisions(struct replay_opts *opts)
10751077
struct commit_list *todo_list = NULL;
10761078
unsigned char sha1[20];
10771079

1080+
if (opts->subcommand == REPLAY_NONE)
1081+
assert(opts->revs);
1082+
10781083
read_and_refresh_cache(opts);
10791084

10801085
/*

t/t3510-cherry-pick-sequence.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,4 +461,9 @@ test_expect_success 'malformed instruction sheet 2' '
461461
test_must_fail git cherry-pick --continue
462462
'
463463

464+
test_expect_success 'empty commit set' '
465+
pristine_detach initial &&
466+
test_expect_code 128 git cherry-pick base..base
467+
'
468+
464469
test_done

0 commit comments

Comments
 (0)