diff options
author | Junio C Hamano <gitster@pobox.com> | 2019-10-11 14:24:46 +0900 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-10-11 14:24:47 +0900 |
commit | 4608a029b490a87469680ee7d055a6d7cb5912c6 (patch) | |
tree | 6bc53915b66001d83e2fa1c6c7aa738545d713df /sequencer.c | |
parent | Merge branch 'tk/git-svn-trim-author-name' (diff) | |
parent | sequencer: simplify root commit creation (diff) | |
download | tgif-4608a029b490a87469680ee7d055a6d7cb5912c6.tar.xz |
Merge branch 'pw/rebase-i-show-HEAD-to-reword'
"git rebase -i" showed a wrong HEAD while "reword" open the editor.
* pw/rebase-i-show-HEAD-to-reword:
sequencer: simplify root commit creation
rebase -i: check for updated todo after squash and reword
rebase -i: always update HEAD before rewording
Diffstat (limited to 'sequencer.c')
-rw-r--r-- | sequencer.c | 130 |
1 files changed, 39 insertions, 91 deletions
diff --git a/sequencer.c b/sequencer.c index ea368bcfe9..501921e08c 100644 --- a/sequencer.c +++ b/sequencer.c @@ -869,34 +869,6 @@ static char *get_author(const char *message) return NULL; } -/* Read author-script and return an ident line (author <email> timestamp) */ -static const char *read_author_ident(struct strbuf *buf) -{ - struct strbuf out = STRBUF_INIT; - char *name, *email, *date; - - if (read_author_script(rebase_path_author_script(), - &name, &email, &date, 0)) - return NULL; - - /* validate date since fmt_ident() will die() on bad value */ - if (parse_date(date, &out)){ - warning(_("invalid date format '%s' in '%s'"), - date, rebase_path_author_script()); - strbuf_release(&out); - return NULL; - } - - strbuf_reset(&out); - strbuf_addstr(&out, fmt_ident(name, email, WANT_AUTHOR_IDENT, date, 0)); - strbuf_swap(buf, &out); - strbuf_release(&out); - free(name); - free(email); - free(date); - return buf->buf; -} - static const char staged_changes_advice[] = N_("you have staged changes in your working tree\n" "If these changes are meant to be squashed into the previous commit, run:\n" @@ -954,47 +926,6 @@ static int run_git_commit(struct repository *r, { struct child_process cmd = CHILD_PROCESS_INIT; - if ((flags & CREATE_ROOT_COMMIT) && !(flags & AMEND_MSG)) { - struct strbuf msg = STRBUF_INIT, script = STRBUF_INIT; - const char *author = NULL; - struct object_id root_commit, *cache_tree_oid; - int res = 0; - - if (is_rebase_i(opts)) { - author = read_author_ident(&script); - if (!author) { - strbuf_release(&script); - return -1; - } - } - - if (!defmsg) - BUG("root commit without message"); - - if (!(cache_tree_oid = get_cache_tree_oid(r->index))) - res = -1; - - if (!res) - res = strbuf_read_file(&msg, defmsg, 0); - - if (res <= 0) - res = error_errno(_("could not read '%s'"), defmsg); - else - res = commit_tree(msg.buf, msg.len, cache_tree_oid, - NULL, &root_commit, author, - opts->gpg_sign); - - strbuf_release(&msg); - strbuf_release(&script); - if (!res) { - update_ref(NULL, "CHERRY_PICK_HEAD", &root_commit, NULL, - REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR); - res = update_ref(NULL, "HEAD", &root_commit, NULL, 0, - UPDATE_REFS_MSG_ON_ERR); - } - return res < 0 ? error(_("writing root commit")) : 0; - } - cmd.git_cmd = 1; if (is_rebase_i(opts) && read_env_script(&cmd.env_array)) { @@ -1378,7 +1309,7 @@ static int try_to_commit(struct repository *r, struct object_id *oid) { struct object_id tree; - struct commit *current_head; + struct commit *current_head = NULL; struct commit_list *parents = NULL; struct commit_extra_header *extra = NULL; struct strbuf err = STRBUF_INIT; @@ -1413,7 +1344,8 @@ static int try_to_commit(struct repository *r, } parents = copy_commit_list(current_head->parents); extra = read_commit_extra_headers(current_head, exclude_gpgsig); - } else if (current_head) { + } else if (current_head && + (!(flags & CREATE_ROOT_COMMIT) || (flags & AMEND_MSG))) { commit_list_insert(current_head, &parents); } @@ -1490,8 +1422,7 @@ static int do_commit(struct repository *r, { int res = 1; - if (!(flags & EDIT_MSG) && !(flags & VERIFY_MSG) && - !(flags & CREATE_ROOT_COMMIT)) { + if (!(flags & EDIT_MSG) && !(flags & VERIFY_MSG)) { struct object_id oid; struct strbuf sb = STRBUF_INIT; @@ -1775,7 +1706,7 @@ static int do_pick_commit(struct repository *r, enum todo_command command, struct commit *commit, struct replay_opts *opts, - int final_fixup) + int final_fixup, int *check_todo) { unsigned int flags = opts->edit ? EDIT_MSG : 0; const char *msg_file = opts->edit ? NULL : git_path_merge_msg(r); @@ -1785,7 +1716,7 @@ static int do_pick_commit(struct repository *r, char *author = NULL; struct commit_message msg = { NULL, NULL, NULL, NULL }; struct strbuf msgbuf = STRBUF_INIT; - int res, unborn = 0, allow; + int res, unborn = 0, reword = 0, allow; if (opts->no_commit) { /* @@ -1855,7 +1786,7 @@ static int do_pick_commit(struct repository *r, opts); if (res || command != TODO_REWORD) goto leave; - flags |= EDIT_MSG | AMEND_MSG | VERIFY_MSG; + reword = 1; msg_file = NULL; goto fast_forward_edit; } @@ -1913,7 +1844,7 @@ static int do_pick_commit(struct repository *r, } if (command == TODO_REWORD) - flags |= EDIT_MSG | VERIFY_MSG; + reword = 1; else if (is_fixup(command)) { if (update_squash_messages(r, command, commit, opts)) return -1; @@ -1997,13 +1928,21 @@ static int do_pick_commit(struct repository *r, } else if (allow) flags |= ALLOW_EMPTY; if (!opts->no_commit) { -fast_forward_edit: if (author || command == TODO_REVERT || (flags & AMEND_MSG)) res = do_commit(r, msg_file, author, opts, flags); else res = error(_("unable to parse commit author")); + *check_todo = !!(flags & EDIT_MSG); + if (!res && reword) { +fast_forward_edit: + res = run_git_commit(r, NULL, opts, EDIT_MSG | + VERIFY_MSG | AMEND_MSG | + (flags & ALLOW_EMPTY)); + *check_todo = 1; + } } + if (!res && final_fixup) { unlink(rebase_path_fixup_msg()); unlink(rebase_path_squash_msg()); @@ -3828,6 +3767,7 @@ static int pick_commits(struct repository *r, while (todo_list->current < todo_list->nr) { struct todo_item *item = todo_list->items + todo_list->current; const char *arg = todo_item_get_arg(todo_list, item); + int check_todo = 0; if (save_todo(todo_list, opts)) return -1; @@ -3866,7 +3806,8 @@ static int pick_commits(struct repository *r, command_to_string(item->command), NULL), 1); res = do_pick_commit(r, item->command, item->commit, - opts, is_final_fixup(todo_list)); + opts, is_final_fixup(todo_list), + &check_todo); if (is_rebase_i(opts) && res < 0) { /* Reschedule */ advise(_(rescheduled_advice), @@ -3923,7 +3864,6 @@ static int pick_commits(struct repository *r, } else if (item->command == TODO_EXEC) { char *end_of_arg = (char *)(arg + item->arg_len); int saved = *end_of_arg; - struct stat st; if (!opts->verbose) term_clear_line(); @@ -3934,17 +3874,8 @@ static int pick_commits(struct repository *r, if (res) { if (opts->reschedule_failed_exec) reschedule = 1; - } else if (stat(get_todo_path(opts), &st)) - res = error_errno(_("could not stat '%s'"), - get_todo_path(opts)); - else if (match_stat_data(&todo_list->stat, &st)) { - /* Reread the todo file if it has changed. */ - todo_list_release(todo_list); - if (read_populate_todo(r, todo_list, opts)) - res = -1; /* message was printed */ - /* `current` will be incremented below */ - todo_list->current = -1; } + check_todo = 1; } else if (item->command == TODO_LABEL) { if ((res = do_label(r, arg, item->arg_len))) reschedule = 1; @@ -3980,6 +3911,20 @@ static int pick_commits(struct repository *r, item->commit, arg, item->arg_len, opts, res, 0); + } else if (check_todo && !res) { + struct stat st; + + if (stat(get_todo_path(opts), &st)) { + res = error_errno(_("could not stat '%s'"), + get_todo_path(opts)); + } else if (match_stat_data(&todo_list->stat, &st)) { + /* Reread the todo file if it has changed. */ + todo_list_release(todo_list); + if (read_populate_todo(r, todo_list, opts)) + res = -1; /* message was printed */ + /* `current` will be incremented below */ + todo_list->current = -1; + } } todo_list->current++; @@ -4306,9 +4251,12 @@ static int single_pick(struct repository *r, struct commit *cmit, struct replay_opts *opts) { + int check_todo; + setenv(GIT_REFLOG_ACTION, action_name(opts), 0); return do_pick_commit(r, opts->action == REPLAY_PICK ? - TODO_PICK : TODO_REVERT, cmit, opts, 0); + TODO_PICK : TODO_REVERT, cmit, opts, 0, + &check_todo); } int sequencer_pick_revisions(struct repository *r, |