rebase -i: use struct commit when parsing options

This is in preparation for using `struct rebase_options` when parsing options in cmd_rebase__interactive(). Using a string for onto, restrict_revision and upstream, was a hangover from the scripted version of rebase. The functions that use these variables are updated to take a `struct commit`. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Phillip Wood committed Apr 17, 2019 at 15:30 UTC 7d3488eb893ba53186770181171ee8ebc8100e18
5 files changed +55 -30
builtin/rebase.c
+24 -18
@@ -147,27 +147,28 @@ static int edit_todo_file(unsigned flags)
147 return res;
148 }
149
150 -static int get_revision_ranges(const char *upstream, const char *onto,
150 +static int get_revision_ranges(struct commit *upstream, struct commit *onto,
151 const char **head_hash,
152 char **revisions, char **shortrevisions)
153 {
154 - const char *base_rev = upstream ? upstream : onto, *shorthead;
154 + struct commit *base_rev = upstream ? upstream : onto;
155 + const char *shorthead;
156 struct object_id orig_head;
157
158 if (get_oid("HEAD", &orig_head))
159 return error(_("no HEAD?"));
160
161 *head_hash = find_unique_abbrev(&orig_head, GIT_MAX_HEXSZ);
161 - *revisions = xstrfmt("%s...%s", base_rev, *head_hash);
162 + *revisions = xstrfmt("%s...%s", oid_to_hex(&base_rev->object.oid),
163 + *head_hash);
164
165 shorthead = find_unique_abbrev(&orig_head, DEFAULT_ABBREV);
166
167 if (upstream) {
168 const char *shortrev;
167 - struct object_id rev_oid;
169
169 - get_oid(base_rev, &rev_oid);
170 - shortrev = find_unique_abbrev(&rev_oid, DEFAULT_ABBREV);
170 + shortrev = find_unique_abbrev(&base_rev->object.oid,
171 + DEFAULT_ABBREV);
172
173 *shortrevisions = xstrfmt("%s..%s", shortrev, shorthead);
174 } else
@@ -177,7 +178,7 @@ static int get_revision_ranges(const char *upstream, const char *onto,
178 }
179
180 static int init_basic_state(struct replay_opts *opts, const char *head_name,
180 - const char *onto, const char *orig_head)
181 + struct commit *onto, const char *orig_head)
182 {
183 FILE *interactive;
184
@@ -195,10 +196,10 @@ static int init_basic_state(struct replay_opts *opts, const char *head_name,
196 }
197
198 static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
198 - const char *switch_to, const char *upstream,
199 - const char *onto, const char *onto_name,
199 + const char *switch_to, struct commit *upstream,
200 + struct commit *onto, const char *onto_name,
201 const char *squash_onto, const char *head_name,
201 - const char *restrict_revision, char *raw_strategies,
202 + struct commit *restrict_revision, char *raw_strategies,
203 struct string_list *commands, unsigned autosquash)
204 {
205 int ret;
@@ -229,7 +230,8 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
230
231 argv_array_pushl(&make_script_args, "", revisions, NULL);
232 if (restrict_revision)
232 - argv_array_push(&make_script_args, restrict_revision);
233 + argv_array_push(&make_script_args,
234 + oid_to_hex(&restrict_revision->object.oid));
235
236 ret = sequencer_make_script(the_repository, &todo_list.buf,
237 make_script_args.argc, make_script_args.argv,
@@ -265,9 +267,10 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
267 struct replay_opts opts = REPLAY_OPTS_INIT;
268 unsigned flags = 0, keep_empty = 0, rebase_merges = 0, autosquash = 0;
269 int abbreviate_commands = 0, rebase_cousins = -1, ret = 0;
268 - const char *onto = NULL, *onto_name = NULL, *restrict_revision = NULL,
269 - *squash_onto = NULL, *upstream = NULL, *head_name = NULL,
270 + const char *onto_name = NULL,
271 + *squash_onto = NULL, *head_name = NULL,
272 *switch_to = NULL, *cmd = NULL;
273 + struct commit *onto = NULL, *upstream = NULL, *restrict_revision = NULL;
274 struct string_list commands = STRING_LIST_INIT_DUP;
275 char *raw_strategies = NULL;
276 enum {
@@ -303,13 +306,16 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
306 N_("rearrange fixup/squash lines"), REARRANGE_SQUASH),
307 OPT_CMDMODE(0, "add-exec-commands", &command,
308 N_("insert exec commands in todo list"), ADD_EXEC),
306 - OPT_STRING(0, "onto", &onto, N_("onto"), N_("onto")),
307 - OPT_STRING(0, "restrict-revision", &restrict_revision,
308 - N_("restrict-revision"), N_("restrict revision")),
309 + { OPTION_CALLBACK, 0, "onto", &onto, N_("onto"), N_("onto"),
310 + PARSE_OPT_NONEG, parse_opt_commit, 0 },
311 + { OPTION_CALLBACK, 0, "restrict-revision", &restrict_revision,
312 + N_("restrict-revision"), N_("restrict revision"),
313 + PARSE_OPT_NONEG, parse_opt_commit, 0 },
314 OPT_STRING(0, "squash-onto", &squash_onto, N_("squash-onto"),
315 N_("squash onto")),
311 - OPT_STRING(0, "upstream", &upstream, N_("upstream"),
312 - N_("the upstream commit")),
316 + { OPTION_CALLBACK, 0, "upstream", &upstream, N_("upstream"),
317 + N_("the upstream commit"), PARSE_OPT_NONEG, parse_opt_commit,
318 + 0 },
319 OPT_STRING(0, "head-name", &head_name, N_("head-name"), N_("head name")),
320 { OPTION_STRING, 'S', "gpg-sign", &opts.gpg_sign, N_("key-id"),
321 N_("GPG-sign commits"),
parse-options-cb.c
+17
@@ -96,6 +96,23 @@ int parse_opt_commits(const struct option *opt, const char *arg, int unset)
96 return 0;
97 }
98
99 +int parse_opt_commit(const struct option *opt, const char *arg, int unset)
100 +{
101 + struct object_id oid;
102 + struct commit *commit;
103 + struct commit **target = opt->value;
104 +
105 + if (!arg)
106 + return -1;
107 + if (get_oid(arg, &oid))
108 + return error("malformed object name %s", arg);
109 + commit = lookup_commit_reference(the_repository, &oid);
110 + if (!commit)
111 + return error("no such commit %s", arg);
112 + *target = commit;
113 + return 0;
114 +}
115 +
116 int parse_opt_object_name(const struct option *opt, const char *arg, int unset)
117 {
118 struct object_id oid;
parse-options.h
+1
@@ -266,6 +266,7 @@ int parse_opt_color_flag_cb(const struct option *, const char *, int);
266 int parse_opt_verbosity_cb(const struct option *, const char *, int);
267 int parse_opt_object_name(const struct option *, const char *, int);
268 int parse_opt_commits(const struct option *, const char *, int);
269 +int parse_opt_commit(const struct option *, const char *, int);
270 int parse_opt_tertiary(const struct option *, const char *, int);
271 int parse_opt_string_list(const struct option *, const char *, int);
272 int parse_opt_noop_cb(const struct option *, const char *, int);
sequencer.c
+11 -10
@@ -2418,14 +2418,15 @@ static void write_strategy_opts(struct replay_opts *opts)
2418 }
2419
2420 int write_basic_state(struct replay_opts *opts, const char *head_name,
2421 - const char *onto, const char *orig_head)
2421 + struct commit *onto, const char *orig_head)
2422 {
2423 const char *quiet = getenv("GIT_QUIET");
2424
2425 if (head_name)
2426 write_file(rebase_path_head_name(), "%s\n", head_name);
2427 if (onto)
2428 - write_file(rebase_path_onto(), "%s\n", onto);
2428 + write_file(rebase_path_onto(), "%s\n",
2429 + oid_to_hex(&onto->object.oid));
2430 if (orig_head)
2431 write_file(rebase_path_orig_head(), "%s\n", orig_head);
2432
@@ -3456,7 +3457,7 @@ int prepare_branch_to_be_rebased(struct repository *r, struct replay_opts *opts,
3457 }
3458
3459 static int checkout_onto(struct repository *r, struct replay_opts *opts,
3459 - const char *onto_name, const char *onto,
3460 + const char *onto_name, const struct object_id *onto,
3461 const char *orig_head)
3462 {
3463 struct object_id oid;
@@ -3465,7 +3466,7 @@ static int checkout_onto(struct repository *r, struct replay_opts *opts,
3466 if (get_oid(orig_head, &oid))
3467 return error(_("%s: not a valid OID"), orig_head);
3468
3468 - if (run_git_checkout(r, opts, onto, action)) {
3469 + if (run_git_checkout(r, opts, oid_to_hex(onto), action)) {
3470 apply_autostash(opts);
3471 sequencer_remove_state(opts);
3472 return error(_("could not detach HEAD"));
@@ -4741,16 +4742,16 @@ static int skip_unnecessary_picks(struct repository *r,
4742
4743 int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
4744 const char *shortrevisions, const char *onto_name,
4744 - const char *onto, const char *orig_head, struct string_list *commands,
4745 - unsigned autosquash, struct todo_list *todo_list)
4745 + struct commit *onto, const char *orig_head,
4746 + struct string_list *commands, unsigned autosquash,
4747 + struct todo_list *todo_list)
4748 {
4749 const char *shortonto, *todo_file = rebase_path_todo();
4750 struct todo_list new_todo = TODO_LIST_INIT;
4751 struct strbuf *buf = &todo_list->buf;
4750 - struct object_id oid;
4752 + struct object_id oid = onto->object.oid;
4753 int res;
4754
4753 - get_oid(onto, &oid);
4755 shortonto = find_unique_abbrev(&oid, DEFAULT_ABBREV);
4756
4757 if (buf->len == 0) {
@@ -4793,7 +4794,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla
4794 if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo) ||
4795 todo_list_check(todo_list, &new_todo)) {
4796 fprintf(stderr, _(edit_todo_list_advice));
4796 - checkout_onto(r, opts, onto_name, onto, orig_head);
4797 + checkout_onto(r, opts, onto_name, &onto->object.oid, orig_head);
4798 todo_list_release(&new_todo);
4799
4800 return -1;
@@ -4812,7 +4813,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla
4813
4814 todo_list_release(&new_todo);
4815
4815 - if (checkout_onto(r, opts, onto_name, oid_to_hex(&oid), orig_head))
4816 + if (checkout_onto(r, opts, onto_name, &oid, orig_head))
4817 return -1;
4818
4819 if (require_clean_work_tree(r, "rebase", "", 1, 1))
sequencer.h
+2 -2
@@ -150,7 +150,7 @@ void todo_list_add_exec_commands(struct todo_list *todo_list,
150 int check_todo_list_from_file(struct repository *r);
151 int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
152 const char *shortrevisions, const char *onto_name,
153 - const char *onto, const char *orig_head, struct string_list *commands,
153 + struct commit *onto, const char *orig_head, struct string_list *commands,
154 unsigned autosquash, struct todo_list *todo_list);
155 int todo_list_rearrange_squash(struct todo_list *todo_list);
156
@@ -191,4 +191,4 @@ int read_author_script(const char *path, char **name, char **email, char **date,
191
192 void parse_strategy_opts(struct replay_opts *opts, char *raw_opts);
193 int write_basic_state(struct replay_opts *opts, const char *head_name,
194 - const char *onto, const char *orig_head);
194 + struct commit *onto, const char *orig_head);