replay: start using parse_options API

Instead of manually parsing arguments, let's start using the parse_options API. This way this new builtin will look more standard, and in some upcoming commits will more easily be able to handle more command line options. Note that we plan to later use standard revision ranges instead of hardcoded "<oldbase> <branch>" arguments. When we will use standard revision ranges, it will be easier to check if there are no spurious arguments if we keep ARGV[0], so let's call parse_options() with PARSE_OPT_KEEP_ARGV0 even if we don't need ARGV[0] right now to avoid some useless code churn. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Nov 24, 2023 at 12:10 UTC d46da6d90be99f91988eececd5368170b0eded1f
1 file changed +32 -13
builtin/replay.c
+32 -13
@@ -15,7 +15,7 @@
15 #include "lockfile.h"
16 #include "merge-ort.h"
17 #include "object-name.h"
18 -#include "read-cache-ll.h"
18 +#include "parse-options.h"
19 #include "refs.h"
20 #include "revision.h"
21 #include "sequencer.h"
@@ -92,6 +92,7 @@ static struct commit *create_commit(struct tree *tree,
92 int cmd_replay(int argc, const char **argv, const char *prefix)
93 {
94 struct commit *onto;
95 + const char *onto_name = NULL;
96 struct commit *last_commit = NULL, *last_picked_commit = NULL;
97 struct object_id head;
98 struct lock_file lock = LOCK_INIT;
@@ -105,16 +106,32 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
106 struct strbuf branch_name = STRBUF_INIT;
107 int ret = 0;
108
108 - if (argc == 2 && !strcmp(argv[1], "-h")) {
109 - printf("usage: (EXPERIMENTAL!) git replay --onto <newbase> <oldbase> <branch>\n");
110 - exit(129);
109 + const char * const replay_usage[] = {
110 + N_("(EXPERIMENTAL!) git replay --onto <newbase> <oldbase> <branch>"),
111 + NULL
112 + };
113 + struct option replay_options[] = {
114 + OPT_STRING(0, "onto", &onto_name,
115 + N_("revision"),
116 + N_("replay onto given commit")),
117 + OPT_END()
118 + };
119 +
120 + argc = parse_options(argc, argv, prefix, replay_options, replay_usage,
121 + PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT);
122 +
123 + if (!onto_name) {
124 + error(_("option --onto is mandatory"));
125 + usage_with_options(replay_usage, replay_options);
126 }
127
113 - if (argc != 5 || strcmp(argv[1], "--onto"))
114 - die("usage: read the code, figure out how to use it, then do so");
128 + if (argc != 3) {
129 + error(_("bad number of arguments"));
130 + usage_with_options(replay_usage, replay_options);
131 + }
132
116 - onto = peel_committish(argv[2]);
117 - strbuf_addf(&branch_name, "refs/heads/%s", argv[4]);
133 + onto = peel_committish(onto_name);
134 + strbuf_addf(&branch_name, "refs/heads/%s", argv[2]);
135
136 /* Sanity check */
137 if (repo_get_oid(the_repository, "HEAD", &head))
@@ -126,6 +143,7 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
143 BUG("Could not read index");
144
145 repo_init_revisions(the_repository, &revs, prefix);
146 +
147 revs.verbose_header = 1;
148 revs.max_parents = 1;
149 revs.cherry_mark = 1;
@@ -134,7 +152,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
152 revs.right_only = 1;
153 revs.sort_order = REV_SORT_IN_GRAPH_ORDER;
154 revs.topo_order = 1;
137 - strvec_pushl(&rev_walk_args, "", argv[4], "--not", argv[3], NULL);
155 +
156 + strvec_pushl(&rev_walk_args, "", argv[2], "--not", argv[1], NULL);
157
158 if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) {
159 ret = error(_("unhandled options"));
@@ -197,8 +216,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
216 &last_commit->object.oid,
217 &last_picked_commit->object.oid,
218 REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {
200 - error(_("could not update %s"), argv[4]);
201 - die("Failed to update %s", argv[4]);
219 + error(_("could not update %s"), argv[2]);
220 + die("Failed to update %s", argv[2]);
221 }
222 if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0)
223 die(_("unable to update HEAD"));
@@ -210,8 +229,8 @@ int cmd_replay(int argc, const char **argv, const char *prefix)
229 &last_commit->object.oid,
230 &head,
231 REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {
213 - error(_("could not update %s"), argv[4]);
214 - die("Failed to update %s", argv[4]);
232 + error(_("could not update %s"), argv[2]);
233 + die("Failed to update %s", argv[2]);
234 }
235 }
236 ret = (result.clean == 0);