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>
This commit is contained in:
Phillip Wood 2019-04-17 15:30:39 +01:00 коммит произвёл Junio C Hamano
Родитель c44c24621d
Коммит 7d3488eb89
5 изменённых файлов: 55 добавлений и 30 удалений

Просмотреть файл

@ -147,27 +147,28 @@ static int edit_todo_file(unsigned flags)
return res; return res;
} }
static int get_revision_ranges(const char *upstream, const char *onto, static int get_revision_ranges(struct commit *upstream, struct commit *onto,
const char **head_hash, const char **head_hash,
char **revisions, char **shortrevisions) char **revisions, char **shortrevisions)
{ {
const char *base_rev = upstream ? upstream : onto, *shorthead; struct commit *base_rev = upstream ? upstream : onto;
const char *shorthead;
struct object_id orig_head; struct object_id orig_head;
if (get_oid("HEAD", &orig_head)) if (get_oid("HEAD", &orig_head))
return error(_("no HEAD?")); return error(_("no HEAD?"));
*head_hash = find_unique_abbrev(&orig_head, GIT_MAX_HEXSZ); *head_hash = find_unique_abbrev(&orig_head, GIT_MAX_HEXSZ);
*revisions = xstrfmt("%s...%s", base_rev, *head_hash); *revisions = xstrfmt("%s...%s", oid_to_hex(&base_rev->object.oid),
*head_hash);
shorthead = find_unique_abbrev(&orig_head, DEFAULT_ABBREV); shorthead = find_unique_abbrev(&orig_head, DEFAULT_ABBREV);
if (upstream) { if (upstream) {
const char *shortrev; const char *shortrev;
struct object_id rev_oid;
get_oid(base_rev, &rev_oid); shortrev = find_unique_abbrev(&base_rev->object.oid,
shortrev = find_unique_abbrev(&rev_oid, DEFAULT_ABBREV); DEFAULT_ABBREV);
*shortrevisions = xstrfmt("%s..%s", shortrev, shorthead); *shortrevisions = xstrfmt("%s..%s", shortrev, shorthead);
} else } else
@ -177,7 +178,7 @@ static int get_revision_ranges(const char *upstream, const char *onto,
} }
static int init_basic_state(struct replay_opts *opts, const char *head_name, static int init_basic_state(struct replay_opts *opts, const char *head_name,
const char *onto, const char *orig_head) struct commit *onto, const char *orig_head)
{ {
FILE *interactive; FILE *interactive;
@ -195,10 +196,10 @@ static int init_basic_state(struct replay_opts *opts, const char *head_name,
} }
static int do_interactive_rebase(struct replay_opts *opts, unsigned flags, static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
const char *switch_to, const char *upstream, const char *switch_to, struct commit *upstream,
const char *onto, const char *onto_name, struct commit *onto, const char *onto_name,
const char *squash_onto, const char *head_name, const char *squash_onto, const char *head_name,
const char *restrict_revision, char *raw_strategies, struct commit *restrict_revision, char *raw_strategies,
struct string_list *commands, unsigned autosquash) struct string_list *commands, unsigned autosquash)
{ {
int ret; int ret;
@ -229,7 +230,8 @@ static int do_interactive_rebase(struct replay_opts *opts, unsigned flags,
argv_array_pushl(&make_script_args, "", revisions, NULL); argv_array_pushl(&make_script_args, "", revisions, NULL);
if (restrict_revision) if (restrict_revision)
argv_array_push(&make_script_args, restrict_revision); argv_array_push(&make_script_args,
oid_to_hex(&restrict_revision->object.oid));
ret = sequencer_make_script(the_repository, &todo_list.buf, ret = sequencer_make_script(the_repository, &todo_list.buf,
make_script_args.argc, make_script_args.argv, make_script_args.argc, make_script_args.argv,
@ -265,9 +267,10 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
struct replay_opts opts = REPLAY_OPTS_INIT; struct replay_opts opts = REPLAY_OPTS_INIT;
unsigned flags = 0, keep_empty = 0, rebase_merges = 0, autosquash = 0; unsigned flags = 0, keep_empty = 0, rebase_merges = 0, autosquash = 0;
int abbreviate_commands = 0, rebase_cousins = -1, ret = 0; int abbreviate_commands = 0, rebase_cousins = -1, ret = 0;
const char *onto = NULL, *onto_name = NULL, *restrict_revision = NULL, const char *onto_name = NULL,
*squash_onto = NULL, *upstream = NULL, *head_name = NULL, *squash_onto = NULL, *head_name = NULL,
*switch_to = NULL, *cmd = NULL; *switch_to = NULL, *cmd = NULL;
struct commit *onto = NULL, *upstream = NULL, *restrict_revision = NULL;
struct string_list commands = STRING_LIST_INIT_DUP; struct string_list commands = STRING_LIST_INIT_DUP;
char *raw_strategies = NULL; char *raw_strategies = NULL;
enum { enum {
@ -303,13 +306,16 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
N_("rearrange fixup/squash lines"), REARRANGE_SQUASH), N_("rearrange fixup/squash lines"), REARRANGE_SQUASH),
OPT_CMDMODE(0, "add-exec-commands", &command, OPT_CMDMODE(0, "add-exec-commands", &command,
N_("insert exec commands in todo list"), ADD_EXEC), N_("insert exec commands in todo list"), ADD_EXEC),
OPT_STRING(0, "onto", &onto, N_("onto"), N_("onto")), { OPTION_CALLBACK, 0, "onto", &onto, N_("onto"), N_("onto"),
OPT_STRING(0, "restrict-revision", &restrict_revision, PARSE_OPT_NONEG, parse_opt_commit, 0 },
N_("restrict-revision"), N_("restrict revision")), { OPTION_CALLBACK, 0, "restrict-revision", &restrict_revision,
N_("restrict-revision"), N_("restrict revision"),
PARSE_OPT_NONEG, parse_opt_commit, 0 },
OPT_STRING(0, "squash-onto", &squash_onto, N_("squash-onto"), OPT_STRING(0, "squash-onto", &squash_onto, N_("squash-onto"),
N_("squash onto")), N_("squash onto")),
OPT_STRING(0, "upstream", &upstream, N_("upstream"), { OPTION_CALLBACK, 0, "upstream", &upstream, N_("upstream"),
N_("the upstream commit")), N_("the upstream commit"), PARSE_OPT_NONEG, parse_opt_commit,
0 },
OPT_STRING(0, "head-name", &head_name, N_("head-name"), N_("head name")), OPT_STRING(0, "head-name", &head_name, N_("head-name"), N_("head name")),
{ OPTION_STRING, 'S', "gpg-sign", &opts.gpg_sign, N_("key-id"), { OPTION_STRING, 'S', "gpg-sign", &opts.gpg_sign, N_("key-id"),
N_("GPG-sign commits"), N_("GPG-sign commits"),

Просмотреть файл

@ -96,6 +96,23 @@ int parse_opt_commits(const struct option *opt, const char *arg, int unset)
return 0; return 0;
} }
int parse_opt_commit(const struct option *opt, const char *arg, int unset)
{
struct object_id oid;
struct commit *commit;
struct commit **target = opt->value;
if (!arg)
return -1;
if (get_oid(arg, &oid))
return error("malformed object name %s", arg);
commit = lookup_commit_reference(the_repository, &oid);
if (!commit)
return error("no such commit %s", arg);
*target = commit;
return 0;
}
int parse_opt_object_name(const struct option *opt, const char *arg, int unset) int parse_opt_object_name(const struct option *opt, const char *arg, int unset)
{ {
struct object_id oid; struct object_id oid;

Просмотреть файл

@ -266,6 +266,7 @@ int parse_opt_color_flag_cb(const struct option *, const char *, int);
int parse_opt_verbosity_cb(const struct option *, const char *, int); int parse_opt_verbosity_cb(const struct option *, const char *, int);
int parse_opt_object_name(const struct option *, const char *, int); int parse_opt_object_name(const struct option *, const char *, int);
int parse_opt_commits(const struct option *, const char *, int); int parse_opt_commits(const struct option *, const char *, int);
int parse_opt_commit(const struct option *, const char *, int);
int parse_opt_tertiary(const struct option *, const char *, int); int parse_opt_tertiary(const struct option *, const char *, int);
int parse_opt_string_list(const struct option *, const char *, int); int parse_opt_string_list(const struct option *, const char *, int);
int parse_opt_noop_cb(const struct option *, const char *, int); int parse_opt_noop_cb(const struct option *, const char *, int);

Просмотреть файл

@ -2418,14 +2418,15 @@ static void write_strategy_opts(struct replay_opts *opts)
} }
int write_basic_state(struct replay_opts *opts, const char *head_name, int write_basic_state(struct replay_opts *opts, const char *head_name,
const char *onto, const char *orig_head) struct commit *onto, const char *orig_head)
{ {
const char *quiet = getenv("GIT_QUIET"); const char *quiet = getenv("GIT_QUIET");
if (head_name) if (head_name)
write_file(rebase_path_head_name(), "%s\n", head_name); write_file(rebase_path_head_name(), "%s\n", head_name);
if (onto) if (onto)
write_file(rebase_path_onto(), "%s\n", onto); write_file(rebase_path_onto(), "%s\n",
oid_to_hex(&onto->object.oid));
if (orig_head) if (orig_head)
write_file(rebase_path_orig_head(), "%s\n", orig_head); write_file(rebase_path_orig_head(), "%s\n", orig_head);
@ -3456,7 +3457,7 @@ int prepare_branch_to_be_rebased(struct repository *r, struct replay_opts *opts,
} }
static int checkout_onto(struct repository *r, struct replay_opts *opts, static int checkout_onto(struct repository *r, struct replay_opts *opts,
const char *onto_name, const char *onto, const char *onto_name, const struct object_id *onto,
const char *orig_head) const char *orig_head)
{ {
struct object_id oid; struct object_id oid;
@ -3465,7 +3466,7 @@ static int checkout_onto(struct repository *r, struct replay_opts *opts,
if (get_oid(orig_head, &oid)) if (get_oid(orig_head, &oid))
return error(_("%s: not a valid OID"), orig_head); return error(_("%s: not a valid OID"), orig_head);
if (run_git_checkout(r, opts, onto, action)) { if (run_git_checkout(r, opts, oid_to_hex(onto), action)) {
apply_autostash(opts); apply_autostash(opts);
sequencer_remove_state(opts); sequencer_remove_state(opts);
return error(_("could not detach HEAD")); return error(_("could not detach HEAD"));
@ -4741,16 +4742,16 @@ static int skip_unnecessary_picks(struct repository *r,
int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags, int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
const char *shortrevisions, const char *onto_name, const char *shortrevisions, const char *onto_name,
const char *onto, const char *orig_head, struct string_list *commands, struct commit *onto, const char *orig_head,
unsigned autosquash, struct todo_list *todo_list) struct string_list *commands, unsigned autosquash,
struct todo_list *todo_list)
{ {
const char *shortonto, *todo_file = rebase_path_todo(); const char *shortonto, *todo_file = rebase_path_todo();
struct todo_list new_todo = TODO_LIST_INIT; struct todo_list new_todo = TODO_LIST_INIT;
struct strbuf *buf = &todo_list->buf; struct strbuf *buf = &todo_list->buf;
struct object_id oid; struct object_id oid = onto->object.oid;
int res; int res;
get_oid(onto, &oid);
shortonto = find_unique_abbrev(&oid, DEFAULT_ABBREV); shortonto = find_unique_abbrev(&oid, DEFAULT_ABBREV);
if (buf->len == 0) { if (buf->len == 0) {
@ -4793,7 +4794,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla
if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo) || if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo) ||
todo_list_check(todo_list, &new_todo)) { todo_list_check(todo_list, &new_todo)) {
fprintf(stderr, _(edit_todo_list_advice)); fprintf(stderr, _(edit_todo_list_advice));
checkout_onto(r, opts, onto_name, onto, orig_head); checkout_onto(r, opts, onto_name, &onto->object.oid, orig_head);
todo_list_release(&new_todo); todo_list_release(&new_todo);
return -1; return -1;
@ -4812,7 +4813,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla
todo_list_release(&new_todo); todo_list_release(&new_todo);
if (checkout_onto(r, opts, onto_name, oid_to_hex(&oid), orig_head)) if (checkout_onto(r, opts, onto_name, &oid, orig_head))
return -1; return -1;
if (require_clean_work_tree(r, "rebase", "", 1, 1)) if (require_clean_work_tree(r, "rebase", "", 1, 1))

Просмотреть файл

@ -150,7 +150,7 @@ void todo_list_add_exec_commands(struct todo_list *todo_list,
int check_todo_list_from_file(struct repository *r); int check_todo_list_from_file(struct repository *r);
int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags, int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
const char *shortrevisions, const char *onto_name, const char *shortrevisions, const char *onto_name,
const char *onto, const char *orig_head, struct string_list *commands, struct commit *onto, const char *orig_head, struct string_list *commands,
unsigned autosquash, struct todo_list *todo_list); unsigned autosquash, struct todo_list *todo_list);
int todo_list_rearrange_squash(struct todo_list *todo_list); int todo_list_rearrange_squash(struct todo_list *todo_list);
@ -191,4 +191,4 @@ int read_author_script(const char *path, char **name, char **email, char **date,
void parse_strategy_opts(struct replay_opts *opts, char *raw_opts); void parse_strategy_opts(struct replay_opts *opts, char *raw_opts);
int write_basic_state(struct replay_opts *opts, const char *head_name, int write_basic_state(struct replay_opts *opts, const char *head_name,
const char *onto, const char *orig_head); struct commit *onto, const char *orig_head);