git
/
sequencer.c
6817 строк · 188.3 Кб
1#define USE_THE_REPOSITORY_VARIABLE2
3#include "git-compat-util.h"4#include "abspath.h"5#include "advice.h"6#include "config.h"7#include "copy.h"8#include "environment.h"9#include "gettext.h"10#include "hex.h"11#include "lockfile.h"12#include "dir.h"13#include "object-file.h"14#include "object-name.h"15#include "object-store-ll.h"16#include "object.h"17#include "pager.h"18#include "commit.h"19#include "sequencer.h"20#include "run-command.h"21#include "hook.h"22#include "utf8.h"23#include "cache-tree.h"24#include "diff.h"25#include "path.h"26#include "revision.h"27#include "rerere.h"28#include "merge.h"29#include "merge-ort.h"30#include "merge-ort-wrappers.h"31#include "refs.h"32#include "sparse-index.h"33#include "strvec.h"34#include "quote.h"35#include "trailer.h"36#include "log-tree.h"37#include "wt-status.h"38#include "hashmap.h"39#include "notes-utils.h"40#include "sigchain.h"41#include "unpack-trees.h"42#include "oidmap.h"43#include "oidset.h"44#include "commit-slab.h"45#include "alias.h"46#include "commit-reach.h"47#include "rebase-interactive.h"48#include "reset.h"49#include "branch.h"50
51#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"52
53/*
54* To accommodate common filesystem limitations, where the loose refs' file
55* names must not exceed `NAME_MAX`, the labels generated by `git rebase
56* --rebase-merges` need to be truncated if the corresponding commit subjects
57* are too long.
58* Add some margin to stay clear from reaching `NAME_MAX`.
59*/
60#define GIT_MAX_LABEL_LENGTH ((NAME_MAX) - (LOCK_SUFFIX_LEN) - 16)61
62static const char sign_off_header[] = "Signed-off-by: ";63static const char cherry_picked_prefix[] = "(cherry picked from commit ";64
65GIT_PATH_FUNC(git_path_commit_editmsg, "COMMIT_EDITMSG")66
67static GIT_PATH_FUNC(git_path_seq_dir, "sequencer")68
69static GIT_PATH_FUNC(git_path_todo_file, "sequencer/todo")70static GIT_PATH_FUNC(git_path_opts_file, "sequencer/opts")71static GIT_PATH_FUNC(git_path_head_file, "sequencer/head")72static GIT_PATH_FUNC(git_path_abort_safety_file, "sequencer/abort-safety")73
74static GIT_PATH_FUNC(rebase_path, "rebase-merge")75/*
76* The file containing rebase commands, comments, and empty lines.
77* This file is created by "git rebase -i" then edited by the user. As
78* the lines are processed, they are removed from the front of this
79* file and written to the tail of 'done'.
80*/
81GIT_PATH_FUNC(rebase_path_todo, "rebase-merge/git-rebase-todo")82GIT_PATH_FUNC(rebase_path_todo_backup, "rebase-merge/git-rebase-todo.backup")83
84GIT_PATH_FUNC(rebase_path_dropped, "rebase-merge/dropped")85
86/*
87* The rebase command lines that have already been processed. A line
88* is moved here when it is first handled, before any associated user
89* actions.
90*/
91static GIT_PATH_FUNC(rebase_path_done, "rebase-merge/done")92/*
93* The file to keep track of how many commands were already processed (e.g.
94* for the prompt).
95*/
96static GIT_PATH_FUNC(rebase_path_msgnum, "rebase-merge/msgnum")97/*
98* The file to keep track of how many commands are to be processed in total
99* (e.g. for the prompt).
100*/
101static GIT_PATH_FUNC(rebase_path_msgtotal, "rebase-merge/end")102/*
103* The commit message that is planned to be used for any changes that
104* need to be committed following a user interaction.
105*/
106static GIT_PATH_FUNC(rebase_path_message, "rebase-merge/message")107/*
108* The file into which is accumulated the suggested commit message for
109* squash/fixup commands. When the first of a series of squash/fixups
110* is seen, the file is created and the commit message from the
111* previous commit and from the first squash/fixup commit are written
112* to it. The commit message for each subsequent squash/fixup commit
113* is appended to the file as it is processed.
114*/
115static GIT_PATH_FUNC(rebase_path_squash_msg, "rebase-merge/message-squash")116/*
117* If the current series of squash/fixups has not yet included a squash
118* command, then this file exists and holds the commit message of the
119* original "pick" commit. (If the series ends without a "squash"
120* command, then this can be used as the commit message of the combined
121* commit without opening the editor.)
122*/
123static GIT_PATH_FUNC(rebase_path_fixup_msg, "rebase-merge/message-fixup")124/*
125* This file contains the list fixup/squash commands that have been
126* accumulated into message-fixup or message-squash so far.
127*/
128static GIT_PATH_FUNC(rebase_path_current_fixups, "rebase-merge/current-fixups")129/*
130* A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
131* GIT_AUTHOR_DATE that will be used for the commit that is currently
132* being rebased.
133*/
134static GIT_PATH_FUNC(rebase_path_author_script, "rebase-merge/author-script")135/*
136* When an "edit" rebase command is being processed, the SHA1 of the
137* commit to be edited is recorded in this file. When "git rebase
138* --continue" is executed, if there are any staged changes then they
139* will be amended to the HEAD commit, but only provided the HEAD
140* commit is still the commit to be edited. When any other rebase
141* command is processed, this file is deleted.
142*/
143static GIT_PATH_FUNC(rebase_path_amend, "rebase-merge/amend")144/*
145* When we stop at a given patch via the "edit" command, this file contains
146* the commit object name of the corresponding patch.
147*/
148static GIT_PATH_FUNC(rebase_path_stopped_sha, "rebase-merge/stopped-sha")149/*
150* When we stop for the user to resolve conflicts this file contains
151* the patch of the commit that is being picked.
152*/
153static GIT_PATH_FUNC(rebase_path_patch, "rebase-merge/patch")154/*
155* For the post-rewrite hook, we make a list of rewritten commits and
156* their new sha1s. The rewritten-pending list keeps the sha1s of
157* commits that have been processed, but not committed yet,
158* e.g. because they are waiting for a 'squash' command.
159*/
160static GIT_PATH_FUNC(rebase_path_rewritten_list, "rebase-merge/rewritten-list")161static GIT_PATH_FUNC(rebase_path_rewritten_pending,162"rebase-merge/rewritten-pending")163
164/*
165* The path of the file containing the OID of the "squash onto" commit, i.e.
166* the dummy commit used for `reset [new root]`.
167*/
168static GIT_PATH_FUNC(rebase_path_squash_onto, "rebase-merge/squash-onto")169
170/*
171* The path of the file listing refs that need to be deleted after the rebase
172* finishes. This is used by the `label` command to record the need for cleanup.
173*/
174static GIT_PATH_FUNC(rebase_path_refs_to_delete, "rebase-merge/refs-to-delete")175
176/*
177* The update-refs file stores a list of refs that will be updated at the end
178* of the rebase sequence. The 'update-ref <ref>' commands in the todo file
179* update the OIDs for the refs in this file, but the refs are not updated
180* until the end of the rebase sequence.
181*
182* rebase_path_update_refs() returns the path to this file for a given
183* worktree directory. For the current worktree, pass the_repository->gitdir.
184*/
185static char *rebase_path_update_refs(const char *wt_git_dir)186{
187return xstrfmt("%s/rebase-merge/update-refs", wt_git_dir);188}
189
190/*
191* The following files are written by git-rebase just after parsing the
192* command-line.
193*/
194static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")195static GIT_PATH_FUNC(rebase_path_cdate_is_adate, "rebase-merge/cdate_is_adate")196static GIT_PATH_FUNC(rebase_path_ignore_date, "rebase-merge/ignore_date")197static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")198static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")199static GIT_PATH_FUNC(rebase_path_quiet, "rebase-merge/quiet")200static GIT_PATH_FUNC(rebase_path_signoff, "rebase-merge/signoff")201static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")202static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")203static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")204static GIT_PATH_FUNC(rebase_path_strategy, "rebase-merge/strategy")205static GIT_PATH_FUNC(rebase_path_strategy_opts, "rebase-merge/strategy_opts")206static GIT_PATH_FUNC(rebase_path_allow_rerere_autoupdate, "rebase-merge/allow_rerere_autoupdate")207static GIT_PATH_FUNC(rebase_path_reschedule_failed_exec, "rebase-merge/reschedule-failed-exec")208static GIT_PATH_FUNC(rebase_path_no_reschedule_failed_exec, "rebase-merge/no-reschedule-failed-exec")209static GIT_PATH_FUNC(rebase_path_drop_redundant_commits, "rebase-merge/drop_redundant_commits")210static GIT_PATH_FUNC(rebase_path_keep_redundant_commits, "rebase-merge/keep_redundant_commits")211
212/*
213* A 'struct replay_ctx' represents the private state of the sequencer.
214*/
215struct replay_ctx {216/*217* The commit message that will be used except at the end of a
218* chain of fixup and squash commands.
219*/
220struct strbuf message;221/*222* The list of completed fixup and squash commands in the
223* current chain.
224*/
225struct strbuf current_fixups;226/*227* Stores the reflog message that will be used when creating a
228* commit. Points to a static buffer and should not be free()'d.
229*/
230const char *reflog_message;231/*232* The number of completed fixup and squash commands in the
233* current chain.
234*/
235int current_fixup_count;236/*237* Whether message contains a commit message.
238*/
239unsigned have_message :1;240};241
242struct replay_ctx* replay_ctx_new(void)243{
244struct replay_ctx *ctx = xcalloc(1, sizeof(*ctx));245
246strbuf_init(&ctx->current_fixups, 0);247strbuf_init(&ctx->message, 0);248
249return ctx;250}
251
252/**
253* A 'struct update_refs_record' represents a value in the update-refs
254* list. We use a string_list to map refs to these (before, after) pairs.
255*/
256struct update_ref_record {257struct object_id before;258struct object_id after;259};260
261static struct update_ref_record *init_update_ref_record(const char *ref)262{
263struct update_ref_record *rec;264
265CALLOC_ARRAY(rec, 1);266
267oidcpy(&rec->before, null_oid());268oidcpy(&rec->after, null_oid());269
270/* This may fail, but that's fine, we will keep the null OID. */271refs_read_ref(get_main_ref_store(the_repository), ref, &rec->before);272
273return rec;274}
275
276static int git_sequencer_config(const char *k, const char *v,277const struct config_context *ctx, void *cb)278{
279struct replay_opts *opts = cb;280
281if (!strcmp(k, "commit.cleanup")) {282if (!v)283return config_error_nonbool(k);284
285if (!strcmp(v, "verbatim")) {286opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_NONE;287opts->explicit_cleanup = 1;288} else if (!strcmp(v, "whitespace")) {289opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_SPACE;290opts->explicit_cleanup = 1;291} else if (!strcmp(v, "strip")) {292opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_ALL;293opts->explicit_cleanup = 1;294} else if (!strcmp(v, "scissors")) {295opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_SCISSORS;296opts->explicit_cleanup = 1;297} else {298warning(_("invalid commit message cleanup mode '%s'"),299v);300}301
302return 0;303}304
305if (!strcmp(k, "commit.gpgsign")) {306free(opts->gpg_sign);307opts->gpg_sign = git_config_bool(k, v) ? xstrdup("") : NULL;308return 0;309}310
311if (!opts->default_strategy && !strcmp(k, "pull.twohead")) {312int ret = git_config_string(&opts->default_strategy, k, v);313if (ret == 0) {314/*315* pull.twohead is allowed to be multi-valued; we only
316* care about the first value.
317*/
318char *tmp = strchr(opts->default_strategy, ' ');319if (tmp)320*tmp = '\0';321}322return ret;323}324
325if (opts->action == REPLAY_REVERT && !strcmp(k, "revert.reference"))326opts->commit_use_reference = git_config_bool(k, v);327
328return git_diff_basic_config(k, v, ctx, NULL);329}
330
331void sequencer_init_config(struct replay_opts *opts)332{
333opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_NONE;334git_config(git_sequencer_config, opts);335}
336
337static inline int is_rebase_i(const struct replay_opts *opts)338{
339return opts->action == REPLAY_INTERACTIVE_REBASE;340}
341
342static const char *get_dir(const struct replay_opts *opts)343{
344if (is_rebase_i(opts))345return rebase_path();346return git_path_seq_dir();347}
348
349static const char *get_todo_path(const struct replay_opts *opts)350{
351if (is_rebase_i(opts))352return rebase_path_todo();353return git_path_todo_file();354}
355
356/*
357* Returns 0 for non-conforming footer
358* Returns 1 for conforming footer
359* Returns 2 when sob exists within conforming footer
360* Returns 3 when sob exists within conforming footer as last entry
361*/
362static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,363size_t ignore_footer)364{
365struct trailer_iterator iter;366size_t i = 0;367int found_sob = 0, found_sob_last = 0;368char saved_char;369
370if (ignore_footer) {371saved_char = sb->buf[sb->len - ignore_footer];372sb->buf[sb->len - ignore_footer] = '\0';373}374
375trailer_iterator_init(&iter, sb->buf);376
377if (ignore_footer)378sb->buf[sb->len - ignore_footer] = saved_char;379
380while (trailer_iterator_advance(&iter)) {381i++;382if (sob && !strncmp(iter.raw, sob->buf, sob->len))383found_sob = i;384}385trailer_iterator_release(&iter);386
387if (!i)388return 0;389
390found_sob_last = (int)i == found_sob;391
392if (found_sob_last)393return 3;394if (found_sob)395return 2;396return 1;397}
398
399static const char *gpg_sign_opt_quoted(struct replay_opts *opts)400{
401static struct strbuf buf = STRBUF_INIT;402
403strbuf_reset(&buf);404if (opts->gpg_sign)405sq_quotef(&buf, "-S%s", opts->gpg_sign);406return buf.buf;407}
408
409static void replay_ctx_release(struct replay_ctx *ctx)410{
411strbuf_release(&ctx->current_fixups);412strbuf_release(&ctx->message);413}
414
415void replay_opts_release(struct replay_opts *opts)416{
417struct replay_ctx *ctx = opts->ctx;418
419free(opts->gpg_sign);420free(opts->reflog_action);421free(opts->default_strategy);422free(opts->strategy);423strvec_clear (&opts->xopts);424if (opts->revs)425release_revisions(opts->revs);426free(opts->revs);427replay_ctx_release(ctx);428free(opts->ctx);429}
430
431int sequencer_remove_state(struct replay_opts *opts)432{
433struct strbuf buf = STRBUF_INIT;434int ret = 0;435
436if (is_rebase_i(opts) &&437strbuf_read_file(&buf, rebase_path_refs_to_delete(), 0) > 0) {438char *p = buf.buf;439while (*p) {440char *eol = strchr(p, '\n');441if (eol)442*eol = '\0';443if (refs_delete_ref(get_main_ref_store(the_repository), "(rebase) cleanup", p, NULL, 0) < 0) {444warning(_("could not delete '%s'"), p);445ret = -1;446}447if (!eol)448break;449p = eol + 1;450}451}452
453strbuf_reset(&buf);454strbuf_addstr(&buf, get_dir(opts));455if (remove_dir_recursively(&buf, 0))456ret = error(_("could not remove '%s'"), buf.buf);457strbuf_release(&buf);458
459return ret;460}
461
462static const char *action_name(const struct replay_opts *opts)463{
464switch (opts->action) {465case REPLAY_REVERT:466return N_("revert");467case REPLAY_PICK:468return N_("cherry-pick");469case REPLAY_INTERACTIVE_REBASE:470return N_("rebase");471}472die(_("unknown action: %d"), opts->action);473}
474
475struct commit_message {476char *parent_label;477char *label;478char *subject;479const char *message;480};481
482static const char *short_commit_name(struct repository *r, struct commit *commit)483{
484return repo_find_unique_abbrev(r, &commit->object.oid, DEFAULT_ABBREV);485}
486
487static int get_message(struct commit *commit, struct commit_message *out)488{
489const char *abbrev, *subject;490int subject_len;491
492out->message = repo_logmsg_reencode(the_repository, commit, NULL,493get_commit_output_encoding());494abbrev = short_commit_name(the_repository, commit);495
496subject_len = find_commit_subject(out->message, &subject);497
498out->subject = xmemdupz(subject, subject_len);499out->label = xstrfmt("%s (%s)", abbrev, out->subject);500out->parent_label = xstrfmt("parent of %s", out->label);501
502return 0;503}
504
505static void free_message(struct commit *commit, struct commit_message *msg)506{
507free(msg->parent_label);508free(msg->label);509free(msg->subject);510repo_unuse_commit_buffer(the_repository, commit, msg->message);511}
512
513const char *rebase_resolvemsg =514N_("Resolve all conflicts manually, mark them as resolved with\n"515"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
516"You can instead skip this commit: run \"git rebase --skip\".\n"
517"To abort and get back to the state before \"git rebase\", run "
518"\"git rebase --abort\".");519
520static void print_advice(struct repository *r, int show_hint,521struct replay_opts *opts)522{
523const char *msg;524
525if (is_rebase_i(opts))526msg = rebase_resolvemsg;527else528msg = getenv("GIT_CHERRY_PICK_HELP");529
530if (msg) {531advise_if_enabled(ADVICE_MERGE_CONFLICT, "%s", msg);532/*533* A conflict has occurred but the porcelain
534* (typically rebase --interactive) wants to take care
535* of the commit itself so remove CHERRY_PICK_HEAD
536*/
537refs_delete_ref(get_main_ref_store(r), "", "CHERRY_PICK_HEAD",538NULL, REF_NO_DEREF);539return;540}541
542if (show_hint) {543if (opts->no_commit)544advise_if_enabled(ADVICE_MERGE_CONFLICT,545_("after resolving the conflicts, mark the corrected paths\n"546"with 'git add <paths>' or 'git rm <paths>'"));547else if (opts->action == REPLAY_PICK)548advise_if_enabled(ADVICE_MERGE_CONFLICT,549_("After resolving the conflicts, mark them with\n"550"\"git add/rm <pathspec>\", then run\n"551"\"git cherry-pick --continue\".\n"552"You can instead skip this commit with \"git cherry-pick --skip\".\n"553"To abort and get back to the state before \"git cherry-pick\",\n"554"run \"git cherry-pick --abort\"."));555else if (opts->action == REPLAY_REVERT)556advise_if_enabled(ADVICE_MERGE_CONFLICT,557_("After resolving the conflicts, mark them with\n"558"\"git add/rm <pathspec>\", then run\n"559"\"git revert --continue\".\n"560"You can instead skip this commit with \"git revert --skip\".\n"561"To abort and get back to the state before \"git revert\",\n"562"run \"git revert --abort\"."));563else564BUG("unexpected pick action in print_advice()");565}566}
567
568static int write_message(const void *buf, size_t len, const char *filename,569int append_eol)570{
571struct lock_file msg_file = LOCK_INIT;572
573int msg_fd = hold_lock_file_for_update(&msg_file, filename, 0);574if (msg_fd < 0)575return error_errno(_("could not lock '%s'"), filename);576if (write_in_full(msg_fd, buf, len) < 0) {577error_errno(_("could not write to '%s'"), filename);578rollback_lock_file(&msg_file);579return -1;580}581if (append_eol && write(msg_fd, "\n", 1) < 0) {582error_errno(_("could not write eol to '%s'"), filename);583rollback_lock_file(&msg_file);584return -1;585}586if (commit_lock_file(&msg_file) < 0)587return error(_("failed to finalize '%s'"), filename);588
589return 0;590}
591
592int read_oneliner(struct strbuf *buf,593const char *path, unsigned flags)594{
595int orig_len = buf->len;596
597if (strbuf_read_file(buf, path, 0) < 0) {598if ((flags & READ_ONELINER_WARN_MISSING) ||599(errno != ENOENT && errno != ENOTDIR))600warning_errno(_("could not read '%s'"), path);601return 0;602}603
604if (buf->len > orig_len && buf->buf[buf->len - 1] == '\n') {605if (--buf->len > orig_len && buf->buf[buf->len - 1] == '\r')606--buf->len;607buf->buf[buf->len] = '\0';608}609
610if ((flags & READ_ONELINER_SKIP_IF_EMPTY) && buf->len == orig_len)611return 0;612
613return 1;614}
615
616static struct tree *empty_tree(struct repository *r)617{
618return lookup_tree(r, the_hash_algo->empty_tree);619}
620
621static int error_dirty_index(struct repository *repo, struct replay_opts *opts)622{
623if (repo_read_index_unmerged(repo))624return error_resolve_conflict(action_name(opts));625
626error(_("your local changes would be overwritten by %s."),627_(action_name(opts)));628
629if (advice_enabled(ADVICE_COMMIT_BEFORE_MERGE))630advise(_("commit your changes or stash them to proceed."));631return -1;632}
633
634static void update_abort_safety_file(void)635{
636struct object_id head;637
638/* Do nothing on a single-pick */639if (!file_exists(git_path_seq_dir()))640return;641
642if (!repo_get_oid(the_repository, "HEAD", &head))643write_file(git_path_abort_safety_file(), "%s", oid_to_hex(&head));644else645write_file(git_path_abort_safety_file(), "%s", "");646}
647
648static int fast_forward_to(struct repository *r,649const struct object_id *to,650const struct object_id *from,651int unborn,652struct replay_opts *opts)653{
654struct ref_transaction *transaction;655struct strbuf sb = STRBUF_INIT;656struct strbuf err = STRBUF_INIT;657
658repo_read_index(r);659if (checkout_fast_forward(r, from, to, 1))660return -1; /* the callee should have complained already */661
662strbuf_addf(&sb, "%s: fast-forward", action_name(opts));663
664transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),665&err);666if (!transaction ||667ref_transaction_update(transaction, "HEAD",668to, unborn && !is_rebase_i(opts) ?669null_oid() : from, NULL, NULL,6700, sb.buf, &err) ||671ref_transaction_commit(transaction, &err)) {672ref_transaction_free(transaction);673error("%s", err.buf);674strbuf_release(&sb);675strbuf_release(&err);676return -1;677}678
679strbuf_release(&sb);680strbuf_release(&err);681ref_transaction_free(transaction);682update_abort_safety_file();683return 0;684}
685
686enum commit_msg_cleanup_mode get_cleanup_mode(const char *cleanup_arg,687int use_editor)688{
689if (!cleanup_arg || !strcmp(cleanup_arg, "default"))690return use_editor ? COMMIT_MSG_CLEANUP_ALL :691COMMIT_MSG_CLEANUP_SPACE;692else if (!strcmp(cleanup_arg, "verbatim"))693return COMMIT_MSG_CLEANUP_NONE;694else if (!strcmp(cleanup_arg, "whitespace"))695return COMMIT_MSG_CLEANUP_SPACE;696else if (!strcmp(cleanup_arg, "strip"))697return COMMIT_MSG_CLEANUP_ALL;698else if (!strcmp(cleanup_arg, "scissors"))699return use_editor ? COMMIT_MSG_CLEANUP_SCISSORS :700COMMIT_MSG_CLEANUP_SPACE;701else702die(_("Invalid cleanup mode %s"), cleanup_arg);703}
704
705/*
706* NB using int rather than enum cleanup_mode to stop clang's
707* -Wtautological-constant-out-of-range-compare complaining that the comparison
708* is always true.
709*/
710static const char *describe_cleanup_mode(int cleanup_mode)711{
712static const char *modes[] = { "whitespace",713"verbatim",714"scissors",715"strip" };716
717if (cleanup_mode < ARRAY_SIZE(modes))718return modes[cleanup_mode];719
720BUG("invalid cleanup_mode provided (%d)", cleanup_mode);721}
722
723void append_conflicts_hint(struct index_state *istate,724struct strbuf *msgbuf, enum commit_msg_cleanup_mode cleanup_mode)725{
726int i;727
728if (cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS) {729strbuf_addch(msgbuf, '\n');730wt_status_append_cut_line(msgbuf);731strbuf_addstr(msgbuf, comment_line_str);732}733
734strbuf_addch(msgbuf, '\n');735strbuf_commented_addf(msgbuf, comment_line_str, "Conflicts:\n");736for (i = 0; i < istate->cache_nr;) {737const struct cache_entry *ce = istate->cache[i++];738if (ce_stage(ce)) {739strbuf_commented_addf(msgbuf, comment_line_str,740"\t%s\n", ce->name);741while (i < istate->cache_nr &&742!strcmp(ce->name, istate->cache[i]->name))743i++;744}745}746}
747
748static int do_recursive_merge(struct repository *r,749struct commit *base, struct commit *next,750const char *base_label, const char *next_label,751struct object_id *head, struct strbuf *msgbuf,752struct replay_opts *opts)753{
754struct merge_options o;755struct merge_result result;756struct tree *next_tree, *base_tree, *head_tree;757int clean, show_output;758int i;759struct lock_file index_lock = LOCK_INIT;760
761if (repo_hold_locked_index(r, &index_lock, LOCK_REPORT_ON_ERROR) < 0)762return -1;763
764repo_read_index(r);765
766init_ui_merge_options(&o, r);767o.ancestor = base ? base_label : "(empty tree)";768o.branch1 = "HEAD";769o.branch2 = next ? next_label : "(empty tree)";770if (is_rebase_i(opts))771o.buffer_output = 2;772o.show_rename_progress = 1;773
774head_tree = parse_tree_indirect(head);775if (!head_tree)776return error(_("unable to read tree (%s)"), oid_to_hex(head));777next_tree = next ? repo_get_commit_tree(r, next) : empty_tree(r);778base_tree = base ? repo_get_commit_tree(r, base) : empty_tree(r);779
780for (i = 0; i < opts->xopts.nr; i++)781parse_merge_opt(&o, opts->xopts.v[i]);782
783if (!opts->strategy || !strcmp(opts->strategy, "ort")) {784memset(&result, 0, sizeof(result));785merge_incore_nonrecursive(&o, base_tree, head_tree, next_tree,786&result);787show_output = !is_rebase_i(opts) || !result.clean;788/*789* TODO: merge_switch_to_result will update index/working tree;
790* we only really want to do that if !result.clean || this is
791* the final patch to be picked. But determining this is the
792* final patch would take some work, and "head_tree" would need
793* to be replace with the tree the index matched before we
794* started doing any picks.
795*/
796merge_switch_to_result(&o, head_tree, &result, 1, show_output);797clean = result.clean;798} else {799ensure_full_index(r->index);800clean = merge_trees(&o, head_tree, next_tree, base_tree);801if (is_rebase_i(opts) && clean <= 0)802fputs(o.obuf.buf, stdout);803strbuf_release(&o.obuf);804}805if (clean < 0) {806rollback_lock_file(&index_lock);807return clean;808}809
810if (write_locked_index(r->index, &index_lock,811COMMIT_LOCK | SKIP_IF_UNCHANGED))812/*813* TRANSLATORS: %s will be "revert", "cherry-pick" or
814* "rebase".
815*/
816return error(_("%s: Unable to write new index file"),817_(action_name(opts)));818
819if (!clean)820append_conflicts_hint(r->index, msgbuf,821opts->default_msg_cleanup);822
823return !clean;824}
825
826static struct object_id *get_cache_tree_oid(struct index_state *istate)827{
828if (!cache_tree_fully_valid(istate->cache_tree))829if (cache_tree_update(istate, 0)) {830error(_("unable to update cache tree"));831return NULL;832}833
834return &istate->cache_tree->oid;835}
836
837static int is_index_unchanged(struct repository *r)838{
839struct object_id head_oid, *cache_tree_oid;840const struct object_id *head_tree_oid;841struct commit *head_commit;842struct index_state *istate = r->index;843const char *head_name;844
845if (!refs_resolve_ref_unsafe(get_main_ref_store(the_repository), "HEAD", RESOLVE_REF_READING, &head_oid, NULL)) {846/* Check to see if this is an unborn branch */847head_name = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),848"HEAD",849RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,850&head_oid, NULL);851if (!head_name ||852!starts_with(head_name, "refs/heads/") ||853!is_null_oid(&head_oid))854return error(_("could not resolve HEAD commit"));855head_tree_oid = the_hash_algo->empty_tree;856} else {857head_commit = lookup_commit(r, &head_oid);858
859/*860* If head_commit is NULL, check_commit, called from
861* lookup_commit, would have indicated that head_commit is not
862* a commit object already. repo_parse_commit() will return failure
863* without further complaints in such a case. Otherwise, if
864* the commit is invalid, repo_parse_commit() will complain. So
865* there is nothing for us to say here. Just return failure.
866*/
867if (repo_parse_commit(r, head_commit))868return -1;869
870head_tree_oid = get_commit_tree_oid(head_commit);871}872
873if (!(cache_tree_oid = get_cache_tree_oid(istate)))874return -1;875
876return oideq(cache_tree_oid, head_tree_oid);877}
878
879static int write_author_script(const char *message)880{
881struct strbuf buf = STRBUF_INIT;882const char *eol;883int res;884
885for (;;)886if (!*message || starts_with(message, "\n")) {887missing_author:888/* Missing 'author' line? */889unlink(rebase_path_author_script());890return 0;891} else if (skip_prefix(message, "author ", &message))892break;893else if ((eol = strchr(message, '\n')))894message = eol + 1;895else896goto missing_author;897
898strbuf_addstr(&buf, "GIT_AUTHOR_NAME='");899while (*message && *message != '\n' && *message != '\r')900if (skip_prefix(message, " <", &message))901break;902else if (*message != '\'')903strbuf_addch(&buf, *(message++));904else905strbuf_addf(&buf, "'\\%c'", *(message++));906strbuf_addstr(&buf, "'\nGIT_AUTHOR_EMAIL='");907while (*message && *message != '\n' && *message != '\r')908if (skip_prefix(message, "> ", &message))909break;910else if (*message != '\'')911strbuf_addch(&buf, *(message++));912else913strbuf_addf(&buf, "'\\%c'", *(message++));914strbuf_addstr(&buf, "'\nGIT_AUTHOR_DATE='@");915while (*message && *message != '\n' && *message != '\r')916if (*message != '\'')917strbuf_addch(&buf, *(message++));918else919strbuf_addf(&buf, "'\\%c'", *(message++));920strbuf_addch(&buf, '\'');921res = write_message(buf.buf, buf.len, rebase_path_author_script(), 1);922strbuf_release(&buf);923return res;924}
925
926/**
927* Take a series of KEY='VALUE' lines where VALUE part is
928* sq-quoted, and append <KEY, VALUE> at the end of the string list
929*/
930static int parse_key_value_squoted(char *buf, struct string_list *list)931{
932while (*buf) {933struct string_list_item *item;934char *np;935char *cp = strchr(buf, '=');936if (!cp) {937np = strchrnul(buf, '\n');938return error(_("no key present in '%.*s'"),939(int) (np - buf), buf);940}941np = strchrnul(cp, '\n');942*cp++ = '\0';943item = string_list_append(list, buf);944
945buf = np + (*np == '\n');946*np = '\0';947cp = sq_dequote(cp);948if (!cp)949return error(_("unable to dequote value of '%s'"),950item->string);951item->util = xstrdup(cp);952}953return 0;954}
955
956/**
957* Reads and parses the state directory's "author-script" file, and sets name,
958* email and date accordingly.
959* Returns 0 on success, -1 if the file could not be parsed.
960*
961* The author script is of the format:
962*
963* GIT_AUTHOR_NAME='$author_name'
964* GIT_AUTHOR_EMAIL='$author_email'
965* GIT_AUTHOR_DATE='$author_date'
966*
967* where $author_name, $author_email and $author_date are quoted. We are strict
968* with our parsing, as the file was meant to be eval'd in the now-removed
969* git-am.sh/git-rebase--interactive.sh scripts, and thus if the file differs
970* from what this function expects, it is better to bail out than to do
971* something that the user does not expect.
972*/
973int read_author_script(const char *path, char **name, char **email, char **date,974int allow_missing)975{
976struct strbuf buf = STRBUF_INIT;977struct string_list kv = STRING_LIST_INIT_DUP;978int retval = -1; /* assume failure */979int i, name_i = -2, email_i = -2, date_i = -2, err = 0;980
981if (strbuf_read_file(&buf, path, 256) <= 0) {982strbuf_release(&buf);983if (errno == ENOENT && allow_missing)984return 0;985else986return error_errno(_("could not open '%s' for reading"),987path);988}989
990if (parse_key_value_squoted(buf.buf, &kv))991goto finish;992
993for (i = 0; i < kv.nr; i++) {994if (!strcmp(kv.items[i].string, "GIT_AUTHOR_NAME")) {995if (name_i != -2)996name_i = error(_("'GIT_AUTHOR_NAME' already given"));997else998name_i = i;999} else if (!strcmp(kv.items[i].string, "GIT_AUTHOR_EMAIL")) {1000if (email_i != -2)1001email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));1002else1003email_i = i;1004} else if (!strcmp(kv.items[i].string, "GIT_AUTHOR_DATE")) {1005if (date_i != -2)1006date_i = error(_("'GIT_AUTHOR_DATE' already given"));1007else1008date_i = i;1009} else {1010err = error(_("unknown variable '%s'"),1011kv.items[i].string);1012}1013}1014if (name_i == -2)1015error(_("missing 'GIT_AUTHOR_NAME'"));1016if (email_i == -2)1017error(_("missing 'GIT_AUTHOR_EMAIL'"));1018if (date_i == -2)1019error(_("missing 'GIT_AUTHOR_DATE'"));1020if (name_i < 0 || email_i < 0 || date_i < 0 || err)1021goto finish;1022*name = kv.items[name_i].util;1023*email = kv.items[email_i].util;1024*date = kv.items[date_i].util;1025retval = 0;1026finish:1027string_list_clear(&kv, !!retval);1028strbuf_release(&buf);1029return retval;1030}
1031
1032/*
1033* Read a GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL AND GIT_AUTHOR_DATE from a
1034* file with shell quoting into struct strvec. Returns -1 on
1035* error, 0 otherwise.
1036*/
1037static int read_env_script(struct strvec *env)1038{
1039char *name, *email, *date;1040
1041if (read_author_script(rebase_path_author_script(),1042&name, &email, &date, 0))1043return -1;1044
1045strvec_pushf(env, "GIT_AUTHOR_NAME=%s", name);1046strvec_pushf(env, "GIT_AUTHOR_EMAIL=%s", email);1047strvec_pushf(env, "GIT_AUTHOR_DATE=%s", date);1048free(name);1049free(email);1050free(date);1051
1052return 0;1053}
1054
1055static char *get_author(const char *message)1056{
1057size_t len;1058const char *a;1059
1060a = find_commit_header(message, "author", &len);1061if (a)1062return xmemdupz(a, len);1063
1064return NULL;1065}
1066
1067static const char *author_date_from_env(const struct strvec *env)1068{
1069int i;1070const char *date;1071
1072for (i = 0; i < env->nr; i++)1073if (skip_prefix(env->v[i],1074"GIT_AUTHOR_DATE=", &date))1075return date;1076/*1077* If GIT_AUTHOR_DATE is missing we should have already errored out when
1078* reading the script
1079*/
1080BUG("GIT_AUTHOR_DATE missing from author script");1081}
1082
1083static const char staged_changes_advice[] =1084N_("you have staged changes in your working tree\n"1085"If these changes are meant to be squashed into the previous commit, run:\n"
1086"\n"
1087" git commit --amend %s\n"
1088"\n"
1089"If they are meant to go into a new commit, run:\n"
1090"\n"
1091" git commit %s\n"
1092"\n"
1093"In both cases, once you're done, continue with:\n"
1094"\n"
1095" git rebase --continue\n");1096
1097#define ALLOW_EMPTY (1<<0)1098#define EDIT_MSG (1<<1)1099#define AMEND_MSG (1<<2)1100#define CLEANUP_MSG (1<<3)1101#define VERIFY_MSG (1<<4)1102#define CREATE_ROOT_COMMIT (1<<5)1103#define VERBATIM_MSG (1<<6)1104
1105static int run_command_silent_on_success(struct child_process *cmd)1106{
1107struct strbuf buf = STRBUF_INIT;1108int rc;1109
1110cmd->stdout_to_stderr = 1;1111rc = pipe_command(cmd,1112NULL, 0,1113NULL, 0,1114&buf, 0);1115
1116if (rc)1117fputs(buf.buf, stderr);1118strbuf_release(&buf);1119return rc;1120}
1121
1122/*
1123* If we are cherry-pick, and if the merge did not result in
1124* hand-editing, we will hit this commit and inherit the original
1125* author date and name.
1126*
1127* If we are revert, or if our cherry-pick results in a hand merge,
1128* we had better say that the current user is responsible for that.
1129*
1130* An exception is when run_git_commit() is called during an
1131* interactive rebase: in that case, we will want to retain the
1132* author metadata.
1133*/
1134static int run_git_commit(const char *defmsg,1135struct replay_opts *opts,1136unsigned int flags)1137{
1138struct replay_ctx *ctx = opts->ctx;1139struct child_process cmd = CHILD_PROCESS_INIT;1140
1141if ((flags & CLEANUP_MSG) && (flags & VERBATIM_MSG))1142BUG("CLEANUP_MSG and VERBATIM_MSG are mutually exclusive");1143
1144cmd.git_cmd = 1;1145
1146if (is_rebase_i(opts) &&1147((opts->committer_date_is_author_date && !opts->ignore_date) ||1148!(!defmsg && (flags & AMEND_MSG))) &&1149read_env_script(&cmd.env)) {1150const char *gpg_opt = gpg_sign_opt_quoted(opts);1151
1152return error(_(staged_changes_advice),1153gpg_opt, gpg_opt);1154}1155
1156strvec_pushf(&cmd.env, GIT_REFLOG_ACTION "=%s", ctx->reflog_message);1157
1158if (opts->committer_date_is_author_date)1159strvec_pushf(&cmd.env, "GIT_COMMITTER_DATE=%s",1160opts->ignore_date ?1161"" :1162author_date_from_env(&cmd.env));1163if (opts->ignore_date)1164strvec_push(&cmd.env, "GIT_AUTHOR_DATE=");1165
1166strvec_push(&cmd.args, "commit");1167
1168if (!(flags & VERIFY_MSG))1169strvec_push(&cmd.args, "-n");1170if ((flags & AMEND_MSG))1171strvec_push(&cmd.args, "--amend");1172if (opts->gpg_sign)1173strvec_pushf(&cmd.args, "-S%s", opts->gpg_sign);1174else1175strvec_push(&cmd.args, "--no-gpg-sign");1176if (defmsg)1177strvec_pushl(&cmd.args, "-F", defmsg, NULL);1178else if (!(flags & EDIT_MSG))1179strvec_pushl(&cmd.args, "-C", "HEAD", NULL);1180if ((flags & CLEANUP_MSG))1181strvec_push(&cmd.args, "--cleanup=strip");1182if ((flags & VERBATIM_MSG))1183strvec_push(&cmd.args, "--cleanup=verbatim");1184if ((flags & EDIT_MSG))1185strvec_push(&cmd.args, "-e");1186else if (!(flags & CLEANUP_MSG) &&1187!opts->signoff && !opts->record_origin &&1188!opts->explicit_cleanup)1189strvec_push(&cmd.args, "--cleanup=verbatim");1190
1191if ((flags & ALLOW_EMPTY))1192strvec_push(&cmd.args, "--allow-empty");1193
1194if (!(flags & EDIT_MSG))1195strvec_push(&cmd.args, "--allow-empty-message");1196
1197if (is_rebase_i(opts) && !(flags & EDIT_MSG))1198return run_command_silent_on_success(&cmd);1199else1200return run_command(&cmd);1201}
1202
1203static int rest_is_empty(const struct strbuf *sb, int start)1204{
1205int i, eol;1206const char *nl;1207
1208/* Check if the rest is just whitespace and Signed-off-by's. */1209for (i = start; i < sb->len; i++) {1210nl = memchr(sb->buf + i, '\n', sb->len - i);1211if (nl)1212eol = nl - sb->buf;1213else1214eol = sb->len;1215
1216if (strlen(sign_off_header) <= eol - i &&1217starts_with(sb->buf + i, sign_off_header)) {1218i = eol;1219continue;1220}1221while (i < eol)1222if (!isspace(sb->buf[i++]))1223return 0;1224}1225
1226return 1;1227}
1228
1229void cleanup_message(struct strbuf *msgbuf,1230enum commit_msg_cleanup_mode cleanup_mode, int verbose)1231{
1232if (verbose || /* Truncate the message just before the diff, if any. */1233cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)1234strbuf_setlen(msgbuf, wt_status_locate_end(msgbuf->buf, msgbuf->len));1235if (cleanup_mode != COMMIT_MSG_CLEANUP_NONE)1236strbuf_stripspace(msgbuf,1237cleanup_mode == COMMIT_MSG_CLEANUP_ALL ? comment_line_str : NULL);1238}
1239
1240/*
1241* Find out if the message in the strbuf contains only whitespace and
1242* Signed-off-by lines.
1243*/
1244int message_is_empty(const struct strbuf *sb,1245enum commit_msg_cleanup_mode cleanup_mode)1246{
1247if (cleanup_mode == COMMIT_MSG_CLEANUP_NONE && sb->len)1248return 0;1249return rest_is_empty(sb, 0);1250}
1251
1252/*
1253* See if the user edited the message in the editor or left what
1254* was in the template intact
1255*/
1256int template_untouched(const struct strbuf *sb, const char *template_file,1257enum commit_msg_cleanup_mode cleanup_mode)1258{
1259struct strbuf tmpl = STRBUF_INIT;1260const char *start;1261
1262if (cleanup_mode == COMMIT_MSG_CLEANUP_NONE && sb->len)1263return 0;1264
1265if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0)1266return 0;1267
1268strbuf_stripspace(&tmpl,1269cleanup_mode == COMMIT_MSG_CLEANUP_ALL ? comment_line_str : NULL);1270if (!skip_prefix(sb->buf, tmpl.buf, &start))1271start = sb->buf;1272strbuf_release(&tmpl);1273return rest_is_empty(sb, start - sb->buf);1274}
1275
1276int update_head_with_reflog(const struct commit *old_head,1277const struct object_id *new_head,1278const char *action, const struct strbuf *msg,1279struct strbuf *err)1280{
1281struct ref_transaction *transaction;1282struct strbuf sb = STRBUF_INIT;1283const char *nl;1284int ret = 0;1285
1286if (action) {1287strbuf_addstr(&sb, action);1288strbuf_addstr(&sb, ": ");1289}1290
1291nl = strchr(msg->buf, '\n');1292if (nl) {1293strbuf_add(&sb, msg->buf, nl + 1 - msg->buf);1294} else {1295strbuf_addbuf(&sb, msg);1296strbuf_addch(&sb, '\n');1297}1298
1299transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),1300err);1301if (!transaction ||1302ref_transaction_update(transaction, "HEAD", new_head,1303old_head ? &old_head->object.oid : null_oid(),1304NULL, NULL, 0, sb.buf, err) ||1305ref_transaction_commit(transaction, err)) {1306ret = -1;1307}1308ref_transaction_free(transaction);1309strbuf_release(&sb);1310
1311return ret;1312}
1313
1314static int run_rewrite_hook(const struct object_id *oldoid,1315const struct object_id *newoid)1316{
1317struct child_process proc = CHILD_PROCESS_INIT;1318int code;1319struct strbuf sb = STRBUF_INIT;1320const char *hook_path = find_hook(the_repository, "post-rewrite");1321
1322if (!hook_path)1323return 0;1324
1325strvec_pushl(&proc.args, hook_path, "amend", NULL);1326proc.in = -1;1327proc.stdout_to_stderr = 1;1328proc.trace2_hook_name = "post-rewrite";1329
1330code = start_command(&proc);1331if (code)1332return code;1333strbuf_addf(&sb, "%s %s\n", oid_to_hex(oldoid), oid_to_hex(newoid));1334sigchain_push(SIGPIPE, SIG_IGN);1335write_in_full(proc.in, sb.buf, sb.len);1336close(proc.in);1337strbuf_release(&sb);1338sigchain_pop(SIGPIPE);1339return finish_command(&proc);1340}
1341
1342void commit_post_rewrite(struct repository *r,1343const struct commit *old_head,1344const struct object_id *new_head)1345{
1346struct notes_rewrite_cfg *cfg;1347
1348cfg = init_copy_notes_for_rewrite("amend");1349if (cfg) {1350/* we are amending, so old_head is not NULL */1351copy_note_for_rewrite(cfg, &old_head->object.oid, new_head);1352finish_copy_notes_for_rewrite(r, cfg, "Notes added by 'git commit --amend'");1353}1354run_rewrite_hook(&old_head->object.oid, new_head);1355}
1356
1357static int run_prepare_commit_msg_hook(struct repository *r,1358struct strbuf *msg,1359const char *commit)1360{
1361int ret = 0;1362const char *name, *arg1 = NULL, *arg2 = NULL;1363
1364name = git_path_commit_editmsg();1365if (write_message(msg->buf, msg->len, name, 0))1366return -1;1367
1368if (commit) {1369arg1 = "commit";1370arg2 = commit;1371} else {1372arg1 = "message";1373}1374if (run_commit_hook(0, r->index_file, NULL, "prepare-commit-msg", name,1375arg1, arg2, NULL))1376ret = error(_("'prepare-commit-msg' hook failed"));1377
1378return ret;1379}
1380
1381static const char implicit_ident_advice_noconfig[] =1382N_("Your name and email address were configured automatically based\n"1383"on your username and hostname. Please check that they are accurate.\n"
1384"You can suppress this message by setting them explicitly. Run the\n"
1385"following command and follow the instructions in your editor to edit\n"
1386"your configuration file:\n"
1387"\n"
1388" git config --global --edit\n"
1389"\n"
1390"After doing this, you may fix the identity used for this commit with:\n"
1391"\n"
1392" git commit --amend --reset-author\n");1393
1394static const char implicit_ident_advice_config[] =1395N_("Your name and email address were configured automatically based\n"1396"on your username and hostname. Please check that they are accurate.\n"
1397"You can suppress this message by setting them explicitly:\n"
1398"\n"
1399" git config --global user.name \"Your Name\"\n"
1400" git config --global user.email you@example.com\n"
1401"\n"
1402"After doing this, you may fix the identity used for this commit with:\n"
1403"\n"
1404" git commit --amend --reset-author\n");1405
1406static const char *implicit_ident_advice(void)1407{
1408char *user_config = interpolate_path("~/.gitconfig", 0);1409char *xdg_config = xdg_config_home("config");1410int config_exists = file_exists(user_config) || file_exists(xdg_config);1411
1412free(user_config);1413free(xdg_config);1414
1415if (config_exists)1416return _(implicit_ident_advice_config);1417else1418return _(implicit_ident_advice_noconfig);1419
1420}
1421
1422void print_commit_summary(struct repository *r,1423const char *prefix,1424const struct object_id *oid,1425unsigned int flags)1426{
1427struct rev_info rev;1428struct commit *commit;1429struct strbuf format = STRBUF_INIT;1430const char *head;1431struct pretty_print_context pctx = {0};1432struct strbuf author_ident = STRBUF_INIT;1433struct strbuf committer_ident = STRBUF_INIT;1434struct ref_store *refs;1435
1436commit = lookup_commit(r, oid);1437if (!commit)1438die(_("couldn't look up newly created commit"));1439if (repo_parse_commit(r, commit))1440die(_("could not parse newly created commit"));1441
1442strbuf_addstr(&format, "format:%h] %s");1443
1444repo_format_commit_message(r, commit, "%an <%ae>", &author_ident,1445&pctx);1446repo_format_commit_message(r, commit, "%cn <%ce>", &committer_ident,1447&pctx);1448if (strbuf_cmp(&author_ident, &committer_ident)) {1449strbuf_addstr(&format, "\n Author: ");1450strbuf_addbuf_percentquote(&format, &author_ident);1451}1452if (flags & SUMMARY_SHOW_AUTHOR_DATE) {1453struct strbuf date = STRBUF_INIT;1454
1455repo_format_commit_message(r, commit, "%ad", &date, &pctx);1456strbuf_addstr(&format, "\n Date: ");1457strbuf_addbuf_percentquote(&format, &date);1458strbuf_release(&date);1459}1460if (!committer_ident_sufficiently_given()) {1461strbuf_addstr(&format, "\n Committer: ");1462strbuf_addbuf_percentquote(&format, &committer_ident);1463if (advice_enabled(ADVICE_IMPLICIT_IDENTITY)) {1464strbuf_addch(&format, '\n');1465strbuf_addstr(&format, implicit_ident_advice());1466}1467}1468strbuf_release(&author_ident);1469strbuf_release(&committer_ident);1470
1471repo_init_revisions(r, &rev, prefix);1472setup_revisions(0, NULL, &rev, NULL);1473
1474rev.diff = 1;1475rev.diffopt.output_format =1476DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY;1477
1478rev.verbose_header = 1;1479rev.show_root_diff = 1;1480get_commit_format(format.buf, &rev);1481rev.always_show_header = 0;1482rev.diffopt.detect_rename = DIFF_DETECT_RENAME;1483diff_setup_done(&rev.diffopt);1484
1485refs = get_main_ref_store(r);1486head = refs_resolve_ref_unsafe(refs, "HEAD", 0, NULL, NULL);1487if (!head)1488die(_("unable to resolve HEAD after creating commit"));1489if (!strcmp(head, "HEAD"))1490head = _("detached HEAD");1491else1492skip_prefix(head, "refs/heads/", &head);1493printf("[%s%s ", head, (flags & SUMMARY_INITIAL_COMMIT) ?1494_(" (root-commit)") : "");1495
1496if (!log_tree_commit(&rev, commit)) {1497rev.always_show_header = 1;1498rev.use_terminator = 1;1499log_tree_commit(&rev, commit);1500}1501
1502release_revisions(&rev);1503strbuf_release(&format);1504}
1505
1506static int parse_head(struct repository *r, struct commit **head)1507{
1508struct commit *current_head;1509struct object_id oid;1510
1511if (repo_get_oid(r, "HEAD", &oid)) {1512current_head = NULL;1513} else {1514current_head = lookup_commit_reference(r, &oid);1515if (!current_head)1516return error(_("could not parse HEAD"));1517if (!oideq(&oid, ¤t_head->object.oid)) {1518warning(_("HEAD %s is not a commit!"),1519oid_to_hex(&oid));1520}1521if (repo_parse_commit(r, current_head))1522return error(_("could not parse HEAD commit"));1523}1524*head = current_head;1525
1526return 0;1527}
1528
1529/*
1530* Try to commit without forking 'git commit'. In some cases we need
1531* to run 'git commit' to display an error message
1532*
1533* Returns:
1534* -1 - error unable to commit
1535* 0 - success
1536* 1 - run 'git commit'
1537*/
1538static int try_to_commit(struct repository *r,1539struct strbuf *msg, const char *author,1540struct replay_opts *opts, unsigned int flags,1541struct object_id *oid)1542{
1543struct replay_ctx *ctx = opts->ctx;1544struct object_id tree;1545struct commit *current_head = NULL;1546struct commit_list *parents = NULL;1547struct commit_extra_header *extra = NULL;1548struct strbuf err = STRBUF_INIT;1549struct strbuf commit_msg = STRBUF_INIT;1550char *amend_author = NULL;1551const char *committer = NULL;1552const char *hook_commit = NULL;1553enum commit_msg_cleanup_mode cleanup;1554int res = 0;1555
1556if ((flags & CLEANUP_MSG) && (flags & VERBATIM_MSG))1557BUG("CLEANUP_MSG and VERBATIM_MSG are mutually exclusive");1558
1559if (parse_head(r, ¤t_head))1560return -1;1561
1562if (flags & AMEND_MSG) {1563const char *exclude_gpgsig[] = { "gpgsig", "gpgsig-sha256", NULL };1564const char *out_enc = get_commit_output_encoding();1565const char *message = repo_logmsg_reencode(r, current_head,1566NULL, out_enc);1567
1568if (!msg) {1569const char *orig_message = NULL;1570
1571find_commit_subject(message, &orig_message);1572msg = &commit_msg;1573strbuf_addstr(msg, orig_message);1574hook_commit = "HEAD";1575}1576author = amend_author = get_author(message);1577repo_unuse_commit_buffer(r, current_head,1578message);1579if (!author) {1580res = error(_("unable to parse commit author"));1581goto out;1582}1583parents = copy_commit_list(current_head->parents);1584extra = read_commit_extra_headers(current_head, exclude_gpgsig);1585} else if (current_head &&1586(!(flags & CREATE_ROOT_COMMIT) || (flags & AMEND_MSG))) {1587commit_list_insert(current_head, &parents);1588}1589
1590if (write_index_as_tree(&tree, r->index, r->index_file, 0, NULL)) {1591res = error(_("git write-tree failed to write a tree"));1592goto out;1593}1594
1595if (!(flags & ALLOW_EMPTY)) {1596struct commit *first_parent = current_head;1597
1598if (flags & AMEND_MSG) {1599if (current_head->parents) {1600first_parent = current_head->parents->item;1601if (repo_parse_commit(r, first_parent)) {1602res = error(_("could not parse HEAD commit"));1603goto out;1604}1605} else {1606first_parent = NULL;1607}1608}1609if (oideq(first_parent1610? get_commit_tree_oid(first_parent)1611: the_hash_algo->empty_tree,1612&tree)) {1613res = 1; /* run 'git commit' to display error message */1614goto out;1615}1616}1617
1618if (hook_exists(r, "prepare-commit-msg")) {1619res = run_prepare_commit_msg_hook(r, msg, hook_commit);1620if (res)1621goto out;1622if (strbuf_read_file(&commit_msg, git_path_commit_editmsg(),16232048) < 0) {1624res = error_errno(_("unable to read commit message "1625"from '%s'"),1626git_path_commit_editmsg());1627goto out;1628}1629msg = &commit_msg;1630}1631
1632if (flags & CLEANUP_MSG)1633cleanup = COMMIT_MSG_CLEANUP_ALL;1634else if (flags & VERBATIM_MSG)1635cleanup = COMMIT_MSG_CLEANUP_NONE;1636else if ((opts->signoff || opts->record_origin) &&1637!opts->explicit_cleanup)1638cleanup = COMMIT_MSG_CLEANUP_SPACE;1639else1640cleanup = opts->default_msg_cleanup;1641
1642if (cleanup != COMMIT_MSG_CLEANUP_NONE)1643strbuf_stripspace(msg,1644cleanup == COMMIT_MSG_CLEANUP_ALL ? comment_line_str : NULL);1645if ((flags & EDIT_MSG) && message_is_empty(msg, cleanup)) {1646res = 1; /* run 'git commit' to display error message */1647goto out;1648}1649
1650if (opts->committer_date_is_author_date) {1651struct ident_split id;1652struct strbuf date = STRBUF_INIT;1653
1654if (!opts->ignore_date) {1655if (split_ident_line(&id, author, (int)strlen(author)) < 0) {1656res = error(_("invalid author identity '%s'"),1657author);1658goto out;1659}1660if (!id.date_begin) {1661res = error(_(1662"corrupt author: missing date information"));1663goto out;1664}1665strbuf_addf(&date, "@%.*s %.*s",1666(int)(id.date_end - id.date_begin),1667id.date_begin,1668(int)(id.tz_end - id.tz_begin),1669id.tz_begin);1670} else {1671reset_ident_date();1672}1673committer = fmt_ident(getenv("GIT_COMMITTER_NAME"),1674getenv("GIT_COMMITTER_EMAIL"),1675WANT_COMMITTER_IDENT,1676opts->ignore_date ? NULL : date.buf,1677IDENT_STRICT);1678strbuf_release(&date);1679} else {1680reset_ident_date();1681}1682
1683if (opts->ignore_date) {1684struct ident_split id;1685char *name, *email;1686
1687if (split_ident_line(&id, author, strlen(author)) < 0) {1688error(_("invalid author identity '%s'"), author);1689goto out;1690}1691name = xmemdupz(id.name_begin, id.name_end - id.name_begin);1692email = xmemdupz(id.mail_begin, id.mail_end - id.mail_begin);1693author = fmt_ident(name, email, WANT_AUTHOR_IDENT, NULL,1694IDENT_STRICT);1695free(name);1696free(email);1697}1698
1699if (commit_tree_extended(msg->buf, msg->len, &tree, parents, oid,1700author, committer, opts->gpg_sign, extra)) {1701res = error(_("failed to write commit object"));1702goto out;1703}1704
1705if (update_head_with_reflog(current_head, oid, ctx->reflog_message,1706msg, &err)) {1707res = error("%s", err.buf);1708goto out;1709}1710
1711run_commit_hook(0, r->index_file, NULL, "post-commit", NULL);1712if (flags & AMEND_MSG)1713commit_post_rewrite(r, current_head, oid);1714
1715out:1716free_commit_extra_headers(extra);1717free_commit_list(parents);1718strbuf_release(&err);1719strbuf_release(&commit_msg);1720free(amend_author);1721
1722return res;1723}
1724
1725static int write_rebase_head(struct object_id *oid)1726{
1727if (refs_update_ref(get_main_ref_store(the_repository), "rebase", "REBASE_HEAD", oid,1728NULL, REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))1729return error(_("could not update %s"), "REBASE_HEAD");1730
1731return 0;1732}
1733
1734static int do_commit(struct repository *r,1735const char *msg_file, const char *author,1736struct replay_opts *opts, unsigned int flags,1737struct object_id *oid)1738{
1739int res = 1;1740
1741if (!(flags & EDIT_MSG) && !(flags & VERIFY_MSG)) {1742struct object_id oid;1743struct strbuf sb = STRBUF_INIT;1744
1745if (msg_file && strbuf_read_file(&sb, msg_file, 2048) < 0)1746return error_errno(_("unable to read commit message "1747"from '%s'"),1748msg_file);1749
1750res = try_to_commit(r, msg_file ? &sb : NULL,1751author, opts, flags, &oid);1752strbuf_release(&sb);1753if (!res) {1754refs_delete_ref(get_main_ref_store(r), "",1755"CHERRY_PICK_HEAD", NULL, REF_NO_DEREF);1756unlink(git_path_merge_msg(r));1757if (!is_rebase_i(opts))1758print_commit_summary(r, NULL, &oid,1759SUMMARY_SHOW_AUTHOR_DATE);1760return res;1761}1762}1763if (res == 1) {1764if (is_rebase_i(opts) && oid)1765if (write_rebase_head(oid))1766return -1;1767return run_git_commit(msg_file, opts, flags);1768}1769
1770return res;1771}
1772
1773static int is_original_commit_empty(struct commit *commit)1774{
1775const struct object_id *ptree_oid;1776
1777if (repo_parse_commit(the_repository, commit))1778return error(_("could not parse commit %s"),1779oid_to_hex(&commit->object.oid));1780if (commit->parents) {1781struct commit *parent = commit->parents->item;1782if (repo_parse_commit(the_repository, parent))1783return error(_("could not parse parent commit %s"),1784oid_to_hex(&parent->object.oid));1785ptree_oid = get_commit_tree_oid(parent);1786} else {1787ptree_oid = the_hash_algo->empty_tree; /* commit is root */1788}1789
1790return oideq(ptree_oid, get_commit_tree_oid(commit));1791}
1792
1793/*
1794* Should empty commits be allowed? Return status:
1795* <0: Error in is_index_unchanged(r) or is_original_commit_empty(commit)
1796* 0: Halt on empty commit
1797* 1: Allow empty commit
1798* 2: Drop empty commit
1799*/
1800static int allow_empty(struct repository *r,1801struct replay_opts *opts,1802struct commit *commit)1803{
1804int index_unchanged, originally_empty;1805
1806/*1807* For a commit that is initially empty, allow_empty determines if it
1808* should be kept or not
1809*
1810* For a commit that becomes empty, keep_redundant_commits and
1811* drop_redundant_commits determine whether the commit should be kept or
1812* dropped. If neither is specified, halt.
1813*/
1814index_unchanged = is_index_unchanged(r);1815if (index_unchanged < 0)1816return index_unchanged;1817if (!index_unchanged)1818return 0; /* we do not have to say --allow-empty */1819
1820originally_empty = is_original_commit_empty(commit);1821if (originally_empty < 0)1822return originally_empty;1823if (originally_empty)1824return opts->allow_empty;1825else if (opts->keep_redundant_commits)1826return 1;1827else if (opts->drop_redundant_commits)1828return 2;1829else1830return 0;1831}
1832
1833static struct {1834char c;1835const char *str;1836} todo_command_info[] = {1837[TODO_PICK] = { 'p', "pick" },1838[TODO_REVERT] = { 0, "revert" },1839[TODO_EDIT] = { 'e', "edit" },1840[TODO_REWORD] = { 'r', "reword" },1841[TODO_FIXUP] = { 'f', "fixup" },1842[TODO_SQUASH] = { 's', "squash" },1843[TODO_EXEC] = { 'x', "exec" },1844[TODO_BREAK] = { 'b', "break" },1845[TODO_LABEL] = { 'l', "label" },1846[TODO_RESET] = { 't', "reset" },1847[TODO_MERGE] = { 'm', "merge" },1848[TODO_UPDATE_REF] = { 'u', "update-ref" },1849[TODO_NOOP] = { 0, "noop" },1850[TODO_DROP] = { 'd', "drop" },1851[TODO_COMMENT] = { 0, NULL },1852};1853
1854static const char *command_to_string(const enum todo_command command)1855{
1856if (command < TODO_COMMENT)1857return todo_command_info[command].str;1858if (command == TODO_COMMENT)1859return comment_line_str;1860die(_("unknown command: %d"), command);1861}
1862
1863static char command_to_char(const enum todo_command command)1864{
1865if (command < TODO_COMMENT)1866return todo_command_info[command].c;1867return 0;1868}
1869
1870static int is_noop(const enum todo_command command)1871{
1872return TODO_NOOP <= command;1873}
1874
1875static int is_fixup(enum todo_command command)1876{
1877return command == TODO_FIXUP || command == TODO_SQUASH;1878}
1879
1880/* Does this command create a (non-merge) commit? */
1881static int is_pick_or_similar(enum todo_command command)1882{
1883switch (command) {1884case TODO_PICK:1885case TODO_REVERT:1886case TODO_EDIT:1887case TODO_REWORD:1888case TODO_FIXUP:1889case TODO_SQUASH:1890return 1;1891default:1892return 0;1893}1894}
1895
1896enum todo_item_flags {1897TODO_EDIT_MERGE_MSG = (1 << 0),1898TODO_REPLACE_FIXUP_MSG = (1 << 1),1899TODO_EDIT_FIXUP_MSG = (1 << 2),1900};1901
1902static const char first_commit_msg_str[] = N_("This is the 1st commit message:");1903static const char nth_commit_msg_fmt[] = N_("This is the commit message #%d:");1904static const char skip_first_commit_msg_str[] = N_("The 1st commit message will be skipped:");1905static const char skip_nth_commit_msg_fmt[] = N_("The commit message #%d will be skipped:");1906static const char combined_commit_msg_fmt[] = N_("This is a combination of %d commits.");1907
1908static int is_fixup_flag(enum todo_command command, unsigned flag)1909{
1910return command == TODO_FIXUP && ((flag & TODO_REPLACE_FIXUP_MSG) ||1911(flag & TODO_EDIT_FIXUP_MSG));1912}
1913
1914/*
1915* Wrapper around strbuf_add_commented_lines() which avoids double
1916* commenting commit subjects.
1917*/
1918static void add_commented_lines(struct strbuf *buf, const void *str, size_t len)1919{
1920const char *s = str;1921while (starts_with_mem(s, len, comment_line_str)) {1922size_t count;1923const char *n = memchr(s, '\n', len);1924if (!n)1925count = len;1926else1927count = n - s + 1;1928strbuf_add(buf, s, count);1929s += count;1930len -= count;1931}1932strbuf_add_commented_lines(buf, s, len, comment_line_str);1933}
1934
1935/* Does the current fixup chain contain a squash command? */
1936static int seen_squash(struct replay_ctx *ctx)1937{
1938return starts_with(ctx->current_fixups.buf, "squash") ||1939strstr(ctx->current_fixups.buf, "\nsquash");1940}
1941
1942static void update_comment_bufs(struct strbuf *buf1, struct strbuf *buf2, int n)1943{
1944strbuf_setlen(buf1, 2);1945strbuf_addf(buf1, _(nth_commit_msg_fmt), n);1946strbuf_addch(buf1, '\n');1947strbuf_setlen(buf2, 2);1948strbuf_addf(buf2, _(skip_nth_commit_msg_fmt), n);1949strbuf_addch(buf2, '\n');1950}
1951
1952/*
1953* Comment out any un-commented commit messages, updating the message comments
1954* to say they will be skipped but do not comment out the empty lines that
1955* surround commit messages and their comments.
1956*/
1957static void update_squash_message_for_fixup(struct strbuf *msg)1958{
1959void (*copy_lines)(struct strbuf *, const void *, size_t) = strbuf_add;1960struct strbuf buf1 = STRBUF_INIT, buf2 = STRBUF_INIT;1961const char *s, *start;1962char *orig_msg;1963size_t orig_msg_len;1964int i = 1;1965
1966strbuf_addf(&buf1, "# %s\n", _(first_commit_msg_str));1967strbuf_addf(&buf2, "# %s\n", _(skip_first_commit_msg_str));1968s = start = orig_msg = strbuf_detach(msg, &orig_msg_len);1969while (s) {1970const char *next;1971size_t off;1972if (skip_prefix(s, buf1.buf, &next)) {1973/*1974* Copy the last message, preserving the blank line
1975* preceding the current line
1976*/
1977off = (s > start + 1 && s[-2] == '\n') ? 1 : 0;1978copy_lines(msg, start, s - start - off);1979if (off)1980strbuf_addch(msg, '\n');1981/*1982* The next message needs to be commented out but the
1983* message header is already commented out so just copy
1984* it and the blank line that follows it.
1985*/
1986strbuf_addbuf(msg, &buf2);1987if (*next == '\n')1988strbuf_addch(msg, *next++);1989start = s = next;1990copy_lines = add_commented_lines;1991update_comment_bufs(&buf1, &buf2, ++i);1992} else if (skip_prefix(s, buf2.buf, &next)) {1993off = (s > start + 1 && s[-2] == '\n') ? 1 : 0;1994copy_lines(msg, start, s - start - off);1995start = s - off;1996s = next;1997copy_lines = strbuf_add;1998update_comment_bufs(&buf1, &buf2, ++i);1999} else {2000s = strchr(s, '\n');2001if (s)2002s++;2003}2004}2005copy_lines(msg, start, orig_msg_len - (start - orig_msg));2006free(orig_msg);2007strbuf_release(&buf1);2008strbuf_release(&buf2);2009}
2010
2011static int append_squash_message(struct strbuf *buf, const char *body,2012enum todo_command command, struct replay_opts *opts,2013unsigned flag)2014{
2015struct replay_ctx *ctx = opts->ctx;2016const char *fixup_msg;2017size_t commented_len = 0, fixup_off;2018/*2019* amend is non-interactive and not normally used with fixup!
2020* or squash! commits, so only comment out those subjects when
2021* squashing commit messages.
2022*/
2023if (starts_with(body, "amend!") ||2024((command == TODO_SQUASH || seen_squash(ctx)) &&2025(starts_with(body, "squash!") || starts_with(body, "fixup!"))))2026commented_len = commit_subject_length(body);2027
2028strbuf_addf(buf, "\n%s ", comment_line_str);2029strbuf_addf(buf, _(nth_commit_msg_fmt),2030++ctx->current_fixup_count + 1);2031strbuf_addstr(buf, "\n\n");2032strbuf_add_commented_lines(buf, body, commented_len, comment_line_str);2033/* buf->buf may be reallocated so store an offset into the buffer */2034fixup_off = buf->len;2035strbuf_addstr(buf, body + commented_len);2036
2037/* fixup -C after squash behaves like squash */2038if (is_fixup_flag(command, flag) && !seen_squash(ctx)) {2039/*2040* We're replacing the commit message so we need to
2041* append the Signed-off-by: trailer if the user
2042* requested '--signoff'.
2043*/
2044if (opts->signoff)2045append_signoff(buf, 0, 0);2046
2047if ((command == TODO_FIXUP) &&2048(flag & TODO_REPLACE_FIXUP_MSG) &&2049(file_exists(rebase_path_fixup_msg()) ||2050!file_exists(rebase_path_squash_msg()))) {2051fixup_msg = skip_blank_lines(buf->buf + fixup_off);2052if (write_message(fixup_msg, strlen(fixup_msg),2053rebase_path_fixup_msg(), 0) < 0)2054return error(_("cannot write '%s'"),2055rebase_path_fixup_msg());2056} else {2057unlink(rebase_path_fixup_msg());2058}2059} else {2060unlink(rebase_path_fixup_msg());2061}2062
2063return 0;2064}
2065
2066static int update_squash_messages(struct repository *r,2067enum todo_command command,2068struct commit *commit,2069struct replay_opts *opts,2070unsigned flag)2071{
2072struct replay_ctx *ctx = opts->ctx;2073struct strbuf buf = STRBUF_INIT;2074int res = 0;2075const char *message, *body;2076const char *encoding = get_commit_output_encoding();2077
2078if (ctx->current_fixup_count > 0) {2079struct strbuf header = STRBUF_INIT;2080char *eol;2081
2082if (strbuf_read_file(&buf, rebase_path_squash_msg(), 9) <= 0)2083return error(_("could not read '%s'"),2084rebase_path_squash_msg());2085
2086eol = !starts_with(buf.buf, comment_line_str) ?2087buf.buf : strchrnul(buf.buf, '\n');2088
2089strbuf_addf(&header, "%s ", comment_line_str);2090strbuf_addf(&header, _(combined_commit_msg_fmt),2091ctx->current_fixup_count + 2);2092strbuf_splice(&buf, 0, eol - buf.buf, header.buf, header.len);2093strbuf_release(&header);2094if (is_fixup_flag(command, flag) && !seen_squash(ctx))2095update_squash_message_for_fixup(&buf);2096} else {2097struct object_id head;2098struct commit *head_commit;2099const char *head_message, *body;2100
2101if (repo_get_oid(r, "HEAD", &head))2102return error(_("need a HEAD to fixup"));2103if (!(head_commit = lookup_commit_reference(r, &head)))2104return error(_("could not read HEAD"));2105if (!(head_message = repo_logmsg_reencode(r, head_commit, NULL,2106encoding)))2107return error(_("could not read HEAD's commit message"));2108
2109find_commit_subject(head_message, &body);2110if (command == TODO_FIXUP && !flag && write_message(body, strlen(body),2111rebase_path_fixup_msg(), 0) < 0) {2112repo_unuse_commit_buffer(r, head_commit, head_message);2113return error(_("cannot write '%s'"), rebase_path_fixup_msg());2114}2115strbuf_addf(&buf, "%s ", comment_line_str);2116strbuf_addf(&buf, _(combined_commit_msg_fmt), 2);2117strbuf_addf(&buf, "\n%s ", comment_line_str);2118strbuf_addstr(&buf, is_fixup_flag(command, flag) ?2119_(skip_first_commit_msg_str) :2120_(first_commit_msg_str));2121strbuf_addstr(&buf, "\n\n");2122if (is_fixup_flag(command, flag))2123strbuf_add_commented_lines(&buf, body, strlen(body),2124comment_line_str);2125else2126strbuf_addstr(&buf, body);2127
2128repo_unuse_commit_buffer(r, head_commit, head_message);2129}2130
2131if (!(message = repo_logmsg_reencode(r, commit, NULL, encoding)))2132return error(_("could not read commit message of %s"),2133oid_to_hex(&commit->object.oid));2134find_commit_subject(message, &body);2135
2136if (command == TODO_SQUASH || is_fixup_flag(command, flag)) {2137res = append_squash_message(&buf, body, command, opts, flag);2138} else if (command == TODO_FIXUP) {2139strbuf_addf(&buf, "\n%s ", comment_line_str);2140strbuf_addf(&buf, _(skip_nth_commit_msg_fmt),2141++ctx->current_fixup_count + 1);2142strbuf_addstr(&buf, "\n\n");2143strbuf_add_commented_lines(&buf, body, strlen(body),2144comment_line_str);2145} else2146return error(_("unknown command: %d"), command);2147repo_unuse_commit_buffer(r, commit, message);2148
2149if (!res)2150res = write_message(buf.buf, buf.len, rebase_path_squash_msg(),21510);2152strbuf_release(&buf);2153
2154if (!res) {2155strbuf_addf(&ctx->current_fixups, "%s%s %s",2156ctx->current_fixups.len ? "\n" : "",2157command_to_string(command),2158oid_to_hex(&commit->object.oid));2159res = write_message(ctx->current_fixups.buf,2160ctx->current_fixups.len,2161rebase_path_current_fixups(), 0);2162}2163
2164return res;2165}
2166
2167static void flush_rewritten_pending(void)2168{
2169struct strbuf buf = STRBUF_INIT;2170struct object_id newoid;2171FILE *out;2172
2173if (strbuf_read_file(&buf, rebase_path_rewritten_pending(), (GIT_MAX_HEXSZ + 1) * 2) > 0 &&2174!repo_get_oid(the_repository, "HEAD", &newoid) &&2175(out = fopen_or_warn(rebase_path_rewritten_list(), "a"))) {2176char *bol = buf.buf, *eol;2177
2178while (*bol) {2179eol = strchrnul(bol, '\n');2180fprintf(out, "%.*s %s\n", (int)(eol - bol),2181bol, oid_to_hex(&newoid));2182if (!*eol)2183break;2184bol = eol + 1;2185}2186fclose(out);2187unlink(rebase_path_rewritten_pending());2188}2189strbuf_release(&buf);2190}
2191
2192static void record_in_rewritten(struct object_id *oid,2193enum todo_command next_command)2194{
2195FILE *out = fopen_or_warn(rebase_path_rewritten_pending(), "a");2196
2197if (!out)2198return;2199
2200fprintf(out, "%s\n", oid_to_hex(oid));2201fclose(out);2202
2203if (!is_fixup(next_command))2204flush_rewritten_pending();2205}
2206
2207static int should_edit(struct replay_opts *opts) {2208if (opts->edit < 0)2209/*2210* Note that we only handle the case of non-conflicted
2211* commits; continue_single_pick() handles the conflicted
2212* commits itself instead of calling this function.
2213*/
2214return (opts->action == REPLAY_REVERT && isatty(0)) ? 1 : 0;2215return opts->edit;2216}
2217
2218static void refer_to_commit(struct replay_opts *opts,2219struct strbuf *msgbuf, struct commit *commit)2220{
2221if (opts->commit_use_reference) {2222struct pretty_print_context ctx = {2223.abbrev = DEFAULT_ABBREV,2224.date_mode.type = DATE_SHORT,2225};2226repo_format_commit_message(the_repository, commit,2227"%h (%s, %ad)", msgbuf, &ctx);2228} else {2229strbuf_addstr(msgbuf, oid_to_hex(&commit->object.oid));2230}2231}
2232
2233static int do_pick_commit(struct repository *r,2234struct todo_item *item,2235struct replay_opts *opts,2236int final_fixup, int *check_todo)2237{
2238struct replay_ctx *ctx = opts->ctx;2239unsigned int flags = should_edit(opts) ? EDIT_MSG : 0;2240const char *msg_file = should_edit(opts) ? NULL : git_path_merge_msg(r);2241struct object_id head;2242struct commit *base, *next, *parent;2243const char *base_label, *next_label;2244char *author = NULL;2245struct commit_message msg = { NULL, NULL, NULL, NULL };2246int res, unborn = 0, reword = 0, allow, drop_commit;2247enum todo_command command = item->command;2248struct commit *commit = item->commit;2249
2250if (opts->no_commit) {2251/*2252* We do not intend to commit immediately. We just want to
2253* merge the differences in, so let's compute the tree
2254* that represents the "current" state for the merge machinery
2255* to work on.
2256*/
2257if (write_index_as_tree(&head, r->index, r->index_file, 0, NULL))2258return error(_("your index file is unmerged."));2259} else {2260unborn = repo_get_oid(r, "HEAD", &head);2261/* Do we want to generate a root commit? */2262if (is_pick_or_similar(command) && opts->have_squash_onto &&2263oideq(&head, &opts->squash_onto)) {2264if (is_fixup(command))2265return error(_("cannot fixup root commit"));2266flags |= CREATE_ROOT_COMMIT;2267unborn = 1;2268} else if (unborn)2269oidcpy(&head, the_hash_algo->empty_tree);2270if (index_differs_from(r, unborn ? empty_tree_oid_hex(the_repository->hash_algo) : "HEAD",2271NULL, 0))2272return error_dirty_index(r, opts);2273}2274discard_index(r->index);2275
2276if (!commit->parents)2277parent = NULL;2278else if (commit->parents->next) {2279/* Reverting or cherry-picking a merge commit */2280int cnt;2281struct commit_list *p;2282
2283if (!opts->mainline)2284return error(_("commit %s is a merge but no -m option was given."),2285oid_to_hex(&commit->object.oid));2286
2287for (cnt = 1, p = commit->parents;2288cnt != opts->mainline && p;2289cnt++)2290p = p->next;2291if (cnt != opts->mainline || !p)2292return error(_("commit %s does not have parent %d"),2293oid_to_hex(&commit->object.oid), opts->mainline);2294parent = p->item;2295} else if (1 < opts->mainline)2296/*2297* Non-first parent explicitly specified as mainline for
2298* non-merge commit
2299*/
2300return error(_("commit %s does not have parent %d"),2301oid_to_hex(&commit->object.oid), opts->mainline);2302else2303parent = commit->parents->item;2304
2305if (get_message(commit, &msg) != 0)2306return error(_("cannot get commit message for %s"),2307oid_to_hex(&commit->object.oid));2308
2309if (opts->allow_ff && !is_fixup(command) &&2310((parent && oideq(&parent->object.oid, &head)) ||2311(!parent && unborn))) {2312if (is_rebase_i(opts))2313write_author_script(msg.message);2314res = fast_forward_to(r, &commit->object.oid, &head, unborn,2315opts);2316if (res || command != TODO_REWORD)2317goto leave;2318reword = 1;2319msg_file = NULL;2320goto fast_forward_edit;2321}2322if (parent && repo_parse_commit(r, parent) < 0)2323/* TRANSLATORS: The first %s will be a "todo" command like2324"revert" or "pick", the second %s a SHA1. */
2325return error(_("%s: cannot parse parent commit %s"),2326command_to_string(command),2327oid_to_hex(&parent->object.oid));2328
2329/*2330* "commit" is an existing commit. We would want to apply
2331* the difference it introduces since its first parent "prev"
2332* on top of the current HEAD if we are cherry-pick. Or the
2333* reverse of it if we are revert.
2334*/
2335
2336if (command == TODO_REVERT) {2337const char *orig_subject;2338
2339base = commit;2340base_label = msg.label;2341next = parent;2342next_label = msg.parent_label;2343if (opts->commit_use_reference) {2344strbuf_addstr(&ctx->message,2345"# *** SAY WHY WE ARE REVERTING ON THE TITLE LINE ***");2346} else if (skip_prefix(msg.subject, "Revert \"", &orig_subject) &&2347/*2348* We don't touch pre-existing repeated reverts, because
2349* theoretically these can be nested arbitrarily deeply,
2350* thus requiring excessive complexity to deal with.
2351*/
2352!starts_with(orig_subject, "Revert \"")) {2353strbuf_addstr(&ctx->message, "Reapply \"");2354strbuf_addstr(&ctx->message, orig_subject);2355} else {2356strbuf_addstr(&ctx->message, "Revert \"");2357strbuf_addstr(&ctx->message, msg.subject);2358strbuf_addstr(&ctx->message, "\"");2359}2360strbuf_addstr(&ctx->message, "\n\nThis reverts commit ");2361refer_to_commit(opts, &ctx->message, commit);2362
2363if (commit->parents && commit->parents->next) {2364strbuf_addstr(&ctx->message, ", reversing\nchanges made to ");2365refer_to_commit(opts, &ctx->message, parent);2366}2367strbuf_addstr(&ctx->message, ".\n");2368} else {2369const char *p;2370
2371base = parent;2372base_label = msg.parent_label;2373next = commit;2374next_label = msg.label;2375
2376/* Append the commit log message to ctx->message. */2377if (find_commit_subject(msg.message, &p))2378strbuf_addstr(&ctx->message, p);2379
2380if (opts->record_origin) {2381strbuf_complete_line(&ctx->message);2382if (!has_conforming_footer(&ctx->message, NULL, 0))2383strbuf_addch(&ctx->message, '\n');2384strbuf_addstr(&ctx->message, cherry_picked_prefix);2385strbuf_addstr(&ctx->message, oid_to_hex(&commit->object.oid));2386strbuf_addstr(&ctx->message, ")\n");2387}2388if (!is_fixup(command))2389author = get_author(msg.message);2390}2391ctx->have_message = 1;2392
2393if (command == TODO_REWORD)2394reword = 1;2395else if (is_fixup(command)) {2396if (update_squash_messages(r, command, commit,2397opts, item->flags)) {2398res = -1;2399goto leave;2400}2401flags |= AMEND_MSG;2402if (!final_fixup)2403msg_file = rebase_path_squash_msg();2404else if (file_exists(rebase_path_fixup_msg())) {2405flags |= VERBATIM_MSG;2406msg_file = rebase_path_fixup_msg();2407} else {2408const char *dest = git_path_squash_msg(r);2409unlink(dest);2410if (copy_file(dest, rebase_path_squash_msg(), 0666)) {2411res = error(_("could not copy '%s' to '%s'"),2412rebase_path_squash_msg(), dest);2413goto leave;2414}2415unlink(git_path_merge_msg(r));2416msg_file = dest;2417flags |= EDIT_MSG;2418}2419}2420
2421if (opts->signoff && !is_fixup(command))2422append_signoff(&ctx->message, 0, 0);2423
2424if (is_rebase_i(opts) && write_author_script(msg.message) < 0)2425res = -1;2426else if (!opts->strategy ||2427!strcmp(opts->strategy, "recursive") ||2428!strcmp(opts->strategy, "ort") ||2429command == TODO_REVERT) {2430res = do_recursive_merge(r, base, next, base_label, next_label,2431&head, &ctx->message, opts);2432if (res < 0)2433goto leave;2434
2435res |= write_message(ctx->message.buf, ctx->message.len,2436git_path_merge_msg(r), 0);2437} else {2438struct commit_list *common = NULL;2439struct commit_list *remotes = NULL;2440
2441res = write_message(ctx->message.buf, ctx->message.len,2442git_path_merge_msg(r), 0);2443
2444commit_list_insert(base, &common);2445commit_list_insert(next, &remotes);2446res |= try_merge_command(r, opts->strategy,2447opts->xopts.nr, opts->xopts.v,2448common, oid_to_hex(&head), remotes);2449free_commit_list(common);2450free_commit_list(remotes);2451}2452
2453/*2454* If the merge was clean or if it failed due to conflict, we write
2455* CHERRY_PICK_HEAD for the subsequent invocation of commit to use.
2456* However, if the merge did not even start, then we don't want to
2457* write it at all.
2458*/
2459if ((command == TODO_PICK || command == TODO_REWORD ||2460command == TODO_EDIT) && !opts->no_commit &&2461(res == 0 || res == 1) &&2462refs_update_ref(get_main_ref_store(the_repository), NULL, "CHERRY_PICK_HEAD", &commit->object.oid, NULL,2463REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))2464res = -1;2465if (command == TODO_REVERT && ((opts->no_commit && res == 0) || res == 1) &&2466refs_update_ref(get_main_ref_store(the_repository), NULL, "REVERT_HEAD", &commit->object.oid, NULL,2467REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))2468res = -1;2469
2470if (res) {2471error(command == TODO_REVERT2472? _("could not revert %s... %s")2473: _("could not apply %s... %s"),2474short_commit_name(r, commit), msg.subject);2475print_advice(r, res == 1, opts);2476repo_rerere(r, opts->allow_rerere_auto);2477goto leave;2478}2479
2480drop_commit = 0;2481allow = allow_empty(r, opts, commit);2482if (allow < 0) {2483res = allow;2484goto leave;2485} else if (allow == 1) {2486flags |= ALLOW_EMPTY;2487} else if (allow == 2) {2488drop_commit = 1;2489refs_delete_ref(get_main_ref_store(r), "", "CHERRY_PICK_HEAD",2490NULL, REF_NO_DEREF);2491unlink(git_path_merge_msg(r));2492refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",2493NULL, REF_NO_DEREF);2494fprintf(stderr,2495_("dropping %s %s -- patch contents already upstream\n"),2496oid_to_hex(&commit->object.oid), msg.subject);2497} /* else allow == 0 and there's nothing special to do */2498if (!opts->no_commit && !drop_commit) {2499if (author || command == TODO_REVERT || (flags & AMEND_MSG))2500res = do_commit(r, msg_file, author, opts, flags,2501commit? &commit->object.oid : NULL);2502else2503res = error(_("unable to parse commit author"));2504*check_todo = !!(flags & EDIT_MSG);2505if (!res && reword) {2506fast_forward_edit:2507res = run_git_commit(NULL, opts, EDIT_MSG |2508VERIFY_MSG | AMEND_MSG |2509(flags & ALLOW_EMPTY));2510*check_todo = 1;2511}2512}2513
2514
2515if (!res && final_fixup) {2516unlink(rebase_path_fixup_msg());2517unlink(rebase_path_squash_msg());2518unlink(rebase_path_current_fixups());2519strbuf_reset(&ctx->current_fixups);2520ctx->current_fixup_count = 0;2521}2522
2523leave:2524free_message(commit, &msg);2525free(author);2526update_abort_safety_file();2527
2528return res;2529}
2530
2531static int prepare_revs(struct replay_opts *opts)2532{
2533/*2534* picking (but not reverting) ranges (but not individual revisions)
2535* should be done in reverse
2536*/
2537if (opts->action == REPLAY_PICK && !opts->revs->no_walk)2538opts->revs->reverse ^= 1;2539
2540if (prepare_revision_walk(opts->revs))2541return error(_("revision walk setup failed"));2542
2543return 0;2544}
2545
2546static int read_and_refresh_cache(struct repository *r,2547struct replay_opts *opts)2548{
2549struct lock_file index_lock = LOCK_INIT;2550int index_fd = repo_hold_locked_index(r, &index_lock, 0);2551if (repo_read_index(r) < 0) {2552rollback_lock_file(&index_lock);2553return error(_("git %s: failed to read the index"),2554action_name(opts));2555}2556refresh_index(r->index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, NULL);2557
2558if (index_fd >= 0) {2559if (write_locked_index(r->index, &index_lock,2560COMMIT_LOCK | SKIP_IF_UNCHANGED)) {2561return error(_("git %s: failed to refresh the index"),2562action_name(opts));2563}2564}2565
2566/*2567* If we are resolving merges in any way other than "ort", then
2568* expand the sparse index.
2569*/
2570if (opts->strategy && strcmp(opts->strategy, "ort"))2571ensure_full_index(r->index);2572return 0;2573}
2574
2575void todo_list_release(struct todo_list *todo_list)2576{
2577strbuf_release(&todo_list->buf);2578FREE_AND_NULL(todo_list->items);2579todo_list->nr = todo_list->alloc = 0;2580}
2581
2582static struct todo_item *append_new_todo(struct todo_list *todo_list)2583{
2584ALLOC_GROW(todo_list->items, todo_list->nr + 1, todo_list->alloc);2585return todo_list->items + todo_list->nr++;2586}
2587
2588const char *todo_item_get_arg(struct todo_list *todo_list,2589struct todo_item *item)2590{
2591return todo_list->buf.buf + item->arg_offset;2592}
2593
2594static int is_command(enum todo_command command, const char **bol)2595{
2596const char *str = todo_command_info[command].str;2597const char nick = todo_command_info[command].c;2598const char *p = *bol;2599
2600return (skip_prefix(p, str, &p) || (nick && *p++ == nick)) &&2601(*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&2602(*bol = p);2603}
2604
2605static int check_label_or_ref_arg(enum todo_command command, const char *arg)2606{
2607switch (command) {2608case TODO_LABEL:2609/*2610* '#' is not a valid label as the merge command uses it to
2611* separate merge parents from the commit subject.
2612*/
2613if (!strcmp(arg, "#") ||2614check_refname_format(arg, REFNAME_ALLOW_ONELEVEL))2615return error(_("'%s' is not a valid label"), arg);2616break;2617
2618case TODO_UPDATE_REF:2619if (check_refname_format(arg, REFNAME_ALLOW_ONELEVEL))2620return error(_("'%s' is not a valid refname"), arg);2621if (check_refname_format(arg, 0))2622return error(_("update-ref requires a fully qualified "2623"refname e.g. refs/heads/%s"), arg);2624break;2625
2626default:2627BUG("unexpected todo_command");2628}2629
2630return 0;2631}
2632
2633static int check_merge_commit_insn(enum todo_command command)2634{
2635switch(command) {2636case TODO_PICK:2637error(_("'%s' does not accept merge commits"),2638todo_command_info[command].str);2639advise_if_enabled(ADVICE_REBASE_TODO_ERROR, _(2640/*2641* TRANSLATORS: 'pick' and 'merge -C' should not be
2642* translated.
2643*/
2644"'pick' does not take a merge commit. If you wanted to\n"2645"replay the merge, use 'merge -C' on the commit."));2646return -1;2647
2648case TODO_REWORD:2649error(_("'%s' does not accept merge commits"),2650todo_command_info[command].str);2651advise_if_enabled(ADVICE_REBASE_TODO_ERROR, _(2652/*2653* TRANSLATORS: 'reword' and 'merge -c' should not be
2654* translated.
2655*/
2656"'reword' does not take a merge commit. If you wanted to\n"2657"replay the merge and reword the commit message, use\n"2658"'merge -c' on the commit"));2659return -1;2660
2661case TODO_EDIT:2662error(_("'%s' does not accept merge commits"),2663todo_command_info[command].str);2664advise_if_enabled(ADVICE_REBASE_TODO_ERROR, _(2665/*2666* TRANSLATORS: 'edit', 'merge -C' and 'break' should
2667* not be translated.
2668*/
2669"'edit' does not take a merge commit. If you wanted to\n"2670"replay the merge, use 'merge -C' on the commit, and then\n"2671"'break' to give the control back to you so that you can\n"2672"do 'git commit --amend && git rebase --continue'."));2673return -1;2674
2675case TODO_FIXUP:2676case TODO_SQUASH:2677return error(_("cannot squash merge commit into another commit"));2678
2679case TODO_MERGE:2680return 0;2681
2682default:2683BUG("unexpected todo_command");2684}2685}
2686
2687static int parse_insn_line(struct repository *r, struct replay_opts *opts,2688struct todo_item *item, const char *buf,2689const char *bol, char *eol)2690{
2691struct object_id commit_oid;2692char *end_of_object_name;2693int i, saved, status, padding;2694
2695item->flags = 0;2696
2697/* left-trim */2698bol += strspn(bol, " \t");2699
2700if (bol == eol || *bol == '\r' || starts_with_mem(bol, eol - bol, comment_line_str)) {2701item->command = TODO_COMMENT;2702item->commit = NULL;2703item->arg_offset = bol - buf;2704item->arg_len = eol - bol;2705return 0;2706}2707
2708for (i = 0; i < TODO_COMMENT; i++)2709if (is_command(i, &bol)) {2710item->command = i;2711break;2712}2713if (i >= TODO_COMMENT)2714return error(_("invalid command '%.*s'"),2715(int)strcspn(bol, " \t\r\n"), bol);2716
2717/* Eat up extra spaces/ tabs before object name */2718padding = strspn(bol, " \t");2719bol += padding;2720
2721if (item->command == TODO_NOOP || item->command == TODO_BREAK) {2722if (bol != eol)2723return error(_("%s does not accept arguments: '%s'"),2724command_to_string(item->command), bol);2725item->commit = NULL;2726item->arg_offset = bol - buf;2727item->arg_len = eol - bol;2728return 0;2729}2730
2731if (!padding)2732return error(_("missing arguments for %s"),2733command_to_string(item->command));2734
2735if (item->command == TODO_EXEC || item->command == TODO_LABEL ||2736item->command == TODO_RESET || item->command == TODO_UPDATE_REF) {2737int ret = 0;2738
2739item->commit = NULL;2740item->arg_offset = bol - buf;2741item->arg_len = (int)(eol - bol);2742if (item->command == TODO_LABEL ||2743item->command == TODO_UPDATE_REF) {2744saved = *eol;2745*eol = '\0';2746ret = check_label_or_ref_arg(item->command, bol);2747*eol = saved;2748}2749return ret;2750}2751
2752if (item->command == TODO_FIXUP) {2753if (skip_prefix(bol, "-C", &bol)) {2754bol += strspn(bol, " \t");2755item->flags |= TODO_REPLACE_FIXUP_MSG;2756} else if (skip_prefix(bol, "-c", &bol)) {2757bol += strspn(bol, " \t");2758item->flags |= TODO_EDIT_FIXUP_MSG;2759}2760}2761
2762if (item->command == TODO_MERGE) {2763if (skip_prefix(bol, "-C", &bol))2764bol += strspn(bol, " \t");2765else if (skip_prefix(bol, "-c", &bol)) {2766bol += strspn(bol, " \t");2767item->flags |= TODO_EDIT_MERGE_MSG;2768} else {2769item->flags |= TODO_EDIT_MERGE_MSG;2770item->commit = NULL;2771item->arg_offset = bol - buf;2772item->arg_len = (int)(eol - bol);2773return 0;2774}2775}2776
2777end_of_object_name = (char *) bol + strcspn(bol, " \t\n");2778saved = *end_of_object_name;2779*end_of_object_name = '\0';2780status = repo_get_oid(r, bol, &commit_oid);2781if (status < 0)2782error(_("could not parse '%s'"), bol); /* return later */2783*end_of_object_name = saved;2784
2785bol = end_of_object_name + strspn(end_of_object_name, " \t");2786item->arg_offset = bol - buf;2787item->arg_len = (int)(eol - bol);2788
2789if (status < 0)2790return status;2791
2792item->commit = lookup_commit_reference(r, &commit_oid);2793if (!item->commit)2794return -1;2795if (is_rebase_i(opts) &&2796item->commit->parents && item->commit->parents->next)2797return check_merge_commit_insn(item->command);2798return 0;2799}
2800
2801int sequencer_get_last_command(struct repository *r UNUSED, enum replay_action *action)2802{
2803const char *todo_file, *bol;2804struct strbuf buf = STRBUF_INIT;2805int ret = 0;2806
2807todo_file = git_path_todo_file();2808if (strbuf_read_file(&buf, todo_file, 0) < 0) {2809if (errno == ENOENT || errno == ENOTDIR)2810return -1;2811else2812return error_errno("unable to open '%s'", todo_file);2813}2814bol = buf.buf + strspn(buf.buf, " \t\r\n");2815if (is_command(TODO_PICK, &bol) && (*bol == ' ' || *bol == '\t'))2816*action = REPLAY_PICK;2817else if (is_command(TODO_REVERT, &bol) &&2818(*bol == ' ' || *bol == '\t'))2819*action = REPLAY_REVERT;2820else2821ret = -1;2822
2823strbuf_release(&buf);2824
2825return ret;2826}
2827
2828int todo_list_parse_insn_buffer(struct repository *r, struct replay_opts *opts,2829char *buf, struct todo_list *todo_list)2830{
2831struct todo_item *item;2832char *p = buf, *next_p;2833int i, res = 0, fixup_okay = file_exists(rebase_path_done());2834
2835todo_list->current = todo_list->nr = todo_list->total_nr = 0;2836
2837for (i = 1; *p; i++, p = next_p) {2838char *eol = strchrnul(p, '\n');2839
2840next_p = *eol ? eol + 1 /* skip LF */ : eol;2841
2842if (p != eol && eol[-1] == '\r')2843eol--; /* strip Carriage Return */2844
2845item = append_new_todo(todo_list);2846item->offset_in_buf = p - todo_list->buf.buf;2847if (parse_insn_line(r, opts, item, buf, p, eol)) {2848res = error(_("invalid line %d: %.*s"),2849i, (int)(eol - p), p);2850item->command = TODO_COMMENT + 1;2851item->arg_offset = p - buf;2852item->arg_len = (int)(eol - p);2853item->commit = NULL;2854}2855
2856if (item->command != TODO_COMMENT)2857todo_list->total_nr++;2858
2859if (fixup_okay)2860; /* do nothing */2861else if (is_fixup(item->command))2862res = error(_("cannot '%s' without a previous commit"),2863command_to_string(item->command));2864else if (!is_noop(item->command))2865fixup_okay = 1;2866}2867
2868return res;2869}
2870
2871static int count_commands(struct todo_list *todo_list)2872{
2873int count = 0, i;2874
2875for (i = 0; i < todo_list->nr; i++)2876if (todo_list->items[i].command != TODO_COMMENT)2877count++;2878
2879return count;2880}
2881
2882static int get_item_line_offset(struct todo_list *todo_list, int index)2883{
2884return index < todo_list->nr ?2885todo_list->items[index].offset_in_buf : todo_list->buf.len;2886}
2887
2888static const char *get_item_line(struct todo_list *todo_list, int index)2889{
2890return todo_list->buf.buf + get_item_line_offset(todo_list, index);2891}
2892
2893static int get_item_line_length(struct todo_list *todo_list, int index)2894{
2895return get_item_line_offset(todo_list, index + 1)2896- get_item_line_offset(todo_list, index);2897}
2898
2899static ssize_t strbuf_read_file_or_whine(struct strbuf *sb, const char *path)2900{
2901int fd;2902ssize_t len;2903
2904fd = open(path, O_RDONLY);2905if (fd < 0)2906return error_errno(_("could not open '%s'"), path);2907len = strbuf_read(sb, fd, 0);2908close(fd);2909if (len < 0)2910return error(_("could not read '%s'."), path);2911return len;2912}
2913
2914static int have_finished_the_last_pick(void)2915{
2916struct strbuf buf = STRBUF_INIT;2917const char *eol;2918const char *todo_path = git_path_todo_file();2919int ret = 0;2920
2921if (strbuf_read_file(&buf, todo_path, 0) < 0) {2922if (errno == ENOENT) {2923return 0;2924} else {2925error_errno("unable to open '%s'", todo_path);2926return 0;2927}2928}2929/* If there is only one line then we are done */2930eol = strchr(buf.buf, '\n');2931if (!eol || !eol[1])2932ret = 1;2933
2934strbuf_release(&buf);2935
2936return ret;2937}
2938
2939void sequencer_post_commit_cleanup(struct repository *r, int verbose)2940{
2941struct replay_opts opts = REPLAY_OPTS_INIT;2942int need_cleanup = 0;2943
2944if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD")) {2945if (!refs_delete_ref(get_main_ref_store(r), "",2946"CHERRY_PICK_HEAD", NULL, REF_NO_DEREF) &&2947verbose)2948warning(_("cancelling a cherry picking in progress"));2949opts.action = REPLAY_PICK;2950need_cleanup = 1;2951}2952
2953if (refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) {2954if (!refs_delete_ref(get_main_ref_store(r), "", "REVERT_HEAD",2955NULL, REF_NO_DEREF) &&2956verbose)2957warning(_("cancelling a revert in progress"));2958opts.action = REPLAY_REVERT;2959need_cleanup = 1;2960}2961
2962refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",2963NULL, REF_NO_DEREF);2964
2965if (!need_cleanup)2966goto out;2967
2968if (!have_finished_the_last_pick())2969goto out;2970
2971sequencer_remove_state(&opts);2972out:2973replay_opts_release(&opts);2974}
2975
2976static void todo_list_write_total_nr(struct todo_list *todo_list)2977{
2978FILE *f = fopen_or_warn(rebase_path_msgtotal(), "w");2979
2980if (f) {2981fprintf(f, "%d\n", todo_list->total_nr);2982fclose(f);2983}2984}
2985
2986static int read_populate_todo(struct repository *r,2987struct todo_list *todo_list,2988struct replay_opts *opts)2989{
2990const char *todo_file = get_todo_path(opts);2991int res;2992
2993strbuf_reset(&todo_list->buf);2994if (strbuf_read_file_or_whine(&todo_list->buf, todo_file) < 0)2995return -1;2996
2997res = todo_list_parse_insn_buffer(r, opts, todo_list->buf.buf, todo_list);2998if (res) {2999if (is_rebase_i(opts))3000return error(_("please fix this using "3001"'git rebase --edit-todo'."));3002return error(_("unusable instruction sheet: '%s'"), todo_file);3003}3004
3005if (!todo_list->nr &&3006(!is_rebase_i(opts) || !file_exists(rebase_path_done())))3007return error(_("no commits parsed."));3008
3009if (!is_rebase_i(opts)) {3010enum todo_command valid =3011opts->action == REPLAY_PICK ? TODO_PICK : TODO_REVERT;3012int i;3013
3014for (i = 0; i < todo_list->nr; i++)3015if (valid == todo_list->items[i].command)3016continue;3017else if (valid == TODO_PICK)3018return error(_("cannot cherry-pick during a revert."));3019else3020return error(_("cannot revert during a cherry-pick."));3021}3022
3023if (is_rebase_i(opts)) {3024struct todo_list done = TODO_LIST_INIT;3025
3026if (strbuf_read_file(&done.buf, rebase_path_done(), 0) > 0 &&3027!todo_list_parse_insn_buffer(r, opts, done.buf.buf, &done))3028todo_list->done_nr = count_commands(&done);3029else3030todo_list->done_nr = 0;3031
3032todo_list->total_nr = todo_list->done_nr3033+ count_commands(todo_list);3034todo_list_release(&done);3035
3036todo_list_write_total_nr(todo_list);3037}3038
3039return 0;3040}
3041
3042static int git_config_string_dup(char **dest,3043const char *var, const char *value)3044{
3045if (!value)3046return config_error_nonbool(var);3047free(*dest);3048*dest = xstrdup(value);3049return 0;3050}
3051
3052static int populate_opts_cb(const char *key, const char *value,3053const struct config_context *ctx,3054void *data)3055{
3056struct replay_opts *opts = data;3057int error_flag = 1;3058
3059if (!value)3060error_flag = 0;3061else if (!strcmp(key, "options.no-commit"))3062opts->no_commit = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3063else if (!strcmp(key, "options.edit"))3064opts->edit = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3065else if (!strcmp(key, "options.allow-empty"))3066opts->allow_empty =3067git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3068else if (!strcmp(key, "options.allow-empty-message"))3069opts->allow_empty_message =3070git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3071else if (!strcmp(key, "options.drop-redundant-commits"))3072opts->drop_redundant_commits =3073git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3074else if (!strcmp(key, "options.keep-redundant-commits"))3075opts->keep_redundant_commits =3076git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3077else if (!strcmp(key, "options.signoff"))3078opts->signoff = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3079else if (!strcmp(key, "options.record-origin"))3080opts->record_origin = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3081else if (!strcmp(key, "options.allow-ff"))3082opts->allow_ff = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);3083else if (!strcmp(key, "options.mainline"))3084opts->mainline = git_config_int(key, value, ctx->kvi);3085else if (!strcmp(key, "options.strategy"))3086git_config_string_dup(&opts->strategy, key, value);3087else if (!strcmp(key, "options.gpg-sign"))3088git_config_string_dup(&opts->gpg_sign, key, value);3089else if (!strcmp(key, "options.strategy-option")) {3090strvec_push(&opts->xopts, value);3091} else if (!strcmp(key, "options.allow-rerere-auto"))3092opts->allow_rerere_auto =3093git_config_bool_or_int(key, value, ctx->kvi, &error_flag) ?3094RERERE_AUTOUPDATE : RERERE_NOAUTOUPDATE;3095else if (!strcmp(key, "options.default-msg-cleanup")) {3096opts->explicit_cleanup = 1;3097opts->default_msg_cleanup = get_cleanup_mode(value, 1);3098} else3099return error(_("invalid key: %s"), key);3100
3101if (!error_flag)3102return error(_("invalid value for '%s': '%s'"), key, value);3103
3104return 0;3105}
3106
3107static void parse_strategy_opts(struct replay_opts *opts, char *raw_opts)3108{
3109int i;3110int count;3111const char **argv;3112char *strategy_opts_string = raw_opts;3113
3114if (*strategy_opts_string == ' ')3115strategy_opts_string++;3116
3117count = split_cmdline(strategy_opts_string, &argv);3118if (count < 0)3119BUG("could not split '%s': %s", strategy_opts_string,3120split_cmdline_strerror(count));3121for (i = 0; i < count; i++) {3122const char *arg = argv[i];3123
3124skip_prefix(arg, "--", &arg);3125strvec_push(&opts->xopts, arg);3126}3127free(argv);3128}
3129
3130static void read_strategy_opts(struct replay_opts *opts, struct strbuf *buf)3131{
3132strbuf_reset(buf);3133if (!read_oneliner(buf, rebase_path_strategy(), 0))3134return;3135opts->strategy = strbuf_detach(buf, NULL);3136if (!read_oneliner(buf, rebase_path_strategy_opts(), 0))3137return;3138
3139parse_strategy_opts(opts, buf->buf);3140}
3141
3142static int read_populate_opts(struct replay_opts *opts)3143{
3144struct replay_ctx *ctx = opts->ctx;3145
3146if (is_rebase_i(opts)) {3147struct strbuf buf = STRBUF_INIT;3148int ret = 0;3149
3150if (read_oneliner(&buf, rebase_path_gpg_sign_opt(),3151READ_ONELINER_SKIP_IF_EMPTY)) {3152if (!starts_with(buf.buf, "-S"))3153strbuf_reset(&buf);3154else {3155free(opts->gpg_sign);3156opts->gpg_sign = xstrdup(buf.buf + 2);3157}3158strbuf_reset(&buf);3159}3160
3161if (read_oneliner(&buf, rebase_path_allow_rerere_autoupdate(),3162READ_ONELINER_SKIP_IF_EMPTY)) {3163if (!strcmp(buf.buf, "--rerere-autoupdate"))3164opts->allow_rerere_auto = RERERE_AUTOUPDATE;3165else if (!strcmp(buf.buf, "--no-rerere-autoupdate"))3166opts->allow_rerere_auto = RERERE_NOAUTOUPDATE;3167strbuf_reset(&buf);3168}3169
3170if (file_exists(rebase_path_verbose()))3171opts->verbose = 1;3172
3173if (file_exists(rebase_path_quiet()))3174opts->quiet = 1;3175
3176if (file_exists(rebase_path_signoff())) {3177opts->allow_ff = 0;3178opts->signoff = 1;3179}3180
3181if (file_exists(rebase_path_cdate_is_adate())) {3182opts->allow_ff = 0;3183opts->committer_date_is_author_date = 1;3184}3185
3186if (file_exists(rebase_path_ignore_date())) {3187opts->allow_ff = 0;3188opts->ignore_date = 1;3189}3190
3191if (file_exists(rebase_path_reschedule_failed_exec()))3192opts->reschedule_failed_exec = 1;3193else if (file_exists(rebase_path_no_reschedule_failed_exec()))3194opts->reschedule_failed_exec = 0;3195
3196if (file_exists(rebase_path_drop_redundant_commits()))3197opts->drop_redundant_commits = 1;3198
3199if (file_exists(rebase_path_keep_redundant_commits()))3200opts->keep_redundant_commits = 1;3201
3202read_strategy_opts(opts, &buf);3203strbuf_reset(&buf);3204
3205if (read_oneliner(&ctx->current_fixups,3206rebase_path_current_fixups(),3207READ_ONELINER_SKIP_IF_EMPTY)) {3208const char *p = ctx->current_fixups.buf;3209ctx->current_fixup_count = 1;3210while ((p = strchr(p, '\n'))) {3211ctx->current_fixup_count++;3212p++;3213}3214}3215
3216if (read_oneliner(&buf, rebase_path_squash_onto(), 0)) {3217if (repo_get_oid_committish(the_repository, buf.buf, &opts->squash_onto) < 0) {3218ret = error(_("unusable squash-onto"));3219goto done_rebase_i;3220}3221opts->have_squash_onto = 1;3222}3223
3224done_rebase_i:3225strbuf_release(&buf);3226return ret;3227}3228
3229if (!file_exists(git_path_opts_file()))3230return 0;3231/*3232* The function git_parse_source(), called from git_config_from_file(),
3233* may die() in case of a syntactically incorrect file. We do not care
3234* about this case, though, because we wrote that file ourselves, so we
3235* are pretty certain that it is syntactically correct.
3236*/
3237if (git_config_from_file(populate_opts_cb, git_path_opts_file(), opts) < 0)3238return error(_("malformed options sheet: '%s'"),3239git_path_opts_file());3240return 0;3241}
3242
3243static void write_strategy_opts(struct replay_opts *opts)3244{
3245struct strbuf buf = STRBUF_INIT;3246
3247/*3248* Quote strategy options so that they can be read correctly
3249* by split_cmdline().
3250*/
3251quote_cmdline(&buf, opts->xopts.v);3252write_file(rebase_path_strategy_opts(), "%s\n", buf.buf);3253strbuf_release(&buf);3254}
3255
3256int write_basic_state(struct replay_opts *opts, const char *head_name,3257struct commit *onto, const struct object_id *orig_head)3258{
3259if (head_name)3260write_file(rebase_path_head_name(), "%s\n", head_name);3261if (onto)3262write_file(rebase_path_onto(), "%s\n",3263oid_to_hex(&onto->object.oid));3264if (orig_head)3265write_file(rebase_path_orig_head(), "%s\n",3266oid_to_hex(orig_head));3267
3268if (opts->quiet)3269write_file(rebase_path_quiet(), "%s", "");3270if (opts->verbose)3271write_file(rebase_path_verbose(), "%s", "");3272if (opts->strategy)3273write_file(rebase_path_strategy(), "%s\n", opts->strategy);3274if (opts->xopts.nr > 0)3275write_strategy_opts(opts);3276
3277if (opts->allow_rerere_auto == RERERE_AUTOUPDATE)3278write_file(rebase_path_allow_rerere_autoupdate(), "--rerere-autoupdate\n");3279else if (opts->allow_rerere_auto == RERERE_NOAUTOUPDATE)3280write_file(rebase_path_allow_rerere_autoupdate(), "--no-rerere-autoupdate\n");3281
3282if (opts->gpg_sign)3283write_file(rebase_path_gpg_sign_opt(), "-S%s\n", opts->gpg_sign);3284if (opts->signoff)3285write_file(rebase_path_signoff(), "--signoff\n");3286if (opts->drop_redundant_commits)3287write_file(rebase_path_drop_redundant_commits(), "%s", "");3288if (opts->keep_redundant_commits)3289write_file(rebase_path_keep_redundant_commits(), "%s", "");3290if (opts->committer_date_is_author_date)3291write_file(rebase_path_cdate_is_adate(), "%s", "");3292if (opts->ignore_date)3293write_file(rebase_path_ignore_date(), "%s", "");3294if (opts->reschedule_failed_exec)3295write_file(rebase_path_reschedule_failed_exec(), "%s", "");3296else3297write_file(rebase_path_no_reschedule_failed_exec(), "%s", "");3298
3299return 0;3300}
3301
3302static int walk_revs_populate_todo(struct todo_list *todo_list,3303struct replay_opts *opts)3304{
3305enum todo_command command = opts->action == REPLAY_PICK ?3306TODO_PICK : TODO_REVERT;3307const char *command_string = todo_command_info[command].str;3308const char *encoding;3309struct commit *commit;3310
3311if (prepare_revs(opts))3312return -1;3313
3314encoding = get_log_output_encoding();3315
3316while ((commit = get_revision(opts->revs))) {3317struct todo_item *item = append_new_todo(todo_list);3318const char *commit_buffer = repo_logmsg_reencode(the_repository,3319commit, NULL,3320encoding);3321const char *subject;3322int subject_len;3323
3324item->command = command;3325item->commit = commit;3326item->arg_offset = 0;3327item->arg_len = 0;3328item->offset_in_buf = todo_list->buf.len;3329subject_len = find_commit_subject(commit_buffer, &subject);3330strbuf_addf(&todo_list->buf, "%s %s %.*s\n", command_string,3331short_commit_name(the_repository, commit),3332subject_len, subject);3333repo_unuse_commit_buffer(the_repository, commit,3334commit_buffer);3335}3336
3337if (!todo_list->nr)3338return error(_("empty commit set passed"));3339
3340return 0;3341}
3342
3343static int create_seq_dir(struct repository *r)3344{
3345enum replay_action action;3346const char *in_progress_error = NULL;3347const char *in_progress_advice = NULL;3348unsigned int advise_skip =3349refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD") ||3350refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD");3351
3352if (!sequencer_get_last_command(r, &action)) {3353switch (action) {3354case REPLAY_REVERT:3355in_progress_error = _("revert is already in progress");3356in_progress_advice =3357_("try \"git revert (--continue | %s--abort | --quit)\"");3358break;3359case REPLAY_PICK:3360in_progress_error = _("cherry-pick is already in progress");3361in_progress_advice =3362_("try \"git cherry-pick (--continue | %s--abort | --quit)\"");3363break;3364default:3365BUG("unexpected action in create_seq_dir");3366}3367}3368if (in_progress_error) {3369error("%s", in_progress_error);3370if (advice_enabled(ADVICE_SEQUENCER_IN_USE))3371advise(in_progress_advice,3372advise_skip ? "--skip | " : "");3373return -1;3374}3375if (mkdir(git_path_seq_dir(), 0777) < 0)3376return error_errno(_("could not create sequencer directory '%s'"),3377git_path_seq_dir());3378
3379return 0;3380}
3381
3382static int save_head(const char *head)3383{
3384return write_message(head, strlen(head), git_path_head_file(), 1);3385}
3386
3387static int rollback_is_safe(void)3388{
3389struct strbuf sb = STRBUF_INIT;3390struct object_id expected_head, actual_head;3391
3392if (strbuf_read_file(&sb, git_path_abort_safety_file(), 0) >= 0) {3393strbuf_trim(&sb);3394if (get_oid_hex(sb.buf, &expected_head)) {3395strbuf_release(&sb);3396die(_("could not parse %s"), git_path_abort_safety_file());3397}3398strbuf_release(&sb);3399}3400else if (errno == ENOENT)3401oidclr(&expected_head, the_repository->hash_algo);3402else3403die_errno(_("could not read '%s'"), git_path_abort_safety_file());3404
3405if (repo_get_oid(the_repository, "HEAD", &actual_head))3406oidclr(&actual_head, the_repository->hash_algo);3407
3408return oideq(&actual_head, &expected_head);3409}
3410
3411static int reset_merge(const struct object_id *oid)3412{
3413struct child_process cmd = CHILD_PROCESS_INIT;3414
3415cmd.git_cmd = 1;3416strvec_pushl(&cmd.args, "reset", "--merge", NULL);3417
3418if (!is_null_oid(oid))3419strvec_push(&cmd.args, oid_to_hex(oid));3420
3421return run_command(&cmd);3422}
3423
3424static int rollback_single_pick(struct repository *r)3425{
3426struct object_id head_oid;3427
3428if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&3429!refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD"))3430return error(_("no cherry-pick or revert in progress"));3431if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", 0, &head_oid, NULL))3432return error(_("cannot resolve HEAD"));3433if (is_null_oid(&head_oid))3434return error(_("cannot abort from a branch yet to be born"));3435return reset_merge(&head_oid);3436}
3437
3438static int skip_single_pick(void)3439{
3440struct object_id head;3441
3442if (refs_read_ref_full(get_main_ref_store(the_repository), "HEAD", 0, &head, NULL))3443return error(_("cannot resolve HEAD"));3444return reset_merge(&head);3445}
3446
3447int sequencer_rollback(struct repository *r, struct replay_opts *opts)3448{
3449FILE *f;3450struct object_id oid;3451struct strbuf buf = STRBUF_INIT;3452const char *p;3453
3454f = fopen(git_path_head_file(), "r");3455if (!f && errno == ENOENT) {3456/*3457* There is no multiple-cherry-pick in progress.
3458* If CHERRY_PICK_HEAD or REVERT_HEAD indicates
3459* a single-cherry-pick in progress, abort that.
3460*/
3461return rollback_single_pick(r);3462}3463if (!f)3464return error_errno(_("cannot open '%s'"), git_path_head_file());3465if (strbuf_getline_lf(&buf, f)) {3466error(_("cannot read '%s': %s"), git_path_head_file(),3467ferror(f) ? strerror(errno) : _("unexpected end of file"));3468fclose(f);3469goto fail;3470}3471fclose(f);3472if (parse_oid_hex(buf.buf, &oid, &p) || *p != '\0') {3473error(_("stored pre-cherry-pick HEAD file '%s' is corrupt"),3474git_path_head_file());3475goto fail;3476}3477if (is_null_oid(&oid)) {3478error(_("cannot abort from a branch yet to be born"));3479goto fail;3480}3481
3482if (!rollback_is_safe()) {3483/* Do not error, just do not rollback */3484warning(_("You seem to have moved HEAD. "3485"Not rewinding, check your HEAD!"));3486} else3487if (reset_merge(&oid))3488goto fail;3489strbuf_release(&buf);3490return sequencer_remove_state(opts);3491fail:3492strbuf_release(&buf);3493return -1;3494}
3495
3496int sequencer_skip(struct repository *r, struct replay_opts *opts)3497{
3498enum replay_action action = -1;3499sequencer_get_last_command(r, &action);3500
3501/*3502* Check whether the subcommand requested to skip the commit is actually
3503* in progress and that it's safe to skip the commit.
3504*
3505* opts->action tells us which subcommand requested to skip the commit.
3506* If the corresponding .git/<ACTION>_HEAD exists, we know that the
3507* action is in progress and we can skip the commit.
3508*
3509* Otherwise we check that the last instruction was related to the
3510* particular subcommand we're trying to execute and barf if that's not
3511* the case.
3512*
3513* Finally we check that the rollback is "safe", i.e., has the HEAD
3514* moved? In this case, it doesn't make sense to "reset the merge" and
3515* "skip the commit" as the user already handled this by committing. But
3516* we'd not want to barf here, instead give advice on how to proceed. We
3517* only need to check that when .git/<ACTION>_HEAD doesn't exist because
3518* it gets removed when the user commits, so if it still exists we're
3519* sure the user can't have committed before.
3520*/
3521switch (opts->action) {3522case REPLAY_REVERT:3523if (!refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) {3524if (action != REPLAY_REVERT)3525return error(_("no revert in progress"));3526if (!rollback_is_safe())3527goto give_advice;3528}3529break;3530case REPLAY_PICK:3531if (!refs_ref_exists(get_main_ref_store(r),3532"CHERRY_PICK_HEAD")) {3533if (action != REPLAY_PICK)3534return error(_("no cherry-pick in progress"));3535if (!rollback_is_safe())3536goto give_advice;3537}3538break;3539default:3540BUG("unexpected action in sequencer_skip");3541}3542
3543if (skip_single_pick())3544return error(_("failed to skip the commit"));3545if (!is_directory(git_path_seq_dir()))3546return 0;3547
3548return sequencer_continue(r, opts);3549
3550give_advice:3551error(_("there is nothing to skip"));3552
3553if (advice_enabled(ADVICE_RESOLVE_CONFLICT)) {3554advise(_("have you committed already?\n"3555"try \"git %s --continue\""),3556action == REPLAY_REVERT ? "revert" : "cherry-pick");3557}3558return -1;3559}
3560
3561static int save_todo(struct todo_list *todo_list, struct replay_opts *opts,3562int reschedule)3563{
3564struct lock_file todo_lock = LOCK_INIT;3565const char *todo_path = get_todo_path(opts);3566int next = todo_list->current, offset, fd;3567
3568/*3569* rebase -i writes "git-rebase-todo" without the currently executing
3570* command, appending it to "done" instead.
3571*/
3572if (is_rebase_i(opts) && !reschedule)3573next++;3574
3575fd = hold_lock_file_for_update(&todo_lock, todo_path, 0);3576if (fd < 0)3577return error_errno(_("could not lock '%s'"), todo_path);3578offset = get_item_line_offset(todo_list, next);3579if (write_in_full(fd, todo_list->buf.buf + offset,3580todo_list->buf.len - offset) < 0)3581return error_errno(_("could not write to '%s'"), todo_path);3582if (commit_lock_file(&todo_lock) < 0)3583return error(_("failed to finalize '%s'"), todo_path);3584
3585if (is_rebase_i(opts) && !reschedule && next > 0) {3586const char *done = rebase_path_done();3587int fd = open(done, O_CREAT | O_WRONLY | O_APPEND, 0666);3588int ret = 0;3589
3590if (fd < 0)3591return 0;3592if (write_in_full(fd, get_item_line(todo_list, next - 1),3593get_item_line_length(todo_list, next - 1))3594< 0)3595ret = error_errno(_("could not write to '%s'"), done);3596if (close(fd) < 0)3597ret = error_errno(_("failed to finalize '%s'"), done);3598return ret;3599}3600return 0;3601}
3602
3603static int save_opts(struct replay_opts *opts)3604{
3605const char *opts_file = git_path_opts_file();3606int res = 0;3607
3608if (opts->no_commit)3609res |= git_config_set_in_file_gently(opts_file,3610"options.no-commit", NULL, "true");3611if (opts->edit >= 0)3612res |= git_config_set_in_file_gently(opts_file, "options.edit", NULL,3613opts->edit ? "true" : "false");3614if (opts->allow_empty)3615res |= git_config_set_in_file_gently(opts_file,3616"options.allow-empty", NULL, "true");3617if (opts->allow_empty_message)3618res |= git_config_set_in_file_gently(opts_file,3619"options.allow-empty-message", NULL, "true");3620if (opts->drop_redundant_commits)3621res |= git_config_set_in_file_gently(opts_file,3622"options.drop-redundant-commits", NULL, "true");3623if (opts->keep_redundant_commits)3624res |= git_config_set_in_file_gently(opts_file,3625"options.keep-redundant-commits", NULL, "true");3626if (opts->signoff)3627res |= git_config_set_in_file_gently(opts_file,3628"options.signoff", NULL, "true");3629if (opts->record_origin)3630res |= git_config_set_in_file_gently(opts_file,3631"options.record-origin", NULL, "true");3632if (opts->allow_ff)3633res |= git_config_set_in_file_gently(opts_file,3634"options.allow-ff", NULL, "true");3635if (opts->mainline) {3636struct strbuf buf = STRBUF_INIT;3637strbuf_addf(&buf, "%d", opts->mainline);3638res |= git_config_set_in_file_gently(opts_file,3639"options.mainline", NULL, buf.buf);3640strbuf_release(&buf);3641}3642if (opts->strategy)3643res |= git_config_set_in_file_gently(opts_file,3644"options.strategy", NULL, opts->strategy);3645if (opts->gpg_sign)3646res |= git_config_set_in_file_gently(opts_file,3647"options.gpg-sign", NULL, opts->gpg_sign);3648for (size_t i = 0; i < opts->xopts.nr; i++)3649res |= git_config_set_multivar_in_file_gently(opts_file,3650"options.strategy-option",3651opts->xopts.v[i], "^$", NULL, 0);3652if (opts->allow_rerere_auto)3653res |= git_config_set_in_file_gently(opts_file,3654"options.allow-rerere-auto", NULL,3655opts->allow_rerere_auto == RERERE_AUTOUPDATE ?3656"true" : "false");3657
3658if (opts->explicit_cleanup)3659res |= git_config_set_in_file_gently(opts_file,3660"options.default-msg-cleanup", NULL,3661describe_cleanup_mode(opts->default_msg_cleanup));3662return res;3663}
3664
3665static int make_patch(struct repository *r,3666struct commit *commit,3667struct replay_opts *opts)3668{
3669struct rev_info log_tree_opt;3670const char *subject;3671char hex[GIT_MAX_HEXSZ + 1];3672int res = 0;3673
3674if (!is_rebase_i(opts))3675BUG("make_patch should only be called when rebasing");3676
3677oid_to_hex_r(hex, &commit->object.oid);3678if (write_message(hex, strlen(hex), rebase_path_stopped_sha(), 1) < 0)3679return -1;3680res |= write_rebase_head(&commit->object.oid);3681
3682memset(&log_tree_opt, 0, sizeof(log_tree_opt));3683repo_init_revisions(r, &log_tree_opt, NULL);3684log_tree_opt.abbrev = 0;3685log_tree_opt.diff = 1;3686log_tree_opt.diffopt.output_format = DIFF_FORMAT_PATCH;3687log_tree_opt.disable_stdin = 1;3688log_tree_opt.no_commit_id = 1;3689log_tree_opt.diffopt.file = fopen(rebase_path_patch(), "w");3690log_tree_opt.diffopt.use_color = GIT_COLOR_NEVER;3691if (!log_tree_opt.diffopt.file)3692res |= error_errno(_("could not open '%s'"),3693rebase_path_patch());3694else {3695res |= log_tree_commit(&log_tree_opt, commit);3696fclose(log_tree_opt.diffopt.file);3697}3698
3699if (!file_exists(rebase_path_message())) {3700const char *encoding = get_commit_output_encoding();3701const char *commit_buffer = repo_logmsg_reencode(r,3702commit, NULL,3703encoding);3704find_commit_subject(commit_buffer, &subject);3705res |= write_message(subject, strlen(subject), rebase_path_message(), 1);3706repo_unuse_commit_buffer(r, commit,3707commit_buffer);3708}3709release_revisions(&log_tree_opt);3710
3711return res;3712}
3713
3714static int intend_to_amend(void)3715{
3716struct object_id head;3717char *p;3718
3719if (repo_get_oid(the_repository, "HEAD", &head))3720return error(_("cannot read HEAD"));3721
3722p = oid_to_hex(&head);3723return write_message(p, strlen(p), rebase_path_amend(), 1);3724}
3725
3726static int error_with_patch(struct repository *r,3727struct commit *commit,3728const char *subject, int subject_len,3729struct replay_opts *opts,3730int exit_code, int to_amend)3731{
3732struct replay_ctx *ctx = opts->ctx;3733
3734/*3735* Write the commit message to be used by "git rebase
3736* --continue". If a "fixup" or "squash" command has conflicts
3737* then we will have already written rebase_path_message() in
3738* error_failed_squash(). If an "edit" command was
3739* fast-forwarded then we don't have a message in ctx->message
3740* and rely on make_patch() to write rebase_path_message()
3741* instead.
3742*/
3743if (ctx->have_message && !file_exists(rebase_path_message()) &&3744write_message(ctx->message.buf, ctx->message.len,3745rebase_path_message(), 0))3746return error(_("could not write commit message file"));3747
3748if (commit && make_patch(r, commit, opts))3749return -1;3750
3751if (to_amend) {3752if (intend_to_amend())3753return -1;3754
3755fprintf(stderr,3756_("You can amend the commit now, with\n"3757"\n"3758" git commit --amend %s\n"3759"\n"3760"Once you are satisfied with your changes, run\n"3761"\n"3762" git rebase --continue\n"),3763gpg_sign_opt_quoted(opts));3764} else if (exit_code) {3765if (commit)3766fprintf_ln(stderr, _("Could not apply %s... %.*s"),3767short_commit_name(r, commit), subject_len, subject);3768else3769/*3770* We don't have the hash of the parent so
3771* just print the line from the todo file.
3772*/
3773fprintf_ln(stderr, _("Could not merge %.*s"),3774subject_len, subject);3775}3776
3777return exit_code;3778}
3779
3780static int error_failed_squash(struct repository *r,3781struct commit *commit,3782struct replay_opts *opts,3783int subject_len,3784const char *subject)3785{
3786if (copy_file(rebase_path_message(), rebase_path_squash_msg(), 0666))3787return error(_("could not copy '%s' to '%s'"),3788rebase_path_squash_msg(), rebase_path_message());3789unlink(git_path_merge_msg(r));3790if (copy_file(git_path_merge_msg(r), rebase_path_message(), 0666))3791return error(_("could not copy '%s' to '%s'"),3792rebase_path_message(),3793git_path_merge_msg(r));3794return error_with_patch(r, commit, subject, subject_len, opts, 1, 0);3795}
3796
3797static int do_exec(struct repository *r, const char *command_line, int quiet)3798{
3799struct child_process cmd = CHILD_PROCESS_INIT;3800int dirty, status;3801
3802if (!quiet)3803fprintf(stderr, _("Executing: %s\n"), command_line);3804cmd.use_shell = 1;3805strvec_push(&cmd.args, command_line);3806strvec_push(&cmd.env, "GIT_CHERRY_PICK_HELP");3807status = run_command(&cmd);3808
3809/* force re-reading of the cache */3810discard_index(r->index);3811if (repo_read_index(r) < 0)3812return error(_("could not read index"));3813
3814dirty = require_clean_work_tree(r, "rebase", NULL, 1, 1);3815
3816if (status) {3817warning(_("execution failed: %s\n%s"3818"You can fix the problem, and then run\n"3819"\n"3820" git rebase --continue\n"3821"\n"),3822command_line,3823dirty ? _("and made changes to the index and/or the "3824"working tree.\n") : "");3825if (status == 127)3826/* command not found */3827status = 1;3828} else if (dirty) {3829warning(_("execution succeeded: %s\nbut "3830"left changes to the index and/or the working tree.\n"3831"Commit or stash your changes, and then run\n"3832"\n"3833" git rebase --continue\n"3834"\n"), command_line);3835status = 1;3836}3837
3838return status;3839}
3840
3841__attribute__((format (printf, 2, 3)))3842static int safe_append(const char *filename, const char *fmt, ...)3843{
3844va_list ap;3845struct lock_file lock = LOCK_INIT;3846int fd = hold_lock_file_for_update(&lock, filename,3847LOCK_REPORT_ON_ERROR);3848struct strbuf buf = STRBUF_INIT;3849
3850if (fd < 0)3851return -1;3852
3853if (strbuf_read_file(&buf, filename, 0) < 0 && errno != ENOENT) {3854error_errno(_("could not read '%s'"), filename);3855rollback_lock_file(&lock);3856return -1;3857}3858strbuf_complete(&buf, '\n');3859va_start(ap, fmt);3860strbuf_vaddf(&buf, fmt, ap);3861va_end(ap);3862
3863if (write_in_full(fd, buf.buf, buf.len) < 0) {3864error_errno(_("could not write to '%s'"), filename);3865strbuf_release(&buf);3866rollback_lock_file(&lock);3867return -1;3868}3869if (commit_lock_file(&lock) < 0) {3870strbuf_release(&buf);3871return error(_("failed to finalize '%s'"), filename);3872}3873
3874strbuf_release(&buf);3875return 0;3876}
3877
3878static int do_label(struct repository *r, const char *name, int len)3879{
3880struct ref_store *refs = get_main_ref_store(r);3881struct ref_transaction *transaction;3882struct strbuf ref_name = STRBUF_INIT, err = STRBUF_INIT;3883struct strbuf msg = STRBUF_INIT;3884int ret = 0;3885struct object_id head_oid;3886
3887if (len == 1 && *name == '#')3888return error(_("illegal label name: '%.*s'"), len, name);3889
3890strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name);3891strbuf_addf(&msg, "rebase (label) '%.*s'", len, name);3892
3893transaction = ref_store_transaction_begin(refs, &err);3894if (!transaction) {3895error("%s", err.buf);3896ret = -1;3897} else if (repo_get_oid(r, "HEAD", &head_oid)) {3898error(_("could not read HEAD"));3899ret = -1;3900} else if (ref_transaction_update(transaction, ref_name.buf,3901&head_oid, NULL, NULL, NULL,39020, msg.buf, &err) < 0 ||3903ref_transaction_commit(transaction, &err)) {3904error("%s", err.buf);3905ret = -1;3906}3907ref_transaction_free(transaction);3908strbuf_release(&err);3909strbuf_release(&msg);3910
3911if (!ret)3912ret = safe_append(rebase_path_refs_to_delete(),3913"%s\n", ref_name.buf);3914strbuf_release(&ref_name);3915
3916return ret;3917}
3918
3919static const char *sequencer_reflog_action(struct replay_opts *opts)3920{
3921if (!opts->reflog_action) {3922opts->reflog_action = getenv(GIT_REFLOG_ACTION);3923opts->reflog_action =3924xstrdup(opts->reflog_action ? opts->reflog_action3925: action_name(opts));3926}3927
3928return opts->reflog_action;3929}
3930
3931__attribute__((format (printf, 3, 4)))3932static const char *reflog_message(struct replay_opts *opts,3933const char *sub_action, const char *fmt, ...)3934{
3935va_list ap;3936static struct strbuf buf = STRBUF_INIT;3937
3938va_start(ap, fmt);3939strbuf_reset(&buf);3940strbuf_addstr(&buf, sequencer_reflog_action(opts));3941if (sub_action)3942strbuf_addf(&buf, " (%s)", sub_action);3943if (fmt) {3944strbuf_addstr(&buf, ": ");3945strbuf_vaddf(&buf, fmt, ap);3946}3947va_end(ap);3948
3949return buf.buf;3950}
3951
3952static struct commit *lookup_label(struct repository *r, const char *label,3953int len, struct strbuf *buf)3954{
3955struct commit *commit;3956struct object_id oid;3957
3958strbuf_reset(buf);3959strbuf_addf(buf, "refs/rewritten/%.*s", len, label);3960if (!refs_read_ref(get_main_ref_store(the_repository), buf->buf, &oid)) {3961commit = lookup_commit_object(r, &oid);3962} else {3963/* fall back to non-rewritten ref or commit */3964strbuf_splice(buf, 0, strlen("refs/rewritten/"), "", 0);3965commit = lookup_commit_reference_by_name(buf->buf);3966}3967
3968if (!commit)3969error(_("could not resolve '%s'"), buf->buf);3970
3971return commit;3972}
3973
3974static int do_reset(struct repository *r,3975const char *name, int len,3976struct replay_opts *opts)3977{
3978struct strbuf ref_name = STRBUF_INIT;3979struct object_id oid;3980struct lock_file lock = LOCK_INIT;3981struct tree_desc desc = { 0 };3982struct tree *tree;3983struct unpack_trees_options unpack_tree_opts = { 0 };3984int ret = 0;3985
3986if (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0)3987return -1;3988
3989if (len == 10 && !strncmp("[new root]", name, len)) {3990if (!opts->have_squash_onto) {3991const char *hex;3992if (commit_tree("", 0, the_hash_algo->empty_tree,3993NULL, &opts->squash_onto,3994NULL, NULL))3995return error(_("writing fake root commit"));3996opts->have_squash_onto = 1;3997hex = oid_to_hex(&opts->squash_onto);3998if (write_message(hex, strlen(hex),3999rebase_path_squash_onto(), 0))4000return error(_("writing squash-onto"));4001}4002oidcpy(&oid, &opts->squash_onto);4003} else {4004int i;4005struct commit *commit;4006
4007/* Determine the length of the label */4008for (i = 0; i < len; i++)4009if (isspace(name[i]))4010break;4011len = i;4012
4013commit = lookup_label(r, name, len, &ref_name);4014if (!commit) {4015ret = -1;4016goto cleanup;4017}4018oid = commit->object.oid;4019}4020
4021setup_unpack_trees_porcelain(&unpack_tree_opts, "reset");4022unpack_tree_opts.head_idx = 1;4023unpack_tree_opts.src_index = r->index;4024unpack_tree_opts.dst_index = r->index;4025unpack_tree_opts.fn = oneway_merge;4026unpack_tree_opts.merge = 1;4027unpack_tree_opts.update = 1;4028unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */4029unpack_tree_opts.skip_cache_tree_update = 1;4030init_checkout_metadata(&unpack_tree_opts.meta, name, &oid, NULL);4031
4032if (repo_read_index_unmerged(r)) {4033ret = error_resolve_conflict(action_name(opts));4034goto cleanup;4035}4036
4037if (!fill_tree_descriptor(r, &desc, &oid)) {4038ret = error(_("failed to find tree of %s"), oid_to_hex(&oid));4039goto cleanup;4040}4041
4042if (unpack_trees(1, &desc, &unpack_tree_opts)) {4043ret = -1;4044goto cleanup;4045}4046
4047tree = parse_tree_indirect(&oid);4048if (!tree)4049return error(_("unable to read tree (%s)"), oid_to_hex(&oid));4050prime_cache_tree(r, r->index, tree);4051
4052if (write_locked_index(r->index, &lock, COMMIT_LOCK) < 0)4053ret = error(_("could not write index"));4054
4055if (!ret)4056ret = refs_update_ref(get_main_ref_store(the_repository), reflog_message(opts, "reset", "'%.*s'",4057len, name),4058"HEAD", &oid,4059NULL, 0, UPDATE_REFS_MSG_ON_ERR);4060cleanup:4061free((void *)desc.buffer);4062if (ret < 0)4063rollback_lock_file(&lock);4064strbuf_release(&ref_name);4065clear_unpack_trees_porcelain(&unpack_tree_opts);4066return ret;4067}
4068
4069static int do_merge(struct repository *r,4070struct commit *commit,4071const char *arg, int arg_len,4072int flags, int *check_todo, struct replay_opts *opts)4073{
4074struct replay_ctx *ctx = opts->ctx;4075int run_commit_flags = 0;4076struct strbuf ref_name = STRBUF_INIT;4077struct commit *head_commit, *merge_commit, *i;4078struct commit_list *bases = NULL, *j;4079struct commit_list *to_merge = NULL, **tail = &to_merge;4080const char *strategy = !opts->xopts.nr &&4081(!opts->strategy ||4082!strcmp(opts->strategy, "recursive") ||4083!strcmp(opts->strategy, "ort")) ?4084NULL : opts->strategy;4085struct merge_options o;4086int merge_arg_len, oneline_offset, can_fast_forward, ret, k;4087static struct lock_file lock;4088const char *p;4089
4090if (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0) {4091ret = -1;4092goto leave_merge;4093}4094
4095head_commit = lookup_commit_reference_by_name("HEAD");4096if (!head_commit) {4097ret = error(_("cannot merge without a current revision"));4098goto leave_merge;4099}4100
4101/*4102* For octopus merges, the arg starts with the list of revisions to be
4103* merged. The list is optionally followed by '#' and the oneline.
4104*/
4105merge_arg_len = oneline_offset = arg_len;4106for (p = arg; p - arg < arg_len; p += strspn(p, " \t\n")) {4107if (!*p)4108break;4109if (*p == '#' && (!p[1] || isspace(p[1]))) {4110p += 1 + strspn(p + 1, " \t\n");4111oneline_offset = p - arg;4112break;4113}4114k = strcspn(p, " \t\n");4115if (!k)4116continue;4117merge_commit = lookup_label(r, p, k, &ref_name);4118if (!merge_commit) {4119ret = error(_("unable to parse '%.*s'"), k, p);4120goto leave_merge;4121}4122tail = &commit_list_insert(merge_commit, tail)->next;4123p += k;4124merge_arg_len = p - arg;4125}4126
4127if (!to_merge) {4128ret = error(_("nothing to merge: '%.*s'"), arg_len, arg);4129goto leave_merge;4130}4131
4132if (opts->have_squash_onto &&4133oideq(&head_commit->object.oid, &opts->squash_onto)) {4134/*4135* When the user tells us to "merge" something into a
4136* "[new root]", let's simply fast-forward to the merge head.
4137*/
4138rollback_lock_file(&lock);4139if (to_merge->next)4140ret = error(_("octopus merge cannot be executed on "4141"top of a [new root]"));4142else4143ret = fast_forward_to(r, &to_merge->item->object.oid,4144&head_commit->object.oid, 0,4145opts);4146goto leave_merge;4147}4148
4149/*4150* If HEAD is not identical to the first parent of the original merge
4151* commit, we cannot fast-forward.
4152*/
4153can_fast_forward = opts->allow_ff && commit && commit->parents &&4154oideq(&commit->parents->item->object.oid,4155&head_commit->object.oid);4156
4157/*4158* If any merge head is different from the original one, we cannot
4159* fast-forward.
4160*/
4161if (can_fast_forward) {4162struct commit_list *p = commit->parents->next;4163
4164for (j = to_merge; j && p; j = j->next, p = p->next)4165if (!oideq(&j->item->object.oid,4166&p->item->object.oid)) {4167can_fast_forward = 0;4168break;4169}4170/*4171* If the number of merge heads differs from the original merge
4172* commit, we cannot fast-forward.
4173*/
4174if (j || p)4175can_fast_forward = 0;4176}4177
4178if (can_fast_forward) {4179rollback_lock_file(&lock);4180ret = fast_forward_to(r, &commit->object.oid,4181&head_commit->object.oid, 0, opts);4182if (flags & TODO_EDIT_MERGE_MSG)4183goto fast_forward_edit;4184
4185goto leave_merge;4186}4187
4188if (commit) {4189const char *encoding = get_commit_output_encoding();4190const char *message = repo_logmsg_reencode(r, commit, NULL,4191encoding);4192const char *body;4193int len;4194
4195if (!message) {4196ret = error(_("could not get commit message of '%s'"),4197oid_to_hex(&commit->object.oid));4198goto leave_merge;4199}4200write_author_script(message);4201find_commit_subject(message, &body);4202len = strlen(body);4203strbuf_add(&ctx->message, body, len);4204repo_unuse_commit_buffer(r, commit, message);4205} else {4206struct strbuf buf = STRBUF_INIT;4207
4208strbuf_addf(&buf, "author %s", git_author_info(0));4209write_author_script(buf.buf);4210strbuf_release(&buf);4211
4212if (oneline_offset < arg_len) {4213strbuf_add(&ctx->message, arg + oneline_offset,4214arg_len - oneline_offset);4215} else {4216strbuf_addf(&ctx->message, "Merge %s '%.*s'",4217to_merge->next ? "branches" : "branch",4218merge_arg_len, arg);4219}4220}4221ctx->have_message = 1;4222if (write_message(ctx->message.buf, ctx->message.len,4223git_path_merge_msg(r), 0)) {4224ret = error_errno(_("could not write '%s'"),4225git_path_merge_msg(r));4226goto leave_merge;4227}4228
4229if (strategy || to_merge->next) {4230/* Octopus merge */4231struct child_process cmd = CHILD_PROCESS_INIT;4232
4233if (read_env_script(&cmd.env)) {4234const char *gpg_opt = gpg_sign_opt_quoted(opts);4235
4236ret = error(_(staged_changes_advice), gpg_opt, gpg_opt);4237goto leave_merge;4238}4239
4240if (opts->committer_date_is_author_date)4241strvec_pushf(&cmd.env, "GIT_COMMITTER_DATE=%s",4242opts->ignore_date ?4243"" :4244author_date_from_env(&cmd.env));4245if (opts->ignore_date)4246strvec_push(&cmd.env, "GIT_AUTHOR_DATE=");4247
4248cmd.git_cmd = 1;4249strvec_push(&cmd.args, "merge");4250strvec_push(&cmd.args, "-s");4251if (!strategy)4252strvec_push(&cmd.args, "octopus");4253else {4254strvec_push(&cmd.args, strategy);4255for (k = 0; k < opts->xopts.nr; k++)4256strvec_pushf(&cmd.args,4257"-X%s", opts->xopts.v[k]);4258}4259if (!(flags & TODO_EDIT_MERGE_MSG))4260strvec_push(&cmd.args, "--no-edit");4261else4262strvec_push(&cmd.args, "--edit");4263strvec_push(&cmd.args, "--no-ff");4264strvec_push(&cmd.args, "--no-log");4265strvec_push(&cmd.args, "--no-stat");4266strvec_push(&cmd.args, "-F");4267strvec_push(&cmd.args, git_path_merge_msg(r));4268if (opts->gpg_sign)4269strvec_pushf(&cmd.args, "-S%s", opts->gpg_sign);4270else4271strvec_push(&cmd.args, "--no-gpg-sign");4272
4273/* Add the tips to be merged */4274for (j = to_merge; j; j = j->next)4275strvec_push(&cmd.args,4276oid_to_hex(&j->item->object.oid));4277
4278strbuf_release(&ref_name);4279refs_delete_ref(get_main_ref_store(r), "", "CHERRY_PICK_HEAD",4280NULL, REF_NO_DEREF);4281rollback_lock_file(&lock);4282
4283ret = run_command(&cmd);4284
4285/* force re-reading of the cache */4286if (!ret) {4287discard_index(r->index);4288if (repo_read_index(r) < 0)4289ret = error(_("could not read index"));4290}4291goto leave_merge;4292}4293
4294merge_commit = to_merge->item;4295if (repo_get_merge_bases(r, head_commit, merge_commit, &bases) < 0) {4296ret = -1;4297goto leave_merge;4298}4299
4300if (bases && oideq(&merge_commit->object.oid,4301&bases->item->object.oid)) {4302ret = 0;4303/* skip merging an ancestor of HEAD */4304goto leave_merge;4305}4306
4307write_message(oid_to_hex(&merge_commit->object.oid), the_hash_algo->hexsz,4308git_path_merge_head(r), 0);4309write_message("no-ff", 5, git_path_merge_mode(r), 0);4310
4311bases = reverse_commit_list(bases);4312
4313repo_read_index(r);4314init_ui_merge_options(&o, r);4315o.branch1 = "HEAD";4316o.branch2 = ref_name.buf;4317o.buffer_output = 2;4318
4319if (!opts->strategy || !strcmp(opts->strategy, "ort")) {4320/*4321* TODO: Should use merge_incore_recursive() and
4322* merge_switch_to_result(), skipping the call to
4323* merge_switch_to_result() when we don't actually need to
4324* update the index and working copy immediately.
4325*/
4326ret = merge_ort_recursive(&o,4327head_commit, merge_commit, bases,4328&i);4329} else {4330ret = merge_recursive(&o, head_commit, merge_commit, bases,4331&i);4332}4333if (ret <= 0)4334fputs(o.obuf.buf, stdout);4335strbuf_release(&o.obuf);4336if (ret < 0) {4337error(_("could not even attempt to merge '%.*s'"),4338merge_arg_len, arg);4339unlink(git_path_merge_msg(r));4340goto leave_merge;4341}4342/*4343* The return value of merge_recursive() is 1 on clean, and 0 on
4344* unclean merge.
4345*
4346* Let's reverse that, so that do_merge() returns 0 upon success and
4347* 1 upon failed merge (keeping the return value -1 for the cases where
4348* we will want to reschedule the `merge` command).
4349*/
4350ret = !ret;4351
4352if (r->index->cache_changed &&4353write_locked_index(r->index, &lock, COMMIT_LOCK)) {4354ret = error(_("merge: Unable to write new index file"));4355goto leave_merge;4356}4357
4358rollback_lock_file(&lock);4359if (ret)4360repo_rerere(r, opts->allow_rerere_auto);4361else4362/*4363* In case of problems, we now want to return a positive
4364* value (a negative one would indicate that the `merge`
4365* command needs to be rescheduled).
4366*/
4367ret = !!run_git_commit(git_path_merge_msg(r), opts,4368run_commit_flags);4369
4370if (!ret && flags & TODO_EDIT_MERGE_MSG) {4371fast_forward_edit:4372*check_todo = 1;4373run_commit_flags |= AMEND_MSG | EDIT_MSG | VERIFY_MSG;4374ret = !!run_git_commit(NULL, opts, run_commit_flags);4375}4376
4377
4378leave_merge:4379strbuf_release(&ref_name);4380rollback_lock_file(&lock);4381free_commit_list(to_merge);4382free_commit_list(bases);4383return ret;4384}
4385
4386static int write_update_refs_state(struct string_list *refs_to_oids)4387{
4388int result = 0;4389struct lock_file lock = LOCK_INIT;4390FILE *fp = NULL;4391struct string_list_item *item;4392char *path;4393
4394path = rebase_path_update_refs(the_repository->gitdir);4395
4396if (!refs_to_oids->nr) {4397if (unlink(path) && errno != ENOENT)4398result = error_errno(_("could not unlink: %s"), path);4399goto cleanup;4400}4401
4402if (safe_create_leading_directories(path)) {4403result = error(_("unable to create leading directories of %s"),4404path);4405goto cleanup;4406}4407
4408if (hold_lock_file_for_update(&lock, path, 0) < 0) {4409result = error(_("another 'rebase' process appears to be running; "4410"'%s.lock' already exists"),4411path);4412goto cleanup;4413}4414
4415fp = fdopen_lock_file(&lock, "w");4416if (!fp) {4417result = error_errno(_("could not open '%s' for writing"), path);4418rollback_lock_file(&lock);4419goto cleanup;4420}4421
4422for_each_string_list_item(item, refs_to_oids) {4423struct update_ref_record *rec = item->util;4424fprintf(fp, "%s\n%s\n%s\n", item->string,4425oid_to_hex(&rec->before), oid_to_hex(&rec->after));4426}4427
4428result = commit_lock_file(&lock);4429
4430cleanup:4431free(path);4432return result;4433}
4434
4435/*
4436* Parse the update-refs file for the current rebase, then remove the
4437* refs that do not appear in the todo_list (and have not had updated
4438* values stored) and add refs that are in the todo_list but not
4439* represented in the update-refs file.
4440*
4441* If there are changes to the update-refs list, then write the new state
4442* to disk.
4443*/
4444void todo_list_filter_update_refs(struct repository *r,4445struct todo_list *todo_list)4446{
4447int i;4448int updated = 0;4449struct string_list update_refs = STRING_LIST_INIT_DUP;4450
4451sequencer_get_update_refs_state(r->gitdir, &update_refs);4452
4453/*4454* For each item in the update_refs list, if it has no updated
4455* value and does not appear in the todo_list, then remove it
4456* from the update_refs list.
4457*/
4458for (i = 0; i < update_refs.nr; i++) {4459int j;4460int found = 0;4461const char *ref = update_refs.items[i].string;4462size_t reflen = strlen(ref);4463struct update_ref_record *rec = update_refs.items[i].util;4464
4465/* OID already stored as updated. */4466if (!is_null_oid(&rec->after))4467continue;4468
4469for (j = 0; !found && j < todo_list->nr; j++) {4470struct todo_item *item = &todo_list->items[j];4471const char *arg = todo_list->buf.buf + item->arg_offset;4472
4473if (item->command != TODO_UPDATE_REF)4474continue;4475
4476if (item->arg_len != reflen ||4477strncmp(arg, ref, reflen))4478continue;4479
4480found = 1;4481}4482
4483if (!found) {4484free(update_refs.items[i].string);4485free(update_refs.items[i].util);4486
4487update_refs.nr--;4488MOVE_ARRAY(update_refs.items + i, update_refs.items + i + 1, update_refs.nr - i);4489
4490updated = 1;4491i--;4492}4493}4494
4495/*4496* For each todo_item, check if its ref is in the update_refs list.
4497* If not, then add it as an un-updated ref.
4498*/
4499for (i = 0; i < todo_list->nr; i++) {4500struct todo_item *item = &todo_list->items[i];4501const char *arg = todo_list->buf.buf + item->arg_offset;4502int j, found = 0;4503
4504if (item->command != TODO_UPDATE_REF)4505continue;4506
4507for (j = 0; !found && j < update_refs.nr; j++) {4508const char *ref = update_refs.items[j].string;4509
4510found = strlen(ref) == item->arg_len &&4511!strncmp(ref, arg, item->arg_len);4512}4513
4514if (!found) {4515struct string_list_item *inserted;4516struct strbuf argref = STRBUF_INIT;4517
4518strbuf_add(&argref, arg, item->arg_len);4519inserted = string_list_insert(&update_refs, argref.buf);4520inserted->util = init_update_ref_record(argref.buf);4521strbuf_release(&argref);4522updated = 1;4523}4524}4525
4526if (updated)4527write_update_refs_state(&update_refs);4528string_list_clear(&update_refs, 1);4529}
4530
4531static int do_update_ref(struct repository *r, const char *refname)4532{
4533struct string_list_item *item;4534struct string_list list = STRING_LIST_INIT_DUP;4535
4536if (sequencer_get_update_refs_state(r->gitdir, &list))4537return -1;4538
4539for_each_string_list_item(item, &list) {4540if (!strcmp(item->string, refname)) {4541struct update_ref_record *rec = item->util;4542if (refs_read_ref(get_main_ref_store(the_repository), "HEAD", &rec->after))4543return -1;4544break;4545}4546}4547
4548write_update_refs_state(&list);4549string_list_clear(&list, 1);4550return 0;4551}
4552
4553static int do_update_refs(struct repository *r, int quiet)4554{
4555int res = 0;4556struct string_list_item *item;4557struct string_list refs_to_oids = STRING_LIST_INIT_DUP;4558struct ref_store *refs = get_main_ref_store(r);4559struct strbuf update_msg = STRBUF_INIT;4560struct strbuf error_msg = STRBUF_INIT;4561
4562if ((res = sequencer_get_update_refs_state(r->gitdir, &refs_to_oids)))4563return res;4564
4565for_each_string_list_item(item, &refs_to_oids) {4566struct update_ref_record *rec = item->util;4567int loop_res;4568
4569loop_res = refs_update_ref(refs, "rewritten during rebase",4570item->string,4571&rec->after, &rec->before,45720, UPDATE_REFS_MSG_ON_ERR);4573res |= loop_res;4574
4575if (quiet)4576continue;4577
4578if (loop_res)4579strbuf_addf(&error_msg, "\t%s\n", item->string);4580else4581strbuf_addf(&update_msg, "\t%s\n", item->string);4582}4583
4584if (!quiet &&4585(update_msg.len || error_msg.len)) {4586fprintf(stderr,4587_("Updated the following refs with %s:\n%s"),4588"--update-refs",4589update_msg.buf);4590
4591if (res)4592fprintf(stderr,4593_("Failed to update the following refs with %s:\n%s"),4594"--update-refs",4595error_msg.buf);4596}4597
4598string_list_clear(&refs_to_oids, 1);4599strbuf_release(&update_msg);4600strbuf_release(&error_msg);4601return res;4602}
4603
4604static int is_final_fixup(struct todo_list *todo_list)4605{
4606int i = todo_list->current;4607
4608if (!is_fixup(todo_list->items[i].command))4609return 0;4610
4611while (++i < todo_list->nr)4612if (is_fixup(todo_list->items[i].command))4613return 0;4614else if (!is_noop(todo_list->items[i].command))4615break;4616return 1;4617}
4618
4619static enum todo_command peek_command(struct todo_list *todo_list, int offset)4620{
4621int i;4622
4623for (i = todo_list->current + offset; i < todo_list->nr; i++)4624if (!is_noop(todo_list->items[i].command))4625return todo_list->items[i].command;4626
4627return -1;4628}
4629
4630static void create_autostash_internal(struct repository *r,4631const char *path,4632const char *refname)4633{
4634struct strbuf buf = STRBUF_INIT;4635struct lock_file lock_file = LOCK_INIT;4636int fd;4637
4638if (path && refname)4639BUG("can only pass path or refname");4640
4641fd = repo_hold_locked_index(r, &lock_file, 0);4642refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);4643if (0 <= fd)4644repo_update_index_if_able(r, &lock_file);4645rollback_lock_file(&lock_file);4646
4647if (has_unstaged_changes(r, 1) ||4648has_uncommitted_changes(r, 1)) {4649struct child_process stash = CHILD_PROCESS_INIT;4650struct reset_head_opts ropts = { .flags = RESET_HEAD_HARD };4651struct object_id oid;4652
4653strvec_pushl(&stash.args,4654"stash", "create", "autostash", NULL);4655stash.git_cmd = 1;4656stash.no_stdin = 1;4657strbuf_reset(&buf);4658if (capture_command(&stash, &buf, GIT_MAX_HEXSZ))4659die(_("Cannot autostash"));4660strbuf_trim_trailing_newline(&buf);4661if (repo_get_oid(r, buf.buf, &oid))4662die(_("Unexpected stash response: '%s'"),4663buf.buf);4664strbuf_reset(&buf);4665strbuf_add_unique_abbrev(&buf, &oid, DEFAULT_ABBREV);4666
4667if (path) {4668if (safe_create_leading_directories_const(path))4669die(_("Could not create directory for '%s'"),4670path);4671write_file(path, "%s", oid_to_hex(&oid));4672} else {4673refs_update_ref(get_main_ref_store(r), "", refname,4674&oid, null_oid(), 0, UPDATE_REFS_DIE_ON_ERR);4675}4676
4677printf(_("Created autostash: %s\n"), buf.buf);4678if (reset_head(r, &ropts) < 0)4679die(_("could not reset --hard"));4680discard_index(r->index);4681if (repo_read_index(r) < 0)4682die(_("could not read index"));4683}4684strbuf_release(&buf);4685}
4686
4687void create_autostash(struct repository *r, const char *path)4688{
4689create_autostash_internal(r, path, NULL);4690}
4691
4692void create_autostash_ref(struct repository *r, const char *refname)4693{
4694create_autostash_internal(r, NULL, refname);4695}
4696
4697static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply)4698{
4699struct child_process child = CHILD_PROCESS_INIT;4700int ret = 0;4701
4702if (attempt_apply) {4703child.git_cmd = 1;4704child.no_stdout = 1;4705child.no_stderr = 1;4706strvec_push(&child.args, "stash");4707strvec_push(&child.args, "apply");4708strvec_push(&child.args, stash_oid);4709ret = run_command(&child);4710}4711
4712if (attempt_apply && !ret)4713fprintf(stderr, _("Applied autostash.\n"));4714else {4715struct child_process store = CHILD_PROCESS_INIT;4716
4717store.git_cmd = 1;4718strvec_push(&store.args, "stash");4719strvec_push(&store.args, "store");4720strvec_push(&store.args, "-m");4721strvec_push(&store.args, "autostash");4722strvec_push(&store.args, "-q");4723strvec_push(&store.args, stash_oid);4724if (run_command(&store))4725ret = error(_("cannot store %s"), stash_oid);4726else4727fprintf(stderr,4728_("%s\n"4729"Your changes are safe in the stash.\n"4730"You can run \"git stash pop\" or"4731" \"git stash drop\" at any time.\n"),4732attempt_apply ?4733_("Applying autostash resulted in conflicts.") :4734_("Autostash exists; creating a new stash entry."));4735}4736
4737return ret;4738}
4739
4740static int apply_save_autostash(const char *path, int attempt_apply)4741{
4742struct strbuf stash_oid = STRBUF_INIT;4743int ret = 0;4744
4745if (!read_oneliner(&stash_oid, path,4746READ_ONELINER_SKIP_IF_EMPTY)) {4747strbuf_release(&stash_oid);4748return 0;4749}4750strbuf_trim(&stash_oid);4751
4752ret = apply_save_autostash_oid(stash_oid.buf, attempt_apply);4753
4754unlink(path);4755strbuf_release(&stash_oid);4756return ret;4757}
4758
4759int save_autostash(const char *path)4760{
4761return apply_save_autostash(path, 0);4762}
4763
4764int apply_autostash(const char *path)4765{
4766return apply_save_autostash(path, 1);4767}
4768
4769int apply_autostash_oid(const char *stash_oid)4770{
4771return apply_save_autostash_oid(stash_oid, 1);4772}
4773
4774static int apply_save_autostash_ref(struct repository *r, const char *refname,4775int attempt_apply)4776{
4777struct object_id stash_oid;4778char stash_oid_hex[GIT_MAX_HEXSZ + 1];4779int flag, ret;4780
4781if (!refs_ref_exists(get_main_ref_store(r), refname))4782return 0;4783
4784if (!refs_resolve_ref_unsafe(get_main_ref_store(r), refname,4785RESOLVE_REF_READING, &stash_oid, &flag))4786return -1;4787if (flag & REF_ISSYMREF)4788return error(_("autostash reference is a symref"));4789
4790oid_to_hex_r(stash_oid_hex, &stash_oid);4791ret = apply_save_autostash_oid(stash_oid_hex, attempt_apply);4792
4793refs_delete_ref(get_main_ref_store(r), "", refname,4794&stash_oid, REF_NO_DEREF);4795
4796return ret;4797}
4798
4799int save_autostash_ref(struct repository *r, const char *refname)4800{
4801return apply_save_autostash_ref(r, refname, 0);4802}
4803
4804int apply_autostash_ref(struct repository *r, const char *refname)4805{
4806return apply_save_autostash_ref(r, refname, 1);4807}
4808
4809static int checkout_onto(struct repository *r, struct replay_opts *opts,4810const char *onto_name, const struct object_id *onto,4811const struct object_id *orig_head)4812{
4813struct reset_head_opts ropts = {4814.oid = onto,4815.orig_head = orig_head,4816.flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD |4817RESET_HEAD_RUN_POST_CHECKOUT_HOOK,4818.head_msg = reflog_message(opts, "start", "checkout %s",4819onto_name),4820.default_reflog_action = sequencer_reflog_action(opts)4821};4822if (reset_head(r, &ropts)) {4823apply_autostash(rebase_path_autostash());4824sequencer_remove_state(opts);4825return error(_("could not detach HEAD"));4826}4827
4828return 0;4829}
4830
4831static int stopped_at_head(struct repository *r)4832{
4833struct object_id head;4834struct commit *commit;4835struct commit_message message;4836
4837if (repo_get_oid(r, "HEAD", &head) ||4838!(commit = lookup_commit(r, &head)) ||4839repo_parse_commit(r, commit) || get_message(commit, &message))4840fprintf(stderr, _("Stopped at HEAD\n"));4841else {4842fprintf(stderr, _("Stopped at %s\n"), message.label);4843free_message(commit, &message);4844}4845return 0;4846
4847}
4848
4849static int reread_todo_if_changed(struct repository *r,4850struct todo_list *todo_list,4851struct replay_opts *opts)4852{
4853int offset;4854struct strbuf buf = STRBUF_INIT;4855
4856if (strbuf_read_file_or_whine(&buf, get_todo_path(opts)) < 0)4857return -1;4858offset = get_item_line_offset(todo_list, todo_list->current + 1);4859if (buf.len != todo_list->buf.len - offset ||4860memcmp(buf.buf, todo_list->buf.buf + offset, buf.len)) {4861/* Reread the todo file if it has changed. */4862todo_list_release(todo_list);4863if (read_populate_todo(r, todo_list, opts))4864return -1; /* message was printed */4865/* `current` will be incremented on return */4866todo_list->current = -1;4867}4868strbuf_release(&buf);4869
4870return 0;4871}
4872
4873static const char rescheduled_advice[] =4874N_("Could not execute the todo command\n"4875"\n"
4876" %.*s"
4877"\n"
4878"It has been rescheduled; To edit the command before continuing, please\n"
4879"edit the todo list first:\n"
4880"\n"
4881" git rebase --edit-todo\n"
4882" git rebase --continue\n");4883
4884static int pick_one_commit(struct repository *r,4885struct todo_list *todo_list,4886struct replay_opts *opts,4887int *check_todo, int* reschedule)4888{
4889struct replay_ctx *ctx = opts->ctx;4890int res;4891struct todo_item *item = todo_list->items + todo_list->current;4892const char *arg = todo_item_get_arg(todo_list, item);4893if (is_rebase_i(opts))4894ctx->reflog_message = reflog_message(4895opts, command_to_string(item->command), NULL);4896
4897res = do_pick_commit(r, item, opts, is_final_fixup(todo_list),4898check_todo);4899if (is_rebase_i(opts) && res < 0) {4900/* Reschedule */4901*reschedule = 1;4902return -1;4903}4904if (item->command == TODO_EDIT) {4905struct commit *commit = item->commit;4906if (!res) {4907if (!opts->verbose)4908term_clear_line();4909fprintf(stderr, _("Stopped at %s... %.*s\n"),4910short_commit_name(r, commit), item->arg_len, arg);4911}4912return error_with_patch(r, commit,4913arg, item->arg_len, opts, res, !res);4914}4915if (is_rebase_i(opts) && !res)4916record_in_rewritten(&item->commit->object.oid,4917peek_command(todo_list, 1));4918if (res && is_fixup(item->command)) {4919if (res == 1)4920intend_to_amend();4921return error_failed_squash(r, item->commit, opts,4922item->arg_len, arg);4923} else if (res && is_rebase_i(opts) && item->commit) {4924int to_amend = 0;4925struct object_id oid;4926
4927/*4928* If we are rewording and have either
4929* fast-forwarded already, or are about to
4930* create a new root commit, we want to amend,
4931* otherwise we do not.
4932*/
4933if (item->command == TODO_REWORD &&4934!repo_get_oid(r, "HEAD", &oid) &&4935(oideq(&item->commit->object.oid, &oid) ||4936(opts->have_squash_onto &&4937oideq(&opts->squash_onto, &oid))))4938to_amend = 1;4939
4940return res | error_with_patch(r, item->commit,4941arg, item->arg_len, opts,4942res, to_amend);4943}4944return res;4945}
4946
4947static int pick_commits(struct repository *r,4948struct todo_list *todo_list,4949struct replay_opts *opts)4950{
4951struct replay_ctx *ctx = opts->ctx;4952int res = 0, reschedule = 0;4953
4954ctx->reflog_message = sequencer_reflog_action(opts);4955if (opts->allow_ff)4956assert(!(opts->signoff || opts->no_commit ||4957opts->record_origin || should_edit(opts) ||4958opts->committer_date_is_author_date ||4959opts->ignore_date));4960if (read_and_refresh_cache(r, opts))4961return -1;4962
4963unlink(rebase_path_message());4964unlink(rebase_path_stopped_sha());4965unlink(rebase_path_amend());4966unlink(rebase_path_patch());4967
4968while (todo_list->current < todo_list->nr) {4969struct todo_item *item = todo_list->items + todo_list->current;4970const char *arg = todo_item_get_arg(todo_list, item);4971int check_todo = 0;4972
4973if (save_todo(todo_list, opts, reschedule))4974return -1;4975if (is_rebase_i(opts)) {4976if (item->command != TODO_COMMENT) {4977FILE *f = fopen(rebase_path_msgnum(), "w");4978
4979todo_list->done_nr++;4980
4981if (f) {4982fprintf(f, "%d\n", todo_list->done_nr);4983fclose(f);4984}4985if (!opts->quiet)4986fprintf(stderr, _("Rebasing (%d/%d)%s"),4987todo_list->done_nr,4988todo_list->total_nr,4989opts->verbose ? "\n" : "\r");4990}4991unlink(rebase_path_author_script());4992unlink(git_path_merge_head(r));4993refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",4994NULL, REF_NO_DEREF);4995refs_delete_ref(get_main_ref_store(r), "", "REBASE_HEAD",4996NULL, REF_NO_DEREF);4997
4998if (item->command == TODO_BREAK) {4999if (!opts->verbose)5000term_clear_line();5001return stopped_at_head(r);5002}5003}5004strbuf_reset(&ctx->message);5005ctx->have_message = 0;5006if (item->command <= TODO_SQUASH) {5007res = pick_one_commit(r, todo_list, opts, &check_todo,5008&reschedule);5009if (!res && item->command == TODO_EDIT)5010return 0;5011} else if (item->command == TODO_EXEC) {5012char *end_of_arg = (char *)(arg + item->arg_len);5013int saved = *end_of_arg;5014
5015if (!opts->verbose)5016term_clear_line();5017*end_of_arg = '\0';5018res = do_exec(r, arg, opts->quiet);5019*end_of_arg = saved;5020
5021if (res) {5022if (opts->reschedule_failed_exec)5023reschedule = 1;5024}5025check_todo = 1;5026} else if (item->command == TODO_LABEL) {5027if ((res = do_label(r, arg, item->arg_len)))5028reschedule = 1;5029} else if (item->command == TODO_RESET) {5030if ((res = do_reset(r, arg, item->arg_len, opts)))5031reschedule = 1;5032} else if (item->command == TODO_MERGE) {5033if ((res = do_merge(r, item->commit, arg, item->arg_len,5034item->flags, &check_todo, opts)) < 0)5035reschedule = 1;5036else if (item->commit)5037record_in_rewritten(&item->commit->object.oid,5038peek_command(todo_list, 1));5039if (res > 0)5040/* failed with merge conflicts */5041return error_with_patch(r, item->commit,5042arg, item->arg_len,5043opts, res, 0);5044} else if (item->command == TODO_UPDATE_REF) {5045struct strbuf ref = STRBUF_INIT;5046strbuf_add(&ref, arg, item->arg_len);5047if ((res = do_update_ref(r, ref.buf)))5048reschedule = 1;5049strbuf_release(&ref);5050} else if (!is_noop(item->command))5051return error(_("unknown command %d"), item->command);5052
5053if (reschedule) {5054advise(_(rescheduled_advice),5055get_item_line_length(todo_list,5056todo_list->current),5057get_item_line(todo_list, todo_list->current));5058if (save_todo(todo_list, opts, reschedule))5059return -1;5060if (item->commit)5061write_rebase_head(&item->commit->object.oid);5062} else if (is_rebase_i(opts) && check_todo && !res &&5063reread_todo_if_changed(r, todo_list, opts)) {5064return -1;5065}5066
5067if (res)5068return res;5069
5070todo_list->current++;5071}5072
5073if (is_rebase_i(opts)) {5074struct strbuf head_ref = STRBUF_INIT, buf = STRBUF_INIT;5075struct stat st;5076
5077if (read_oneliner(&head_ref, rebase_path_head_name(), 0) &&5078starts_with(head_ref.buf, "refs/")) {5079const char *msg;5080struct object_id head, orig;5081int res;5082
5083if (repo_get_oid(r, "HEAD", &head)) {5084res = error(_("cannot read HEAD"));5085cleanup_head_ref:5086strbuf_release(&head_ref);5087strbuf_release(&buf);5088return res;5089}5090if (!read_oneliner(&buf, rebase_path_orig_head(), 0) ||5091get_oid_hex(buf.buf, &orig)) {5092res = error(_("could not read orig-head"));5093goto cleanup_head_ref;5094}5095strbuf_reset(&buf);5096if (!read_oneliner(&buf, rebase_path_onto(), 0)) {5097res = error(_("could not read 'onto'"));5098goto cleanup_head_ref;5099}5100msg = reflog_message(opts, "finish", "%s onto %s",5101head_ref.buf, buf.buf);5102if (refs_update_ref(get_main_ref_store(the_repository), msg, head_ref.buf, &head, &orig,5103REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR)) {5104res = error(_("could not update %s"),5105head_ref.buf);5106goto cleanup_head_ref;5107}5108msg = reflog_message(opts, "finish", "returning to %s",5109head_ref.buf);5110if (refs_update_symref(get_main_ref_store(the_repository), "HEAD", head_ref.buf, msg)) {5111res = error(_("could not update HEAD to %s"),5112head_ref.buf);5113goto cleanup_head_ref;5114}5115strbuf_reset(&buf);5116}5117
5118if (opts->verbose) {5119struct rev_info log_tree_opt;5120struct object_id orig, head;5121
5122memset(&log_tree_opt, 0, sizeof(log_tree_opt));5123repo_init_revisions(r, &log_tree_opt, NULL);5124log_tree_opt.diff = 1;5125log_tree_opt.diffopt.output_format =5126DIFF_FORMAT_DIFFSTAT;5127log_tree_opt.disable_stdin = 1;5128
5129if (read_oneliner(&buf, rebase_path_orig_head(), 0) &&5130!repo_get_oid(r, buf.buf, &orig) &&5131!repo_get_oid(r, "HEAD", &head)) {5132diff_tree_oid(&orig, &head, "",5133&log_tree_opt.diffopt);5134log_tree_diff_flush(&log_tree_opt);5135}5136release_revisions(&log_tree_opt);5137}5138flush_rewritten_pending();5139if (!stat(rebase_path_rewritten_list(), &st) &&5140st.st_size > 0) {5141struct child_process child = CHILD_PROCESS_INIT;5142struct run_hooks_opt hook_opt = RUN_HOOKS_OPT_INIT;5143
5144child.in = open(rebase_path_rewritten_list(), O_RDONLY);5145child.git_cmd = 1;5146strvec_push(&child.args, "notes");5147strvec_push(&child.args, "copy");5148strvec_push(&child.args, "--for-rewrite=rebase");5149/* we don't care if this copying failed */5150run_command(&child);5151
5152hook_opt.path_to_stdin = rebase_path_rewritten_list();5153strvec_push(&hook_opt.args, "rebase");5154run_hooks_opt(r, "post-rewrite", &hook_opt);5155}5156apply_autostash(rebase_path_autostash());5157
5158if (!opts->quiet) {5159if (!opts->verbose)5160term_clear_line();5161fprintf(stderr,5162_("Successfully rebased and updated %s.\n"),5163head_ref.buf);5164}5165
5166strbuf_release(&buf);5167strbuf_release(&head_ref);5168
5169if (do_update_refs(r, opts->quiet))5170return -1;5171}5172
5173/*5174* Sequence of picks finished successfully; cleanup by
5175* removing the .git/sequencer directory
5176*/
5177return sequencer_remove_state(opts);5178}
5179
5180static int continue_single_pick(struct repository *r, struct replay_opts *opts)5181{
5182struct child_process cmd = CHILD_PROCESS_INIT;5183
5184if (!refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD") &&5185!refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD"))5186return error(_("no cherry-pick or revert in progress"));5187
5188cmd.git_cmd = 1;5189strvec_push(&cmd.args, "commit");5190
5191/*5192* continue_single_pick() handles the case of recovering from a
5193* conflict. should_edit() doesn't handle that case; for a conflict,
5194* we want to edit if the user asked for it, or if they didn't specify
5195* and stdin is a tty.
5196*/
5197if (!opts->edit || (opts->edit < 0 && !isatty(0)))5198/*5199* Include --cleanup=strip as well because we don't want the
5200* "# Conflicts:" messages.
5201*/
5202strvec_pushl(&cmd.args, "--no-edit", "--cleanup=strip", NULL);5203
5204return run_command(&cmd);5205}
5206
5207static int commit_staged_changes(struct repository *r,5208struct replay_opts *opts,5209struct todo_list *todo_list)5210{
5211struct replay_ctx *ctx = opts->ctx;5212unsigned int flags = ALLOW_EMPTY | EDIT_MSG;5213unsigned int final_fixup = 0, is_clean;5214struct strbuf rev = STRBUF_INIT;5215int ret;5216
5217if (has_unstaged_changes(r, 1)) {5218ret = error(_("cannot rebase: You have unstaged changes."));5219goto out;5220}5221
5222is_clean = !has_uncommitted_changes(r, 0);5223
5224if (!is_clean && !file_exists(rebase_path_message())) {5225const char *gpg_opt = gpg_sign_opt_quoted(opts);5226ret = error(_(staged_changes_advice), gpg_opt, gpg_opt);5227goto out;5228}5229
5230if (file_exists(rebase_path_amend())) {5231struct object_id head, to_amend;5232
5233if (repo_get_oid(r, "HEAD", &head)) {5234ret = error(_("cannot amend non-existing commit"));5235goto out;5236}5237
5238if (!read_oneliner(&rev, rebase_path_amend(), 0)) {5239ret = error(_("invalid file: '%s'"), rebase_path_amend());5240goto out;5241}5242
5243if (get_oid_hex(rev.buf, &to_amend)) {5244ret = error(_("invalid contents: '%s'"),5245rebase_path_amend());5246goto out;5247}5248if (!is_clean && !oideq(&head, &to_amend)) {5249ret = error(_("\nYou have uncommitted changes in your "5250"working tree. Please, commit them\n"5251"first and then run 'git rebase "5252"--continue' again."));5253goto out;5254}5255/*5256* When skipping a failed fixup/squash, we need to edit the
5257* commit message, the current fixup list and count, and if it
5258* was the last fixup/squash in the chain, we need to clean up
5259* the commit message and if there was a squash, let the user
5260* edit it.
5261*/
5262if (!is_clean || !ctx->current_fixup_count)5263; /* this is not the final fixup */5264else if (!oideq(&head, &to_amend) ||5265!file_exists(rebase_path_stopped_sha())) {5266/* was a final fixup or squash done manually? */5267if (!is_fixup(peek_command(todo_list, 0))) {5268unlink(rebase_path_fixup_msg());5269unlink(rebase_path_squash_msg());5270unlink(rebase_path_current_fixups());5271strbuf_reset(&ctx->current_fixups);5272ctx->current_fixup_count = 0;5273}5274} else {5275/* we are in a fixup/squash chain */5276const char *p = ctx->current_fixups.buf;5277int len = ctx->current_fixups.len;5278
5279ctx->current_fixup_count--;5280if (!len)5281BUG("Incorrect current_fixups:\n%s", p);5282while (len && p[len - 1] != '\n')5283len--;5284strbuf_setlen(&ctx->current_fixups, len);5285if (write_message(p, len, rebase_path_current_fixups(),52860) < 0) {5287ret = error(_("could not write file: '%s'"),5288rebase_path_current_fixups());5289goto out;5290}5291
5292/*5293* If a fixup/squash in a fixup/squash chain failed, the
5294* commit message is already correct, no need to commit
5295* it again.
5296*
5297* Only if it is the final command in the fixup/squash
5298* chain, and only if the chain is longer than a single
5299* fixup/squash command (which was just skipped), do we
5300* actually need to re-commit with a cleaned up commit
5301* message.
5302*/
5303if (ctx->current_fixup_count > 0 &&5304!is_fixup(peek_command(todo_list, 0))) {5305final_fixup = 1;5306/*5307* If there was not a single "squash" in the
5308* chain, we only need to clean up the commit
5309* message, no need to bother the user with
5310* opening the commit message in the editor.
5311*/
5312if (!starts_with(p, "squash ") &&5313!strstr(p, "\nsquash "))5314flags = (flags & ~EDIT_MSG) | CLEANUP_MSG;5315} else if (is_fixup(peek_command(todo_list, 0))) {5316/*5317* We need to update the squash message to skip
5318* the latest commit message.
5319*/
5320struct commit *commit;5321const char *msg;5322const char *path = rebase_path_squash_msg();5323const char *encoding = get_commit_output_encoding();5324
5325if (parse_head(r, &commit)) {5326ret = error(_("could not parse HEAD"));5327goto out;5328}5329
5330p = repo_logmsg_reencode(r, commit, NULL, encoding);5331if (!p) {5332ret = error(_("could not parse commit %s"),5333oid_to_hex(&commit->object.oid));5334goto unuse_commit_buffer;5335}5336find_commit_subject(p, &msg);5337if (write_message(msg, strlen(msg), path, 0)) {5338ret = error(_("could not write file: "5339"'%s'"), path);5340goto unuse_commit_buffer;5341}5342
5343ret = 0;5344
5345unuse_commit_buffer:5346repo_unuse_commit_buffer(r, commit, p);5347if (ret)5348goto out;5349}5350}5351
5352flags |= AMEND_MSG;5353}5354
5355if (is_clean) {5356if (refs_ref_exists(get_main_ref_store(r),5357"CHERRY_PICK_HEAD") &&5358refs_delete_ref(get_main_ref_store(r), "",5359"CHERRY_PICK_HEAD", NULL, REF_NO_DEREF)) {5360ret = error(_("could not remove CHERRY_PICK_HEAD"));5361goto out;5362}5363
5364if (unlink(git_path_merge_msg(r)) && errno != ENOENT) {5365ret = error_errno(_("could not remove '%s'"),5366git_path_merge_msg(r));5367goto out;5368}5369
5370if (!final_fixup) {5371ret = 0;5372goto out;5373}5374}5375
5376if (run_git_commit(final_fixup ? NULL : rebase_path_message(),5377opts, flags)) {5378ret = error(_("could not commit staged changes."));5379goto out;5380}5381
5382unlink(rebase_path_amend());5383unlink(git_path_merge_head(r));5384refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",5385NULL, REF_NO_DEREF);5386if (final_fixup) {5387unlink(rebase_path_fixup_msg());5388unlink(rebase_path_squash_msg());5389}5390if (ctx->current_fixup_count > 0) {5391/*5392* Whether final fixup or not, we just cleaned up the commit
5393* message...
5394*/
5395unlink(rebase_path_current_fixups());5396strbuf_reset(&ctx->current_fixups);5397ctx->current_fixup_count = 0;5398}5399
5400ret = 0;5401
5402out:5403strbuf_release(&rev);5404return ret;5405}
5406
5407int sequencer_continue(struct repository *r, struct replay_opts *opts)5408{
5409struct replay_ctx *ctx = opts->ctx;5410struct todo_list todo_list = TODO_LIST_INIT;5411int res;5412
5413if (read_and_refresh_cache(r, opts))5414return -1;5415
5416if (read_populate_opts(opts))5417return -1;5418if (is_rebase_i(opts)) {5419if ((res = read_populate_todo(r, &todo_list, opts)))5420goto release_todo_list;5421
5422if (file_exists(rebase_path_dropped())) {5423if ((res = todo_list_check_against_backup(r, opts,5424&todo_list)))5425goto release_todo_list;5426
5427unlink(rebase_path_dropped());5428}5429
5430ctx->reflog_message = reflog_message(opts, "continue", NULL);5431if (commit_staged_changes(r, opts, &todo_list)) {5432res = -1;5433goto release_todo_list;5434}5435} else if (!file_exists(get_todo_path(opts)))5436return continue_single_pick(r, opts);5437else if ((res = read_populate_todo(r, &todo_list, opts)))5438goto release_todo_list;5439
5440if (!is_rebase_i(opts)) {5441/* Verify that the conflict has been resolved */5442if (refs_ref_exists(get_main_ref_store(r),5443"CHERRY_PICK_HEAD") ||5444refs_ref_exists(get_main_ref_store(r), "REVERT_HEAD")) {5445res = continue_single_pick(r, opts);5446if (res)5447goto release_todo_list;5448}5449if (index_differs_from(r, "HEAD", NULL, 0)) {5450res = error_dirty_index(r, opts);5451goto release_todo_list;5452}5453todo_list.current++;5454} else if (file_exists(rebase_path_stopped_sha())) {5455struct strbuf buf = STRBUF_INIT;5456struct object_id oid;5457
5458if (read_oneliner(&buf, rebase_path_stopped_sha(),5459READ_ONELINER_SKIP_IF_EMPTY) &&5460!get_oid_hex(buf.buf, &oid))5461record_in_rewritten(&oid, peek_command(&todo_list, 0));5462strbuf_release(&buf);5463}5464
5465res = pick_commits(r, &todo_list, opts);5466release_todo_list:5467todo_list_release(&todo_list);5468return res;5469}
5470
5471static int single_pick(struct repository *r,5472struct commit *cmit,5473struct replay_opts *opts)5474{
5475int check_todo;5476struct todo_item item;5477
5478item.command = opts->action == REPLAY_PICK ?5479TODO_PICK : TODO_REVERT;5480item.commit = cmit;5481
5482opts->ctx->reflog_message = sequencer_reflog_action(opts);5483return do_pick_commit(r, &item, opts, 0, &check_todo);5484}
5485
5486int sequencer_pick_revisions(struct repository *r,5487struct replay_opts *opts)5488{
5489struct todo_list todo_list = TODO_LIST_INIT;5490struct object_id oid;5491int i, res;5492
5493assert(opts->revs);5494if (read_and_refresh_cache(r, opts)) {5495res = -1;5496goto out;5497}5498
5499for (i = 0; i < opts->revs->pending.nr; i++) {5500struct object_id oid;5501const char *name = opts->revs->pending.objects[i].name;5502
5503/* This happens when using --stdin. */5504if (!strlen(name))5505continue;5506
5507if (!repo_get_oid(r, name, &oid)) {5508if (!lookup_commit_reference_gently(r, &oid, 1)) {5509enum object_type type = oid_object_info(r,5510&oid,5511NULL);5512res = error(_("%s: can't cherry-pick a %s"),5513name, type_name(type));5514goto out;5515}5516} else {5517res = error(_("%s: bad revision"), name);5518goto out;5519}5520}5521
5522/*5523* If we were called as "git cherry-pick <commit>", just
5524* cherry-pick/revert it, set CHERRY_PICK_HEAD /
5525* REVERT_HEAD, and don't touch the sequencer state.
5526* This means it is possible to cherry-pick in the middle
5527* of a cherry-pick sequence.
5528*/
5529if (opts->revs->cmdline.nr == 1 &&5530opts->revs->cmdline.rev->whence == REV_CMD_REV &&5531opts->revs->no_walk &&5532!opts->revs->cmdline.rev->flags) {5533struct commit *cmit;5534
5535if (prepare_revision_walk(opts->revs)) {5536res = error(_("revision walk setup failed"));5537goto out;5538}5539
5540cmit = get_revision(opts->revs);5541if (!cmit) {5542res = error(_("empty commit set passed"));5543goto out;5544}5545
5546if (get_revision(opts->revs))5547BUG("unexpected extra commit from walk");5548
5549res = single_pick(r, cmit, opts);5550goto out;5551}5552
5553/*5554* Start a new cherry-pick/ revert sequence; but
5555* first, make sure that an existing one isn't in
5556* progress
5557*/
5558
5559if (walk_revs_populate_todo(&todo_list, opts) ||5560create_seq_dir(r) < 0) {5561res = -1;5562goto out;5563}5564
5565if (repo_get_oid(r, "HEAD", &oid) && (opts->action == REPLAY_REVERT)) {5566res = error(_("can't revert as initial commit"));5567goto out;5568}5569
5570if (save_head(oid_to_hex(&oid))) {5571res = -1;5572goto out;5573}5574
5575if (save_opts(opts)) {5576res = -1;5577goto out;5578}5579
5580update_abort_safety_file();5581res = pick_commits(r, &todo_list, opts);5582
5583out:5584todo_list_release(&todo_list);5585return res;5586}
5587
5588void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)5589{
5590unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;5591struct strbuf sob = STRBUF_INIT;5592int has_footer;5593
5594strbuf_addstr(&sob, sign_off_header);5595strbuf_addstr(&sob, fmt_name(WANT_COMMITTER_IDENT));5596strbuf_addch(&sob, '\n');5597
5598if (!ignore_footer)5599strbuf_complete_line(msgbuf);5600
5601/*5602* If the whole message buffer is equal to the sob, pretend that we
5603* found a conforming footer with a matching sob
5604*/
5605if (msgbuf->len - ignore_footer == sob.len &&5606!strncmp(msgbuf->buf, sob.buf, sob.len))5607has_footer = 3;5608else5609has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer);5610
5611if (!has_footer) {5612const char *append_newlines = NULL;5613size_t len = msgbuf->len - ignore_footer;5614
5615if (!len) {5616/*5617* The buffer is completely empty. Leave foom for
5618* the title and body to be filled in by the user.
5619*/
5620append_newlines = "\n\n";5621} else if (len == 1) {5622/*5623* Buffer contains a single newline. Add another
5624* so that we leave room for the title and body.
5625*/
5626append_newlines = "\n";5627} else if (msgbuf->buf[len - 2] != '\n') {5628/*5629* Buffer ends with a single newline. Add another
5630* so that there is an empty line between the message
5631* body and the sob.
5632*/
5633append_newlines = "\n";5634} /* else, the buffer already ends with two newlines. */5635
5636if (append_newlines)5637strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,5638append_newlines, strlen(append_newlines));5639}5640
5641if (has_footer != 3 && (!no_dup_sob || has_footer != 2))5642strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,5643sob.buf, sob.len);5644
5645strbuf_release(&sob);5646}
5647
5648struct labels_entry {5649struct hashmap_entry entry;5650char label[FLEX_ARRAY];5651};5652
5653static int labels_cmp(const void *fndata UNUSED,5654const struct hashmap_entry *eptr,5655const struct hashmap_entry *entry_or_key, const void *key)5656{
5657const struct labels_entry *a, *b;5658
5659a = container_of(eptr, const struct labels_entry, entry);5660b = container_of(entry_or_key, const struct labels_entry, entry);5661
5662return key ? strcmp(a->label, key) : strcmp(a->label, b->label);5663}
5664
5665struct string_entry {5666struct oidmap_entry entry;5667char string[FLEX_ARRAY];5668};5669
5670struct label_state {5671struct oidmap commit2label;5672struct hashmap labels;5673struct strbuf buf;5674int max_label_length;5675};5676
5677static const char *label_oid(struct object_id *oid, const char *label,5678struct label_state *state)5679{
5680struct labels_entry *labels_entry;5681struct string_entry *string_entry;5682struct object_id dummy;5683int i;5684
5685string_entry = oidmap_get(&state->commit2label, oid);5686if (string_entry)5687return string_entry->string;5688
5689/*5690* For "uninteresting" commits, i.e. commits that are not to be
5691* rebased, and which can therefore not be labeled, we use a unique
5692* abbreviation of the commit name. This is slightly more complicated
5693* than calling repo_find_unique_abbrev() because we also need to make
5694* sure that the abbreviation does not conflict with any other
5695* label.
5696*
5697* We disallow "interesting" commits to be labeled by a string that
5698* is a valid full-length hash, to ensure that we always can find an
5699* abbreviation for any uninteresting commit's names that does not
5700* clash with any other label.
5701*/
5702strbuf_reset(&state->buf);5703if (!label) {5704char *p;5705
5706strbuf_grow(&state->buf, GIT_MAX_HEXSZ);5707label = p = state->buf.buf;5708
5709repo_find_unique_abbrev_r(the_repository, p, oid,5710default_abbrev);5711
5712/*5713* We may need to extend the abbreviated hash so that there is
5714* no conflicting label.
5715*/
5716if (hashmap_get_from_hash(&state->labels, strihash(p), p)) {5717size_t i = strlen(p) + 1;5718
5719oid_to_hex_r(p, oid);5720for (; i < the_hash_algo->hexsz; i++) {5721char save = p[i];5722p[i] = '\0';5723if (!hashmap_get_from_hash(&state->labels,5724strihash(p), p))5725break;5726p[i] = save;5727}5728}5729} else {5730struct strbuf *buf = &state->buf;5731int label_is_utf8 = 1; /* start with this assumption */5732size_t max_len = buf->len + state->max_label_length;5733
5734/*5735* Sanitize labels by replacing non-alpha-numeric characters
5736* (including white-space ones) by dashes, as they might be
5737* illegal in file names (and hence in ref names).
5738*
5739* Note that we retain non-ASCII UTF-8 characters (identified
5740* via the most significant bit). They should be all acceptable
5741* in file names.
5742*
5743* As we will use the labels as names of (loose) refs, it is
5744* vital that the name not be longer than the maximum component
5745* size of the file system (`NAME_MAX`). We are careful to
5746* truncate the label accordingly, allowing for the `.lock`
5747* suffix and for the label to be UTF-8 encoded (i.e. we avoid
5748* truncating in the middle of a character).
5749*/
5750for (; *label && buf->len + 1 < max_len; label++)5751if (isalnum(*label) ||5752(!label_is_utf8 && (*label & 0x80)))5753strbuf_addch(buf, *label);5754else if (*label & 0x80) {5755const char *p = label;5756
5757utf8_width(&p, NULL);5758if (p) {5759if (buf->len + (p - label) > max_len)5760break;5761strbuf_add(buf, label, p - label);5762label = p - 1;5763} else {5764label_is_utf8 = 0;5765strbuf_addch(buf, *label);5766}5767/* avoid leading dash and double-dashes */5768} else if (buf->len && buf->buf[buf->len - 1] != '-')5769strbuf_addch(buf, '-');5770if (!buf->len) {5771strbuf_addstr(buf, "rev-");5772strbuf_add_unique_abbrev(buf, oid, default_abbrev);5773}5774label = buf->buf;5775
5776if ((buf->len == the_hash_algo->hexsz &&5777!get_oid_hex(label, &dummy)) ||5778(buf->len == 1 && *label == '#') ||5779hashmap_get_from_hash(&state->labels,5780strihash(label), label)) {5781/*5782* If the label already exists, or if the label is a
5783* valid full OID, or the label is a '#' (which we use
5784* as a separator between merge heads and oneline), we
5785* append a dash and a number to make it unique.
5786*/
5787size_t len = buf->len;5788
5789for (i = 2; ; i++) {5790strbuf_setlen(buf, len);5791strbuf_addf(buf, "-%d", i);5792if (!hashmap_get_from_hash(&state->labels,5793strihash(buf->buf),5794buf->buf))5795break;5796}5797
5798label = buf->buf;5799}5800}5801
5802FLEX_ALLOC_STR(labels_entry, label, label);5803hashmap_entry_init(&labels_entry->entry, strihash(label));5804hashmap_add(&state->labels, &labels_entry->entry);5805
5806FLEX_ALLOC_STR(string_entry, string, label);5807oidcpy(&string_entry->entry.oid, oid);5808oidmap_put(&state->commit2label, string_entry);5809
5810return string_entry->string;5811}
5812
5813static int make_script_with_merges(struct pretty_print_context *pp,5814struct rev_info *revs, struct strbuf *out,5815unsigned flags)5816{
5817int keep_empty = flags & TODO_LIST_KEEP_EMPTY;5818int rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;5819int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO;5820int skipped_commit = 0;5821struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;5822struct strbuf label = STRBUF_INIT;5823struct commit_list *commits = NULL, **tail = &commits, *iter;5824struct commit_list *tips = NULL, **tips_tail = &tips;5825struct commit *commit;5826struct oidmap commit2todo = OIDMAP_INIT;5827struct string_entry *entry;5828struct oidset interesting = OIDSET_INIT, child_seen = OIDSET_INIT,5829shown = OIDSET_INIT;5830struct label_state state =5831{ OIDMAP_INIT, { NULL }, STRBUF_INIT, GIT_MAX_LABEL_LENGTH };5832
5833int abbr = flags & TODO_LIST_ABBREVIATE_CMDS;5834const char *cmd_pick = abbr ? "p" : "pick",5835*cmd_label = abbr ? "l" : "label",5836*cmd_reset = abbr ? "t" : "reset",5837*cmd_merge = abbr ? "m" : "merge";5838
5839git_config_get_int("rebase.maxlabellength", &state.max_label_length);5840
5841oidmap_init(&commit2todo, 0);5842oidmap_init(&state.commit2label, 0);5843hashmap_init(&state.labels, labels_cmp, NULL, 0);5844strbuf_init(&state.buf, 32);5845
5846if (revs->cmdline.nr && (revs->cmdline.rev[0].flags & BOTTOM)) {5847struct labels_entry *onto_label_entry;5848struct object_id *oid = &revs->cmdline.rev[0].item->oid;5849FLEX_ALLOC_STR(entry, string, "onto");5850oidcpy(&entry->entry.oid, oid);5851oidmap_put(&state.commit2label, entry);5852
5853FLEX_ALLOC_STR(onto_label_entry, label, "onto");5854hashmap_entry_init(&onto_label_entry->entry, strihash("onto"));5855hashmap_add(&state.labels, &onto_label_entry->entry);5856}5857
5858/*5859* First phase:
5860* - get onelines for all commits
5861* - gather all branch tips (i.e. 2nd or later parents of merges)
5862* - label all branch tips
5863*/
5864while ((commit = get_revision(revs))) {5865struct commit_list *to_merge;5866const char *p1, *p2;5867struct object_id *oid;5868int is_empty;5869
5870tail = &commit_list_insert(commit, tail)->next;5871oidset_insert(&interesting, &commit->object.oid);5872
5873is_empty = is_original_commit_empty(commit);5874if (!is_empty && (commit->object.flags & PATCHSAME)) {5875if (flags & TODO_LIST_WARN_SKIPPED_CHERRY_PICKS)5876warning(_("skipped previously applied commit %s"),5877short_commit_name(the_repository, commit));5878skipped_commit = 1;5879continue;5880}5881if (is_empty && !keep_empty)5882continue;5883
5884strbuf_reset(&oneline);5885pretty_print_commit(pp, commit, &oneline);5886
5887to_merge = commit->parents ? commit->parents->next : NULL;5888if (!to_merge) {5889/* non-merge commit: easy case */5890strbuf_reset(&buf);5891strbuf_addf(&buf, "%s %s %s", cmd_pick,5892oid_to_hex(&commit->object.oid),5893oneline.buf);5894if (is_empty)5895strbuf_addf(&buf, " %s empty",5896comment_line_str);5897
5898FLEX_ALLOC_STR(entry, string, buf.buf);5899oidcpy(&entry->entry.oid, &commit->object.oid);5900oidmap_put(&commit2todo, entry);5901
5902continue;5903}5904
5905/* Create a label */5906strbuf_reset(&label);5907if (skip_prefix(oneline.buf, "Merge ", &p1) &&5908(p1 = strchr(p1, '\'')) &&5909(p2 = strchr(++p1, '\'')))5910strbuf_add(&label, p1, p2 - p1);5911else if (skip_prefix(oneline.buf, "Merge pull request ",5912&p1) &&5913(p1 = strstr(p1, " from ")))5914strbuf_addstr(&label, p1 + strlen(" from "));5915else5916strbuf_addbuf(&label, &oneline);5917
5918strbuf_reset(&buf);5919strbuf_addf(&buf, "%s -C %s",5920cmd_merge, oid_to_hex(&commit->object.oid));5921
5922/* label the tips of merged branches */5923for (; to_merge; to_merge = to_merge->next) {5924oid = &to_merge->item->object.oid;5925strbuf_addch(&buf, ' ');5926
5927if (!oidset_contains(&interesting, oid)) {5928strbuf_addstr(&buf, label_oid(oid, NULL,5929&state));5930continue;5931}5932
5933tips_tail = &commit_list_insert(to_merge->item,5934tips_tail)->next;5935
5936strbuf_addstr(&buf, label_oid(oid, label.buf, &state));5937}5938strbuf_addf(&buf, " # %s", oneline.buf);5939
5940FLEX_ALLOC_STR(entry, string, buf.buf);5941oidcpy(&entry->entry.oid, &commit->object.oid);5942oidmap_put(&commit2todo, entry);5943}5944if (skipped_commit)5945advise_if_enabled(ADVICE_SKIPPED_CHERRY_PICKS,5946_("use --reapply-cherry-picks to include skipped commits"));5947
5948/*5949* Second phase:
5950* - label branch points
5951* - add HEAD to the branch tips
5952*/
5953for (iter = commits; iter; iter = iter->next) {5954struct commit_list *parent = iter->item->parents;5955for (; parent; parent = parent->next) {5956struct object_id *oid = &parent->item->object.oid;5957if (!oidset_contains(&interesting, oid))5958continue;5959if (oidset_insert(&child_seen, oid))5960label_oid(oid, "branch-point", &state);5961}5962
5963/* Add HEAD as implicit "tip of branch" */5964if (!iter->next)5965tips_tail = &commit_list_insert(iter->item,5966tips_tail)->next;5967}5968
5969/*5970* Third phase: output the todo list. This is a bit tricky, as we
5971* want to avoid jumping back and forth between revisions. To
5972* accomplish that goal, we walk backwards from the branch tips,
5973* gathering commits not yet shown, reversing the list on the fly,
5974* then outputting that list (labeling revisions as needed).
5975*/
5976strbuf_addf(out, "%s onto\n", cmd_label);5977for (iter = tips; iter; iter = iter->next) {5978struct commit_list *list = NULL, *iter2;5979
5980commit = iter->item;5981if (oidset_contains(&shown, &commit->object.oid))5982continue;5983entry = oidmap_get(&state.commit2label, &commit->object.oid);5984
5985if (entry)5986strbuf_addf(out, "\n%s Branch %s\n", comment_line_str, entry->string);5987else5988strbuf_addch(out, '\n');5989
5990while (oidset_contains(&interesting, &commit->object.oid) &&5991!oidset_contains(&shown, &commit->object.oid)) {5992commit_list_insert(commit, &list);5993if (!commit->parents) {5994commit = NULL;5995break;5996}5997commit = commit->parents->item;5998}5999
6000if (!commit)6001strbuf_addf(out, "%s %s\n", cmd_reset,6002rebase_cousins || root_with_onto ?6003"onto" : "[new root]");6004else {6005const char *to = NULL;6006
6007entry = oidmap_get(&state.commit2label,6008&commit->object.oid);6009if (entry)6010to = entry->string;6011else if (!rebase_cousins)6012to = label_oid(&commit->object.oid, NULL,6013&state);6014
6015if (!to || !strcmp(to, "onto"))6016strbuf_addf(out, "%s onto\n", cmd_reset);6017else {6018strbuf_reset(&oneline);6019pretty_print_commit(pp, commit, &oneline);6020strbuf_addf(out, "%s %s # %s\n",6021cmd_reset, to, oneline.buf);6022}6023}6024
6025for (iter2 = list; iter2; iter2 = iter2->next) {6026struct object_id *oid = &iter2->item->object.oid;6027entry = oidmap_get(&commit2todo, oid);6028/* only show if not already upstream */6029if (entry)6030strbuf_addf(out, "%s\n", entry->string);6031entry = oidmap_get(&state.commit2label, oid);6032if (entry)6033strbuf_addf(out, "%s %s\n",6034cmd_label, entry->string);6035oidset_insert(&shown, oid);6036}6037
6038free_commit_list(list);6039}6040
6041free_commit_list(commits);6042free_commit_list(tips);6043
6044strbuf_release(&label);6045strbuf_release(&oneline);6046strbuf_release(&buf);6047
6048oidset_clear(&interesting);6049oidset_clear(&child_seen);6050oidset_clear(&shown);6051oidmap_free(&commit2todo, 1);6052oidmap_free(&state.commit2label, 1);6053hashmap_clear_and_free(&state.labels, struct labels_entry, entry);6054strbuf_release(&state.buf);6055
6056return 0;6057}
6058
6059int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,6060const char **argv, unsigned flags)6061{
6062char *format = NULL;6063struct pretty_print_context pp = {0};6064struct rev_info revs;6065struct commit *commit;6066int keep_empty = flags & TODO_LIST_KEEP_EMPTY;6067const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick";6068int rebase_merges = flags & TODO_LIST_REBASE_MERGES;6069int reapply_cherry_picks = flags & TODO_LIST_REAPPLY_CHERRY_PICKS;6070int skipped_commit = 0;6071int ret = 0;6072
6073repo_init_revisions(r, &revs, NULL);6074revs.verbose_header = 1;6075if (!rebase_merges)6076revs.max_parents = 1;6077revs.cherry_mark = !reapply_cherry_picks;6078revs.limited = 1;6079revs.reverse = 1;6080revs.right_only = 1;6081revs.sort_order = REV_SORT_IN_GRAPH_ORDER;6082revs.topo_order = 1;6083
6084revs.pretty_given = 1;6085git_config_get_string("rebase.instructionFormat", &format);6086if (!format || !*format) {6087free(format);6088format = xstrdup("%s");6089}6090get_commit_format(format, &revs);6091free(format);6092pp.fmt = revs.commit_format;6093pp.output_encoding = get_log_output_encoding();6094
6095if (setup_revisions(argc, argv, &revs, NULL) > 1) {6096ret = error(_("make_script: unhandled options"));6097goto cleanup;6098}6099
6100if (prepare_revision_walk(&revs) < 0) {6101ret = error(_("make_script: error preparing revisions"));6102goto cleanup;6103}6104
6105if (rebase_merges) {6106ret = make_script_with_merges(&pp, &revs, out, flags);6107goto cleanup;6108}6109
6110while ((commit = get_revision(&revs))) {6111int is_empty = is_original_commit_empty(commit);6112
6113if (!is_empty && (commit->object.flags & PATCHSAME)) {6114if (flags & TODO_LIST_WARN_SKIPPED_CHERRY_PICKS)6115warning(_("skipped previously applied commit %s"),6116short_commit_name(r, commit));6117skipped_commit = 1;6118continue;6119}6120if (is_empty && !keep_empty)6121continue;6122strbuf_addf(out, "%s %s ", insn,6123oid_to_hex(&commit->object.oid));6124pretty_print_commit(&pp, commit, out);6125if (is_empty)6126strbuf_addf(out, " %s empty", comment_line_str);6127strbuf_addch(out, '\n');6128}6129if (skipped_commit)6130advise_if_enabled(ADVICE_SKIPPED_CHERRY_PICKS,6131_("use --reapply-cherry-picks to include skipped commits"));6132cleanup:6133release_revisions(&revs);6134return ret;6135}
6136
6137/*
6138* Add commands after pick and (series of) squash/fixup commands
6139* in the todo list.
6140*/
6141static void todo_list_add_exec_commands(struct todo_list *todo_list,6142struct string_list *commands)6143{
6144struct strbuf *buf = &todo_list->buf;6145size_t base_offset = buf->len;6146int i, insert, nr = 0, alloc = 0;6147struct todo_item *items = NULL, *base_items = NULL;6148
6149CALLOC_ARRAY(base_items, commands->nr);6150for (i = 0; i < commands->nr; i++) {6151size_t command_len = strlen(commands->items[i].string);6152
6153strbuf_addstr(buf, commands->items[i].string);6154strbuf_addch(buf, '\n');6155
6156base_items[i].command = TODO_EXEC;6157base_items[i].offset_in_buf = base_offset;6158base_items[i].arg_offset = base_offset;6159base_items[i].arg_len = command_len;6160
6161base_offset += command_len + 1;6162}6163
6164/*6165* Insert <commands> after every pick. Here, fixup/squash chains
6166* are considered part of the pick, so we insert the commands *after*
6167* those chains if there are any.
6168*
6169* As we insert the exec commands immediately after rearranging
6170* any fixups and before the user edits the list, a fixup chain
6171* can never contain comments (any comments are empty picks that
6172* have been commented out because the user did not specify
6173* --keep-empty). So, it is safe to insert an exec command
6174* without looking at the command following a comment.
6175*/
6176insert = 0;6177for (i = 0; i < todo_list->nr; i++) {6178enum todo_command command = todo_list->items[i].command;6179if (insert && !is_fixup(command)) {6180ALLOC_GROW(items, nr + commands->nr, alloc);6181COPY_ARRAY(items + nr, base_items, commands->nr);6182nr += commands->nr;6183
6184insert = 0;6185}6186
6187ALLOC_GROW(items, nr + 1, alloc);6188items[nr++] = todo_list->items[i];6189
6190if (command == TODO_PICK || command == TODO_MERGE)6191insert = 1;6192}6193
6194/* insert or append final <commands> */6195if (insert) {6196ALLOC_GROW(items, nr + commands->nr, alloc);6197COPY_ARRAY(items + nr, base_items, commands->nr);6198nr += commands->nr;6199}6200
6201free(base_items);6202FREE_AND_NULL(todo_list->items);6203todo_list->items = items;6204todo_list->nr = nr;6205todo_list->alloc = alloc;6206}
6207
6208static void todo_list_to_strbuf(struct repository *r,6209struct todo_list *todo_list,6210struct strbuf *buf, int num, unsigned flags)6211{
6212struct todo_item *item;6213int i, max = todo_list->nr;6214
6215if (num > 0 && num < max)6216max = num;6217
6218for (item = todo_list->items, i = 0; i < max; i++, item++) {6219char cmd;6220
6221/* if the item is not a command write it and continue */6222if (item->command >= TODO_COMMENT) {6223strbuf_addf(buf, "%.*s\n", item->arg_len,6224todo_item_get_arg(todo_list, item));6225continue;6226}6227
6228/* add command to the buffer */6229cmd = command_to_char(item->command);6230if ((flags & TODO_LIST_ABBREVIATE_CMDS) && cmd)6231strbuf_addch(buf, cmd);6232else6233strbuf_addstr(buf, command_to_string(item->command));6234
6235/* add commit id */6236if (item->commit) {6237const char *oid = flags & TODO_LIST_SHORTEN_IDS ?6238short_commit_name(r, item->commit) :6239oid_to_hex(&item->commit->object.oid);6240
6241if (item->command == TODO_FIXUP) {6242if (item->flags & TODO_EDIT_FIXUP_MSG)6243strbuf_addstr(buf, " -c");6244else if (item->flags & TODO_REPLACE_FIXUP_MSG) {6245strbuf_addstr(buf, " -C");6246}6247}6248
6249if (item->command == TODO_MERGE) {6250if (item->flags & TODO_EDIT_MERGE_MSG)6251strbuf_addstr(buf, " -c");6252else6253strbuf_addstr(buf, " -C");6254}6255
6256strbuf_addf(buf, " %s", oid);6257}6258
6259/* add all the rest */6260if (!item->arg_len)6261strbuf_addch(buf, '\n');6262else6263strbuf_addf(buf, " %.*s\n", item->arg_len,6264todo_item_get_arg(todo_list, item));6265}6266}
6267
6268int todo_list_write_to_file(struct repository *r, struct todo_list *todo_list,6269const char *file, const char *shortrevisions,6270const char *shortonto, int num, unsigned flags)6271{
6272int res;6273struct strbuf buf = STRBUF_INIT;6274
6275todo_list_to_strbuf(r, todo_list, &buf, num, flags);6276if (flags & TODO_LIST_APPEND_TODO_HELP)6277append_todo_help(count_commands(todo_list),6278shortrevisions, shortonto, &buf);6279
6280res = write_message(buf.buf, buf.len, file, 0);6281strbuf_release(&buf);6282
6283return res;6284}
6285
6286/* skip picking commits whose parents are unchanged */
6287static int skip_unnecessary_picks(struct repository *r,6288struct todo_list *todo_list,6289struct object_id *base_oid)6290{
6291struct object_id *parent_oid;6292int i;6293
6294for (i = 0; i < todo_list->nr; i++) {6295struct todo_item *item = todo_list->items + i;6296
6297if (item->command >= TODO_NOOP)6298continue;6299if (item->command != TODO_PICK)6300break;6301if (repo_parse_commit(r, item->commit)) {6302return error(_("could not parse commit '%s'"),6303oid_to_hex(&item->commit->object.oid));6304}6305if (!item->commit->parents)6306break; /* root commit */6307if (item->commit->parents->next)6308break; /* merge commit */6309parent_oid = &item->commit->parents->item->object.oid;6310if (!oideq(parent_oid, base_oid))6311break;6312oidcpy(base_oid, &item->commit->object.oid);6313}6314if (i > 0) {6315const char *done_path = rebase_path_done();6316
6317if (todo_list_write_to_file(r, todo_list, done_path, NULL, NULL, i, 0)) {6318error_errno(_("could not write to '%s'"), done_path);6319return -1;6320}6321
6322MOVE_ARRAY(todo_list->items, todo_list->items + i, todo_list->nr - i);6323todo_list->nr -= i;6324todo_list->current = 0;6325todo_list->done_nr += i;6326
6327if (is_fixup(peek_command(todo_list, 0)))6328record_in_rewritten(base_oid, peek_command(todo_list, 0));6329}6330
6331return 0;6332}
6333
6334struct todo_add_branch_context {6335struct todo_item *items;6336size_t items_nr;6337size_t items_alloc;6338struct strbuf *buf;6339struct commit *commit;6340struct string_list refs_to_oids;6341};6342
6343static int add_decorations_to_list(const struct commit *commit,6344struct todo_add_branch_context *ctx)6345{
6346const struct name_decoration *decoration = get_name_decoration(&commit->object);6347const char *head_ref = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),6348"HEAD",6349RESOLVE_REF_READING,6350NULL,6351NULL);6352
6353while (decoration) {6354struct todo_item *item;6355const char *path;6356size_t base_offset = ctx->buf->len;6357
6358/*6359* If the branch is the current HEAD, then it will be
6360* updated by the default rebase behavior.
6361*/
6362if (head_ref && !strcmp(head_ref, decoration->name)) {6363decoration = decoration->next;6364continue;6365}6366
6367ALLOC_GROW(ctx->items,6368ctx->items_nr + 1,6369ctx->items_alloc);6370item = &ctx->items[ctx->items_nr];6371memset(item, 0, sizeof(*item));6372
6373/* If the branch is checked out, then leave a comment instead. */6374if ((path = branch_checked_out(decoration->name))) {6375item->command = TODO_COMMENT;6376strbuf_addf(ctx->buf, "# Ref %s checked out at '%s'\n",6377decoration->name, path);6378} else {6379struct string_list_item *sti;6380item->command = TODO_UPDATE_REF;6381strbuf_addf(ctx->buf, "%s\n", decoration->name);6382
6383sti = string_list_insert(&ctx->refs_to_oids,6384decoration->name);6385sti->util = init_update_ref_record(decoration->name);6386}6387
6388item->offset_in_buf = base_offset;6389item->arg_offset = base_offset;6390item->arg_len = ctx->buf->len - base_offset;6391ctx->items_nr++;6392
6393decoration = decoration->next;6394}6395
6396return 0;6397}
6398
6399/*
6400* For each 'pick' command, find out if the commit has a decoration in
6401* refs/heads/. If so, then add a 'label for-update-refs/' command.
6402*/
6403static int todo_list_add_update_ref_commands(struct todo_list *todo_list)6404{
6405int i, res;6406static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP;6407static struct string_list decorate_refs_exclude_config = STRING_LIST_INIT_NODUP;6408static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP;6409struct decoration_filter decoration_filter = {6410.include_ref_pattern = &decorate_refs_include,6411.exclude_ref_pattern = &decorate_refs_exclude,6412.exclude_ref_config_pattern = &decorate_refs_exclude_config,6413};6414struct todo_add_branch_context ctx = {6415.buf = &todo_list->buf,6416.refs_to_oids = STRING_LIST_INIT_DUP,6417};6418
6419ctx.items_alloc = 2 * todo_list->nr + 1;6420ALLOC_ARRAY(ctx.items, ctx.items_alloc);6421
6422string_list_append(&decorate_refs_include, "refs/heads/");6423load_ref_decorations(&decoration_filter, 0);6424
6425for (i = 0; i < todo_list->nr; ) {6426struct todo_item *item = &todo_list->items[i];6427
6428/* insert ith item into new list */6429ALLOC_GROW(ctx.items,6430ctx.items_nr + 1,6431ctx.items_alloc);6432
6433ctx.items[ctx.items_nr++] = todo_list->items[i++];6434
6435if (item->commit) {6436ctx.commit = item->commit;6437add_decorations_to_list(item->commit, &ctx);6438}6439}6440
6441res = write_update_refs_state(&ctx.refs_to_oids);6442
6443string_list_clear(&ctx.refs_to_oids, 1);6444
6445if (res) {6446/* we failed, so clean up the new list. */6447free(ctx.items);6448return res;6449}6450
6451free(todo_list->items);6452todo_list->items = ctx.items;6453todo_list->nr = ctx.items_nr;6454todo_list->alloc = ctx.items_alloc;6455
6456return 0;6457}
6458
6459int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,6460const char *shortrevisions, const char *onto_name,6461struct commit *onto, const struct object_id *orig_head,6462struct string_list *commands, unsigned autosquash,6463unsigned update_refs,6464struct todo_list *todo_list)6465{
6466char shortonto[GIT_MAX_HEXSZ + 1];6467const char *todo_file = rebase_path_todo();6468struct todo_list new_todo = TODO_LIST_INIT;6469struct strbuf *buf = &todo_list->buf, buf2 = STRBUF_INIT;6470struct object_id oid = onto->object.oid;6471int res;6472
6473repo_find_unique_abbrev_r(r, shortonto, &oid,6474DEFAULT_ABBREV);6475
6476if (buf->len == 0) {6477struct todo_item *item = append_new_todo(todo_list);6478item->command = TODO_NOOP;6479item->commit = NULL;6480item->arg_len = item->arg_offset = item->flags = item->offset_in_buf = 0;6481}6482
6483if (update_refs && todo_list_add_update_ref_commands(todo_list))6484return -1;6485
6486if (autosquash && todo_list_rearrange_squash(todo_list))6487return -1;6488
6489if (commands->nr)6490todo_list_add_exec_commands(todo_list, commands);6491
6492if (count_commands(todo_list) == 0) {6493apply_autostash(rebase_path_autostash());6494sequencer_remove_state(opts);6495
6496return error(_("nothing to do"));6497}6498
6499res = edit_todo_list(r, opts, todo_list, &new_todo, shortrevisions,6500shortonto, flags);6501if (res == -1)6502return -1;6503else if (res == -2) {6504apply_autostash(rebase_path_autostash());6505sequencer_remove_state(opts);6506
6507return -1;6508} else if (res == -3) {6509apply_autostash(rebase_path_autostash());6510sequencer_remove_state(opts);6511todo_list_release(&new_todo);6512
6513return error(_("nothing to do"));6514} else if (res == -4) {6515checkout_onto(r, opts, onto_name, &onto->object.oid, orig_head);6516todo_list_release(&new_todo);6517
6518return -1;6519}6520
6521/* Expand the commit IDs */6522todo_list_to_strbuf(r, &new_todo, &buf2, -1, 0);6523strbuf_swap(&new_todo.buf, &buf2);6524strbuf_release(&buf2);6525/* Nothing is done yet, and we're reparsing, so let's reset the count */6526new_todo.total_nr = 0;6527if (todo_list_parse_insn_buffer(r, opts, new_todo.buf.buf, &new_todo) < 0)6528BUG("invalid todo list after expanding IDs:\n%s",6529new_todo.buf.buf);6530
6531if (opts->allow_ff && skip_unnecessary_picks(r, &new_todo, &oid)) {6532todo_list_release(&new_todo);6533return error(_("could not skip unnecessary pick commands"));6534}6535
6536if (todo_list_write_to_file(r, &new_todo, todo_file, NULL, NULL, -1,6537flags & ~(TODO_LIST_SHORTEN_IDS))) {6538todo_list_release(&new_todo);6539return error_errno(_("could not write '%s'"), todo_file);6540}6541
6542res = -1;6543
6544if (checkout_onto(r, opts, onto_name, &oid, orig_head))6545goto cleanup;6546
6547if (require_clean_work_tree(r, "rebase", NULL, 1, 1))6548goto cleanup;6549
6550todo_list_write_total_nr(&new_todo);6551res = pick_commits(r, &new_todo, opts);6552
6553cleanup:6554todo_list_release(&new_todo);6555
6556return res;6557}
6558
6559struct subject2item_entry {6560struct hashmap_entry entry;6561int i;6562char subject[FLEX_ARRAY];6563};6564
6565static int subject2item_cmp(const void *fndata UNUSED,6566const struct hashmap_entry *eptr,6567const struct hashmap_entry *entry_or_key,6568const void *key)6569{
6570const struct subject2item_entry *a, *b;6571
6572a = container_of(eptr, const struct subject2item_entry, entry);6573b = container_of(entry_or_key, const struct subject2item_entry, entry);6574
6575return key ? strcmp(a->subject, key) : strcmp(a->subject, b->subject);6576}
6577
6578define_commit_slab(commit_todo_item, struct todo_item *);6579
6580static int skip_fixupish(const char *subject, const char **p) {6581return skip_prefix(subject, "fixup! ", p) ||6582skip_prefix(subject, "amend! ", p) ||6583skip_prefix(subject, "squash! ", p);6584}
6585
6586/*
6587* Rearrange the todo list that has both "pick commit-id msg" and "pick
6588* commit-id fixup!/squash! msg" in it so that the latter is put immediately
6589* after the former, and change "pick" to "fixup"/"squash".
6590*
6591* Note that if the config has specified a custom instruction format, each log
6592* message will have to be retrieved from the commit (as the oneline in the
6593* script cannot be trusted) in order to normalize the autosquash arrangement.
6594*/
6595int todo_list_rearrange_squash(struct todo_list *todo_list)6596{
6597struct hashmap subject2item;6598int rearranged = 0, *next, *tail, i, nr = 0;6599char **subjects;6600struct commit_todo_item commit_todo;6601struct todo_item *items = NULL;6602
6603init_commit_todo_item(&commit_todo);6604/*6605* The hashmap maps onelines to the respective todo list index.
6606*
6607* If any items need to be rearranged, the next[i] value will indicate
6608* which item was moved directly after the i'th.
6609*
6610* In that case, last[i] will indicate the index of the latest item to
6611* be moved to appear after the i'th.
6612*/
6613hashmap_init(&subject2item, subject2item_cmp, NULL, todo_list->nr);6614ALLOC_ARRAY(next, todo_list->nr);6615ALLOC_ARRAY(tail, todo_list->nr);6616ALLOC_ARRAY(subjects, todo_list->nr);6617for (i = 0; i < todo_list->nr; i++) {6618struct strbuf buf = STRBUF_INIT;6619struct todo_item *item = todo_list->items + i;6620const char *commit_buffer, *subject, *p;6621size_t subject_len;6622int i2 = -1;6623struct subject2item_entry *entry;6624
6625next[i] = tail[i] = -1;6626if (!item->commit || item->command == TODO_DROP) {6627subjects[i] = NULL;6628continue;6629}6630
6631if (is_fixup(item->command)) {6632clear_commit_todo_item(&commit_todo);6633return error(_("the script was already rearranged."));6634}6635
6636repo_parse_commit(the_repository, item->commit);6637commit_buffer = repo_logmsg_reencode(the_repository,6638item->commit, NULL,6639"UTF-8");6640find_commit_subject(commit_buffer, &subject);6641format_subject(&buf, subject, " ");6642subject = subjects[i] = strbuf_detach(&buf, &subject_len);6643repo_unuse_commit_buffer(the_repository, item->commit,6644commit_buffer);6645if (skip_fixupish(subject, &p)) {6646struct commit *commit2;6647
6648for (;;) {6649while (isspace(*p))6650p++;6651if (!skip_fixupish(p, &p))6652break;6653}6654
6655entry = hashmap_get_entry_from_hash(&subject2item,6656strhash(p), p,6657struct subject2item_entry,6658entry);6659if (entry)6660/* found by title */6661i2 = entry->i;6662else if (!strchr(p, ' ') &&6663(commit2 =6664lookup_commit_reference_by_name(p)) &&6665*commit_todo_item_at(&commit_todo, commit2))6666/* found by commit name */6667i2 = *commit_todo_item_at(&commit_todo, commit2)6668- todo_list->items;6669else {6670/* copy can be a prefix of the commit subject */6671for (i2 = 0; i2 < i; i2++)6672if (subjects[i2] &&6673starts_with(subjects[i2], p))6674break;6675if (i2 == i)6676i2 = -1;6677}6678}6679if (i2 >= 0) {6680rearranged = 1;6681if (starts_with(subject, "fixup!")) {6682todo_list->items[i].command = TODO_FIXUP;6683} else if (starts_with(subject, "amend!")) {6684todo_list->items[i].command = TODO_FIXUP;6685todo_list->items[i].flags = TODO_REPLACE_FIXUP_MSG;6686} else {6687todo_list->items[i].command = TODO_SQUASH;6688}6689if (tail[i2] < 0) {6690next[i] = next[i2];6691next[i2] = i;6692} else {6693next[i] = next[tail[i2]];6694next[tail[i2]] = i;6695}6696tail[i2] = i;6697} else if (!hashmap_get_from_hash(&subject2item,6698strhash(subject), subject)) {6699FLEX_ALLOC_MEM(entry, subject, subject, subject_len);6700entry->i = i;6701hashmap_entry_init(&entry->entry,6702strhash(entry->subject));6703hashmap_put(&subject2item, &entry->entry);6704}6705
6706*commit_todo_item_at(&commit_todo, item->commit) = item;6707}6708
6709if (rearranged) {6710ALLOC_ARRAY(items, todo_list->nr);6711
6712for (i = 0; i < todo_list->nr; i++) {6713enum todo_command command = todo_list->items[i].command;6714int cur = i;6715
6716/*6717* Initially, all commands are 'pick's. If it is a
6718* fixup or a squash now, we have rearranged it.
6719*/
6720if (is_fixup(command))6721continue;6722
6723while (cur >= 0) {6724items[nr++] = todo_list->items[cur];6725cur = next[cur];6726}6727}6728
6729assert(nr == todo_list->nr);6730todo_list->alloc = nr;6731FREE_AND_NULL(todo_list->items);6732todo_list->items = items;6733}6734
6735free(next);6736free(tail);6737for (i = 0; i < todo_list->nr; i++)6738free(subjects[i]);6739free(subjects);6740hashmap_clear_and_free(&subject2item, struct subject2item_entry, entry);6741
6742clear_commit_todo_item(&commit_todo);6743
6744return 0;6745}
6746
6747int sequencer_determine_whence(struct repository *r, enum commit_whence *whence)6748{
6749if (refs_ref_exists(get_main_ref_store(r), "CHERRY_PICK_HEAD")) {6750struct object_id cherry_pick_head, rebase_head;6751
6752if (file_exists(git_path_seq_dir()))6753*whence = FROM_CHERRY_PICK_MULTI;6754if (file_exists(rebase_path()) &&6755!repo_get_oid(r, "REBASE_HEAD", &rebase_head) &&6756!repo_get_oid(r, "CHERRY_PICK_HEAD", &cherry_pick_head) &&6757oideq(&rebase_head, &cherry_pick_head))6758*whence = FROM_REBASE_PICK;6759else6760*whence = FROM_CHERRY_PICK_SINGLE;6761
6762return 1;6763}6764
6765return 0;6766}
6767
6768int sequencer_get_update_refs_state(const char *wt_dir,6769struct string_list *refs)6770{
6771int result = 0;6772FILE *fp = NULL;6773struct strbuf ref = STRBUF_INIT;6774struct strbuf hash = STRBUF_INIT;6775struct update_ref_record *rec = NULL;6776
6777char *path = rebase_path_update_refs(wt_dir);6778
6779fp = fopen(path, "r");6780if (!fp)6781goto cleanup;6782
6783while (strbuf_getline(&ref, fp) != EOF) {6784struct string_list_item *item;6785
6786CALLOC_ARRAY(rec, 1);6787
6788if (strbuf_getline(&hash, fp) == EOF ||6789get_oid_hex(hash.buf, &rec->before)) {6790warning(_("update-refs file at '%s' is invalid"),6791path);6792result = -1;6793goto cleanup;6794}6795
6796if (strbuf_getline(&hash, fp) == EOF ||6797get_oid_hex(hash.buf, &rec->after)) {6798warning(_("update-refs file at '%s' is invalid"),6799path);6800result = -1;6801goto cleanup;6802}6803
6804item = string_list_insert(refs, ref.buf);6805item->util = rec;6806rec = NULL;6807}6808
6809cleanup:6810if (fp)6811fclose(fp);6812free(path);6813free(rec);6814strbuf_release(&ref);6815strbuf_release(&hash);6816return result;6817}
6818