X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=sequencer.c;h=1d206fd22456cce12f7496321df8a47fcb94db9e;hb=ae76814c6ca1af63f947c3525dfd1a799c3d9fd4;hp=4407a3f97858acdf47add8e8848cba12daf1de6d;hpb=4aeeef377347934d6f459e27f7d793de4ce384bb;p=thirdparty%2Fgit.git diff --git a/sequencer.c b/sequencer.c index 4407a3f978..1d206fd224 100644 --- a/sequencer.c +++ b/sequencer.c @@ -279,7 +279,7 @@ static const char *gpg_sign_opt_quoted(struct replay_opts *opts) int sequencer_remove_state(struct replay_opts *opts) { struct strbuf buf = STRBUF_INIT; - int i; + int i, ret = 0; if (is_rebase_i(opts) && strbuf_read_file(&buf, rebase_path_refs_to_delete(), 0) > 0) { @@ -288,8 +288,10 @@ int sequencer_remove_state(struct replay_opts *opts) char *eol = strchr(p, '\n'); if (eol) *eol = '\0'; - if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0) + if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0) { warning(_("could not delete '%s'"), p); + ret = -1; + } if (!eol) break; p = eol + 1; @@ -305,10 +307,11 @@ int sequencer_remove_state(struct replay_opts *opts) strbuf_reset(&buf); strbuf_addstr(&buf, get_dir(opts)); - remove_dir_recursively(&buf, 0); + if (remove_dir_recursively(&buf, 0)) + ret = error(_("could not remove '%s'"), buf.buf); strbuf_release(&buf); - return 0; + return ret; } static const char *action_name(const struct replay_opts *opts) @@ -2168,6 +2171,41 @@ static int parse_insn_line(struct repository *r, struct todo_item *item, return !item->commit; } +int sequencer_get_last_command(struct repository *r, enum replay_action *action) +{ + struct todo_item item; + char *eol; + const char *todo_file; + struct strbuf buf = STRBUF_INIT; + int ret = -1; + + todo_file = git_path_todo_file(); + if (strbuf_read_file(&buf, todo_file, 0) < 0) { + if (errno == ENOENT) + return -1; + else + return error_errno("unable to open '%s'", todo_file); + } + eol = strchrnul(buf.buf, '\n'); + if (buf.buf != eol && eol[-1] == '\r') + eol--; /* strip Carriage Return */ + if (parse_insn_line(r, &item, buf.buf, buf.buf, eol)) + goto fail; + if (item.command == TODO_PICK) + *action = REPLAY_PICK; + else if (item.command == TODO_REVERT) + *action = REPLAY_REVERT; + else + goto fail; + + ret = 0; + + fail: + strbuf_release(&buf); + + return ret; +} + int todo_list_parse_insn_buffer(struct repository *r, char *buf, struct todo_list *todo_list) { @@ -2251,6 +2289,57 @@ static ssize_t strbuf_read_file_or_whine(struct strbuf *sb, const char *path) return len; } +static int have_finished_the_last_pick(void) +{ + struct strbuf buf = STRBUF_INIT; + const char *eol; + const char *todo_path = git_path_todo_file(); + int ret = 0; + + if (strbuf_read_file(&buf, todo_path, 0) < 0) { + if (errno == ENOENT) { + return 0; + } else { + error_errno("unable to open '%s'", todo_path); + return 0; + } + } + /* If there is only one line then we are done */ + eol = strchr(buf.buf, '\n'); + if (!eol || !eol[1]) + ret = 1; + + strbuf_release(&buf); + + return ret; +} + +void sequencer_post_commit_cleanup(struct repository *r) +{ + struct replay_opts opts = REPLAY_OPTS_INIT; + int need_cleanup = 0; + + if (file_exists(git_path_cherry_pick_head(r))) { + unlink(git_path_cherry_pick_head(r)); + opts.action = REPLAY_PICK; + need_cleanup = 1; + } + + if (file_exists(git_path_revert_head(r))) { + unlink(git_path_revert_head(r)); + opts.action = REPLAY_REVERT; + need_cleanup = 1; + } + + if (!need_cleanup) + return; + + if (!have_finished_the_last_pick()) + return; + + sequencer_remove_state(&opts); +} + static int read_populate_todo(struct repository *r, struct todo_list *todo_list, struct replay_opts *opts) @@ -2494,14 +2583,15 @@ static void write_strategy_opts(struct replay_opts *opts) } 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"); if (head_name) write_file(rebase_path_head_name(), "%s\n", head_name); 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) write_file(rebase_path_orig_head(), "%s\n", orig_head); @@ -3517,10 +3607,11 @@ static const char *reflog_message(struct replay_opts *opts, return buf.buf; } -static int run_git_checkout(struct replay_opts *opts, const char *commit, - const char *action) +static int run_git_checkout(struct repository *r, struct replay_opts *opts, + const char *commit, const char *action) { struct child_process cmd = CHILD_PROCESS_INIT; + int ret; cmd.git_cmd = 1; @@ -3529,26 +3620,32 @@ static int run_git_checkout(struct replay_opts *opts, const char *commit, argv_array_pushf(&cmd.env_array, GIT_REFLOG_ACTION "=%s", action); if (opts->verbose) - return run_command(&cmd); + ret = run_command(&cmd); else - return run_command_silent_on_success(&cmd); + ret = run_command_silent_on_success(&cmd); + + if (!ret) + discard_index(r->index); + + return ret; } -int prepare_branch_to_be_rebased(struct replay_opts *opts, const char *commit) +int prepare_branch_to_be_rebased(struct repository *r, struct replay_opts *opts, + const char *commit) { const char *action; if (commit && *commit) { action = reflog_message(opts, "start", "checkout %s", commit); - if (run_git_checkout(opts, commit, action)) + if (run_git_checkout(r, opts, commit, action)) return error(_("could not checkout %s"), commit); } return 0; } -static int checkout_onto(struct replay_opts *opts, - const char *onto_name, const char *onto, +static int checkout_onto(struct repository *r, struct replay_opts *opts, + const char *onto_name, const struct object_id *onto, const char *orig_head) { struct object_id oid; @@ -3557,7 +3654,7 @@ static int checkout_onto(struct replay_opts *opts, if (get_oid(orig_head, &oid)) return error(_("%s: not a valid OID"), orig_head); - if (run_git_checkout(opts, onto, action)) { + if (run_git_checkout(r, opts, oid_to_hex(onto), action)) { apply_autostash(opts); sequencer_remove_state(opts); return error(_("could not detach HEAD")); @@ -3637,8 +3734,11 @@ static int pick_commits(struct repository *r, unlink(git_path_merge_head(the_repository)); delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF); - if (item->command == TODO_BREAK) + if (item->command == TODO_BREAK) { + if (!opts->verbose) + term_clear_line(); return stopped_at_head(r); + } } if (item->command <= TODO_SQUASH) { if (is_rebase_i(opts)) @@ -3660,11 +3760,14 @@ static int pick_commits(struct repository *r, } if (item->command == TODO_EDIT) { struct commit *commit = item->commit; - if (!res) + if (!res) { + if (!opts->verbose) + term_clear_line(); fprintf(stderr, _("Stopped at %s... %.*s\n"), short_commit_name(commit), item->arg_len, arg); + } return error_with_patch(r, commit, arg, item->arg_len, opts, res, !res); } @@ -3702,6 +3805,8 @@ static int pick_commits(struct repository *r, int saved = *end_of_arg; struct stat st; + if (!opts->verbose) + term_clear_line(); *end_of_arg = '\0'; res = do_exec(r, arg); *end_of_arg = saved; @@ -3860,10 +3965,13 @@ cleanup_head_ref: } apply_autostash(opts); - if (!opts->quiet) + if (!opts->quiet) { + if (!opts->verbose) + term_clear_line(); fprintf(stderr, "Successfully rebased and updated %s.\n", head_ref.buf); + } strbuf_release(&buf); strbuf_release(&head_ref); @@ -4833,16 +4941,16 @@ static int skip_unnecessary_picks(struct repository *r, int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags, const char *shortrevisions, const char *onto_name, - const char *onto, const char *orig_head, struct string_list *commands, - unsigned autosquash, struct todo_list *todo_list) + struct commit *onto, const char *orig_head, + struct string_list *commands, unsigned autosquash, + struct todo_list *todo_list) { const char *shortonto, *todo_file = rebase_path_todo(); struct todo_list new_todo = TODO_LIST_INIT; struct strbuf *buf = &todo_list->buf; - struct object_id oid; + struct object_id oid = onto->object.oid; int res; - get_oid(onto, &oid); shortonto = find_unique_abbrev(&oid, DEFAULT_ABBREV); if (buf->len == 0) { @@ -4885,7 +4993,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) || todo_list_check(todo_list, &new_todo)) { fprintf(stderr, _(edit_todo_list_advice)); - checkout_onto(opts, onto_name, onto, orig_head); + checkout_onto(r, opts, onto_name, &onto->object.oid, orig_head); todo_list_release(&new_todo); return -1; @@ -4904,7 +5012,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla todo_list_release(&new_todo); - if (checkout_onto(opts, onto_name, oid_to_hex(&oid), orig_head)) + if (checkout_onto(r, opts, onto_name, &oid, orig_head)) return -1; if (require_clean_work_tree(r, "rebase", "", 1, 1))