git/sequencer.c

#define USE_THE_REPOSITORY_VARIABLE

#include "git-compat-util.h"
#include "abspath.h"
#include "advice.h"
#include "config.h"
#include "copy.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
#include "lockfile.h"
#include "dir.h"
#include "object-file.h"
#include "object-name.h"
#include "object-store-ll.h"
#include "object.h"
#include "pager.h"
#include "commit.h"
#include "sequencer.h"
#include "run-command.h"
#include "hook.h"
#include "utf8.h"
#include "cache-tree.h"
#include "diff.h"
#include "path.h"
#include "revision.h"
#include "rerere.h"
#include "merge.h"
#include "merge-ort.h"
#include "merge-ort-wrappers.h"
#include "refs.h"
#include "sparse-index.h"
#include "strvec.h"
#include "quote.h"
#include "trailer.h"
#include "log-tree.h"
#include "wt-status.h"
#include "hashmap.h"
#include "notes-utils.h"
#include "sigchain.h"
#include "unpack-trees.h"
#include "oidmap.h"
#include "oidset.h"
#include "commit-slab.h"
#include "alias.h"
#include "commit-reach.h"
#include "rebase-interactive.h"
#include "reset.h"
#include "branch.h"

#define GIT_REFLOG_ACTION

/*
 * To accommodate common filesystem limitations, where the loose refs' file
 * names must not exceed `NAME_MAX`, the labels generated by `git rebase
 * --rebase-merges` need to be truncated if the corresponding commit subjects
 * are too long.
 * Add some margin to stay clear from reaching `NAME_MAX`.
 */
#define GIT_MAX_LABEL_LENGTH

static const char sign_off_header[] =;
static const char cherry_picked_prefix[] =;

GIT_PATH_FUNC(git_path_commit_editmsg, "COMMIT_EDITMSG")

static GIT_PATH_FUNC(git_path_seq_dir, "sequencer")

static GIT_PATH_FUNC(git_path_todo_file, "sequencer/todo")
static GIT_PATH_FUNC(git_path_opts_file, "sequencer/opts")
static GIT_PATH_FUNC(git_path_head_file, "sequencer/head")
static GIT_PATH_FUNC(git_path_abort_safety_file, "sequencer/abort-safety")

static GIT_PATH_FUNC(rebase_path, "rebase-merge")
/*
 * The file containing rebase commands, comments, and empty lines.
 * This file is created by "git rebase -i" then edited by the user. As
 * the lines are processed, they are removed from the front of this
 * file and written to the tail of 'done'.
 */
GIT_PATH_FUNC(rebase_path_todo, "rebase-merge/git-rebase-todo")
GIT_PATH_FUNC(rebase_path_todo_backup, "rebase-merge/git-rebase-todo.backup")

GIT_PATH_FUNC(rebase_path_dropped, "rebase-merge/dropped")

/*
 * The rebase command lines that have already been processed. A line
 * is moved here when it is first handled, before any associated user
 * actions.
 */
static GIT_PATH_FUNC(rebase_path_done, "rebase-merge/done")
/*
 * The file to keep track of how many commands were already processed (e.g.
 * for the prompt).
 */
static GIT_PATH_FUNC(rebase_path_msgnum, "rebase-merge/msgnum")
/*
 * The file to keep track of how many commands are to be processed in total
 * (e.g. for the prompt).
 */
static GIT_PATH_FUNC(rebase_path_msgtotal, "rebase-merge/end")
/*
 * The commit message that is planned to be used for any changes that
 * need to be committed following a user interaction.
 */
static GIT_PATH_FUNC(rebase_path_message, "rebase-merge/message")
/*
 * The file into which is accumulated the suggested commit message for
 * squash/fixup commands. When the first of a series of squash/fixups
 * is seen, the file is created and the commit message from the
 * previous commit and from the first squash/fixup commit are written
 * to it. The commit message for each subsequent squash/fixup commit
 * is appended to the file as it is processed.
 */
static GIT_PATH_FUNC(rebase_path_squash_msg, "rebase-merge/message-squash")
/*
 * If the current series of squash/fixups has not yet included a squash
 * command, then this file exists and holds the commit message of the
 * original "pick" commit.  (If the series ends without a "squash"
 * command, then this can be used as the commit message of the combined
 * commit without opening the editor.)
 */
static GIT_PATH_FUNC(rebase_path_fixup_msg, "rebase-merge/message-fixup")
/*
 * This file contains the list fixup/squash commands that have been
 * accumulated into message-fixup or message-squash so far.
 */
static GIT_PATH_FUNC(rebase_path_current_fixups, "rebase-merge/current-fixups")
/*
 * A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
 * GIT_AUTHOR_DATE that will be used for the commit that is currently
 * being rebased.
 */
static GIT_PATH_FUNC(rebase_path_author_script, "rebase-merge/author-script")
/*
 * When an "edit" rebase command is being processed, the SHA1 of the
 * commit to be edited is recorded in this file.  When "git rebase
 * --continue" is executed, if there are any staged changes then they
 * will be amended to the HEAD commit, but only provided the HEAD
 * commit is still the commit to be edited.  When any other rebase
 * command is processed, this file is deleted.
 */
static GIT_PATH_FUNC(rebase_path_amend, "rebase-merge/amend")
/*
 * When we stop at a given patch via the "edit" command, this file contains
 * the commit object name of the corresponding patch.
 */
static GIT_PATH_FUNC(rebase_path_stopped_sha, "rebase-merge/stopped-sha")
/*
 * When we stop for the user to resolve conflicts this file contains
 * the patch of the commit that is being picked.
 */
static GIT_PATH_FUNC(rebase_path_patch, "rebase-merge/patch")
/*
 * For the post-rewrite hook, we make a list of rewritten commits and
 * their new sha1s.  The rewritten-pending list keeps the sha1s of
 * commits that have been processed, but not committed yet,
 * e.g. because they are waiting for a 'squash' command.
 */
static GIT_PATH_FUNC(rebase_path_rewritten_list, "rebase-merge/rewritten-list")
static GIT_PATH_FUNC(rebase_path_rewritten_pending,
	"rebase-merge/rewritten-pending")

/*
 * The path of the file containing the OID of the "squash onto" commit, i.e.
 * the dummy commit used for `reset [new root]`.
 */
static GIT_PATH_FUNC(rebase_path_squash_onto, "rebase-merge/squash-onto")

/*
 * The path of the file listing refs that need to be deleted after the rebase
 * finishes. This is used by the `label` command to record the need for cleanup.
 */
static GIT_PATH_FUNC(rebase_path_refs_to_delete, "rebase-merge/refs-to-delete")

/*
 * The update-refs file stores a list of refs that will be updated at the end
 * of the rebase sequence. The 'update-ref <ref>' commands in the todo file
 * update the OIDs for the refs in this file, but the refs are not updated
 * until the end of the rebase sequence.
 *
 * rebase_path_update_refs() returns the path to this file for a given
 * worktree directory. For the current worktree, pass the_repository->gitdir.
 */
static char *rebase_path_update_refs(const char *wt_git_dir)
{}

/*
 * The following files are written by git-rebase just after parsing the
 * command-line.
 */
static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
static GIT_PATH_FUNC(rebase_path_cdate_is_adate, "rebase-merge/cdate_is_adate")
static GIT_PATH_FUNC(rebase_path_ignore_date, "rebase-merge/ignore_date")
static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
static GIT_PATH_FUNC(rebase_path_quiet, "rebase-merge/quiet")
static GIT_PATH_FUNC(rebase_path_signoff, "rebase-merge/signoff")
static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
static GIT_PATH_FUNC(rebase_path_strategy, "rebase-merge/strategy")
static GIT_PATH_FUNC(rebase_path_strategy_opts, "rebase-merge/strategy_opts")
static GIT_PATH_FUNC(rebase_path_allow_rerere_autoupdate, "rebase-merge/allow_rerere_autoupdate")
static GIT_PATH_FUNC(rebase_path_reschedule_failed_exec, "rebase-merge/reschedule-failed-exec")
static GIT_PATH_FUNC(rebase_path_no_reschedule_failed_exec, "rebase-merge/no-reschedule-failed-exec")
static GIT_PATH_FUNC(rebase_path_drop_redundant_commits, "rebase-merge/drop_redundant_commits")
static GIT_PATH_FUNC(rebase_path_keep_redundant_commits, "rebase-merge/keep_redundant_commits")

/*
 * A 'struct replay_ctx' represents the private state of the sequencer.
 */
struct replay_ctx {};

struct replay_ctx* replay_ctx_new(void)
{}

/**
 * A 'struct update_refs_record' represents a value in the update-refs
 * list. We use a string_list to map refs to these (before, after) pairs.
 */
struct update_ref_record {};

static struct update_ref_record *init_update_ref_record(const char *ref)
{}

static int git_sequencer_config(const char *k, const char *v,
				const struct config_context *ctx, void *cb)
{}

void sequencer_init_config(struct replay_opts *opts)
{}

static inline int is_rebase_i(const struct replay_opts *opts)
{}

static const char *get_dir(const struct replay_opts *opts)
{}

static const char *get_todo_path(const struct replay_opts *opts)
{}

/*
 * Returns 0 for non-conforming footer
 * Returns 1 for conforming footer
 * Returns 2 when sob exists within conforming footer
 * Returns 3 when sob exists within conforming footer as last entry
 */
static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
	size_t ignore_footer)
{}

static const char *gpg_sign_opt_quoted(struct replay_opts *opts)
{}

static void replay_ctx_release(struct replay_ctx *ctx)
{}

void replay_opts_release(struct replay_opts *opts)
{}

int sequencer_remove_state(struct replay_opts *opts)
{}

static const char *action_name(const struct replay_opts *opts)
{}

struct commit_message {};

static const char *short_commit_name(struct repository *r, struct commit *commit)
{}

static int get_message(struct commit *commit, struct commit_message *out)
{}

static void free_message(struct commit *commit, struct commit_message *msg)
{}

const char *rebase_resolvemsg =);

static void print_advice(struct repository *r, int show_hint,
			 struct replay_opts *opts)
{}

static int write_message(const void *buf, size_t len, const char *filename,
			 int append_eol)
{}

int read_oneliner(struct strbuf *buf,
	const char *path, unsigned flags)
{}

static struct tree *empty_tree(struct repository *r)
{}

static int error_dirty_index(struct repository *repo, struct replay_opts *opts)
{}

static void update_abort_safety_file(void)
{}

static int fast_forward_to(struct repository *r,
			   const struct object_id *to,
			   const struct object_id *from,
			   int unborn,
			   struct replay_opts *opts)
{}

enum commit_msg_cleanup_mode get_cleanup_mode(const char *cleanup_arg,
	int use_editor)
{}

/*
 * NB using int rather than enum cleanup_mode to stop clang's
 * -Wtautological-constant-out-of-range-compare complaining that the comparison
 * is always true.
 */
static const char *describe_cleanup_mode(int cleanup_mode)
{}

void append_conflicts_hint(struct index_state *istate,
	struct strbuf *msgbuf, enum commit_msg_cleanup_mode cleanup_mode)
{}

static int do_recursive_merge(struct repository *r,
			      struct commit *base, struct commit *next,
			      const char *base_label, const char *next_label,
			      struct object_id *head, struct strbuf *msgbuf,
			      struct replay_opts *opts)
{}

static struct object_id *get_cache_tree_oid(struct index_state *istate)
{}

static int is_index_unchanged(struct repository *r)
{}

static int write_author_script(const char *message)
{}

/**
 * Take a series of KEY='VALUE' lines where VALUE part is
 * sq-quoted, and append <KEY, VALUE> at the end of the string list
 */
static int parse_key_value_squoted(char *buf, struct string_list *list)
{}

/**
 * Reads and parses the state directory's "author-script" file, and sets name,
 * email and date accordingly.
 * Returns 0 on success, -1 if the file could not be parsed.
 *
 * The author script is of the format:
 *
 *	GIT_AUTHOR_NAME='$author_name'
 *	GIT_AUTHOR_EMAIL='$author_email'
 *	GIT_AUTHOR_DATE='$author_date'
 *
 * where $author_name, $author_email and $author_date are quoted. We are strict
 * with our parsing, as the file was meant to be eval'd in the now-removed
 * git-am.sh/git-rebase--interactive.sh scripts, and thus if the file differs
 * from what this function expects, it is better to bail out than to do
 * something that the user does not expect.
 */
int read_author_script(const char *path, char **name, char **email, char **date,
		       int allow_missing)
{}

/*
 * Read a GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL AND GIT_AUTHOR_DATE from a
 * file with shell quoting into struct strvec. Returns -1 on
 * error, 0 otherwise.
 */
static int read_env_script(struct strvec *env)
{}

static char *get_author(const char *message)
{}

static const char *author_date_from_env(const struct strvec *env)
{}

static const char staged_changes_advice[] =);

#define ALLOW_EMPTY
#define EDIT_MSG
#define AMEND_MSG
#define CLEANUP_MSG
#define VERIFY_MSG
#define CREATE_ROOT_COMMIT
#define VERBATIM_MSG

static int run_command_silent_on_success(struct child_process *cmd)
{}

/*
 * If we are cherry-pick, and if the merge did not result in
 * hand-editing, we will hit this commit and inherit the original
 * author date and name.
 *
 * If we are revert, or if our cherry-pick results in a hand merge,
 * we had better say that the current user is responsible for that.
 *
 * An exception is when run_git_commit() is called during an
 * interactive rebase: in that case, we will want to retain the
 * author metadata.
 */
static int run_git_commit(const char *defmsg,
			  struct replay_opts *opts,
			  unsigned int flags)
{}

static int rest_is_empty(const struct strbuf *sb, int start)
{}

void cleanup_message(struct strbuf *msgbuf,
	enum commit_msg_cleanup_mode cleanup_mode, int verbose)
{}

/*
 * Find out if the message in the strbuf contains only whitespace and
 * Signed-off-by lines.
 */
int message_is_empty(const struct strbuf *sb,
		     enum commit_msg_cleanup_mode cleanup_mode)
{}

/*
 * See if the user edited the message in the editor or left what
 * was in the template intact
 */
int template_untouched(const struct strbuf *sb, const char *template_file,
		       enum commit_msg_cleanup_mode cleanup_mode)
{}

int update_head_with_reflog(const struct commit *old_head,
			    const struct object_id *new_head,
			    const char *action, const struct strbuf *msg,
			    struct strbuf *err)
{}

static int run_rewrite_hook(const struct object_id *oldoid,
			    const struct object_id *newoid)
{}

void commit_post_rewrite(struct repository *r,
			 const struct commit *old_head,
			 const struct object_id *new_head)
{}

static int run_prepare_commit_msg_hook(struct repository *r,
				       struct strbuf *msg,
				       const char *commit)
{}

static const char implicit_ident_advice_noconfig[] =);

static const char implicit_ident_advice_config[] =);

static const char *implicit_ident_advice(void)
{}

void print_commit_summary(struct repository *r,
			  const char *prefix,
			  const struct object_id *oid,
			  unsigned int flags)
{}

static int parse_head(struct repository *r, struct commit **head)
{}

/*
 * Try to commit without forking 'git commit'. In some cases we need
 * to run 'git commit' to display an error message
 *
 * Returns:
 *  -1 - error unable to commit
 *   0 - success
 *   1 - run 'git commit'
 */
static int try_to_commit(struct repository *r,
			 struct strbuf *msg, const char *author,
			 struct replay_opts *opts, unsigned int flags,
			 struct object_id *oid)
{}

static int write_rebase_head(struct object_id *oid)
{}

static int do_commit(struct repository *r,
		     const char *msg_file, const char *author,
		     struct replay_opts *opts, unsigned int flags,
		     struct object_id *oid)
{}

static int is_original_commit_empty(struct commit *commit)
{}

/*
 * Should empty commits be allowed?  Return status:
 *    <0: Error in is_index_unchanged(r) or is_original_commit_empty(commit)
 *     0: Halt on empty commit
 *     1: Allow empty commit
 *     2: Drop empty commit
 */
static int allow_empty(struct repository *r,
		       struct replay_opts *opts,
		       struct commit *commit)
{}

static struct {} todo_command_info[] =;

static const char *command_to_string(const enum todo_command command)
{}

static char command_to_char(const enum todo_command command)
{}

static int is_noop(const enum todo_command command)
{}

static int is_fixup(enum todo_command command)
{}

/* Does this command create a (non-merge) commit? */
static int is_pick_or_similar(enum todo_command command)
{}

enum todo_item_flags {};

static const char first_commit_msg_str[] =);
static const char nth_commit_msg_fmt[] =);
static const char skip_first_commit_msg_str[] =);
static const char skip_nth_commit_msg_fmt[] =);
static const char combined_commit_msg_fmt[] =);

static int is_fixup_flag(enum todo_command command, unsigned flag)
{}

/*
 * Wrapper around strbuf_add_commented_lines() which avoids double
 * commenting commit subjects.
 */
static void add_commented_lines(struct strbuf *buf, const void *str, size_t len)
{}

/* Does the current fixup chain contain a squash command? */
static int seen_squash(struct replay_ctx *ctx)
{}

static void update_comment_bufs(struct strbuf *buf1, struct strbuf *buf2, int n)
{}

/*
 * Comment out any un-commented commit messages, updating the message comments
 * to say they will be skipped but do not comment out the empty lines that
 * surround commit messages and their comments.
 */
static void update_squash_message_for_fixup(struct strbuf *msg)
{}

static int append_squash_message(struct strbuf *buf, const char *body,
			 enum todo_command command, struct replay_opts *opts,
			 unsigned flag)
{}

static int update_squash_messages(struct repository *r,
				  enum todo_command command,
				  struct commit *commit,
				  struct replay_opts *opts,
				  unsigned flag)
{}

static void flush_rewritten_pending(void)
{}

static void record_in_rewritten(struct object_id *oid,
		enum todo_command next_command)
{}

static int should_edit(struct replay_opts *opts) {}

static void refer_to_commit(struct replay_opts *opts,
			    struct strbuf *msgbuf, struct commit *commit)
{}

static int do_pick_commit(struct repository *r,
			  struct todo_item *item,
			  struct replay_opts *opts,
			  int final_fixup, int *check_todo)
{}

static int prepare_revs(struct replay_opts *opts)
{}

static int read_and_refresh_cache(struct repository *r,
				  struct replay_opts *opts)
{}

void todo_list_release(struct todo_list *todo_list)
{}

static struct todo_item *append_new_todo(struct todo_list *todo_list)
{}

const char *todo_item_get_arg(struct todo_list *todo_list,
			      struct todo_item *item)
{}

static int is_command(enum todo_command command, const char **bol)
{}

static int check_label_or_ref_arg(enum todo_command command, const char *arg)
{}

static int check_merge_commit_insn(enum todo_command command)
{}

static int parse_insn_line(struct repository *r, struct replay_opts *opts,
			   struct todo_item *item, const char *buf,
			   const char *bol, char *eol)
{}

int sequencer_get_last_command(struct repository *r UNUSED, enum replay_action *action)
{}

int todo_list_parse_insn_buffer(struct repository *r, struct replay_opts *opts,
				char *buf, struct todo_list *todo_list)
{}

static int count_commands(struct todo_list *todo_list)
{}

static int get_item_line_offset(struct todo_list *todo_list, int index)
{}

static const char *get_item_line(struct todo_list *todo_list, int index)
{}

static int get_item_line_length(struct todo_list *todo_list, int index)
{}

static ssize_t strbuf_read_file_or_whine(struct strbuf *sb, const char *path)
{}

static int have_finished_the_last_pick(void)
{}

void sequencer_post_commit_cleanup(struct repository *r, int verbose)
{}

static void todo_list_write_total_nr(struct todo_list *todo_list)
{}

static int read_populate_todo(struct repository *r,
			      struct todo_list *todo_list,
			      struct replay_opts *opts)
{}

static int git_config_string_dup(char **dest,
				 const char *var, const char *value)
{}

static int populate_opts_cb(const char *key, const char *value,
			    const struct config_context *ctx,
			    void *data)
{}

static void parse_strategy_opts(struct replay_opts *opts, char *raw_opts)
{}

static void read_strategy_opts(struct replay_opts *opts, struct strbuf *buf)
{}

static int read_populate_opts(struct replay_opts *opts)
{}

static void write_strategy_opts(struct replay_opts *opts)
{}

int write_basic_state(struct replay_opts *opts, const char *head_name,
		      struct commit *onto, const struct object_id *orig_head)
{}

static int walk_revs_populate_todo(struct todo_list *todo_list,
				struct replay_opts *opts)
{}

static int create_seq_dir(struct repository *r)
{}

static int save_head(const char *head)
{}

static int rollback_is_safe(void)
{}

static int reset_merge(const struct object_id *oid)
{}

static int rollback_single_pick(struct repository *r)
{}

static int skip_single_pick(void)
{}

int sequencer_rollback(struct repository *r, struct replay_opts *opts)
{}

int sequencer_skip(struct repository *r, struct replay_opts *opts)
{}

static int save_todo(struct todo_list *todo_list, struct replay_opts *opts,
		     int reschedule)
{}

static int save_opts(struct replay_opts *opts)
{}

static int make_patch(struct repository *r,
		      struct commit *commit,
		      struct replay_opts *opts)
{}

static int intend_to_amend(void)
{}

static int error_with_patch(struct repository *r,
			    struct commit *commit,
			    const char *subject, int subject_len,
			    struct replay_opts *opts,
			    int exit_code, int to_amend)
{}

static int error_failed_squash(struct repository *r,
			       struct commit *commit,
			       struct replay_opts *opts,
			       int subject_len,
			       const char *subject)
{}

static int do_exec(struct repository *r, const char *command_line, int quiet)
{}

__attribute__((format (printf, 2, 3)))
static int safe_append(const char *filename, const char *fmt, ...)
{}

static int do_label(struct repository *r, const char *name, int len)
{}

static const char *sequencer_reflog_action(struct replay_opts *opts)
{}

__attribute__((format (printf, 3, 4)))
static const char *reflog_message(struct replay_opts *opts,
	const char *sub_action, const char *fmt, ...)
{}

static struct commit *lookup_label(struct repository *r, const char *label,
				   int len, struct strbuf *buf)
{}

static int do_reset(struct repository *r,
		    const char *name, int len,
		    struct replay_opts *opts)
{}

static int do_merge(struct repository *r,
		    struct commit *commit,
		    const char *arg, int arg_len,
		    int flags, int *check_todo, struct replay_opts *opts)
{}

static int write_update_refs_state(struct string_list *refs_to_oids)
{}

/*
 * Parse the update-refs file for the current rebase, then remove the
 * refs that do not appear in the todo_list (and have not had updated
 * values stored) and add refs that are in the todo_list but not
 * represented in the update-refs file.
 *
 * If there are changes to the update-refs list, then write the new state
 * to disk.
 */
void todo_list_filter_update_refs(struct repository *r,
				  struct todo_list *todo_list)
{}

static int do_update_ref(struct repository *r, const char *refname)
{}

static int do_update_refs(struct repository *r, int quiet)
{}

static int is_final_fixup(struct todo_list *todo_list)
{}

static enum todo_command peek_command(struct todo_list *todo_list, int offset)
{}

static void create_autostash_internal(struct repository *r,
				      const char *path,
				      const char *refname)
{}

void create_autostash(struct repository *r, const char *path)
{}

void create_autostash_ref(struct repository *r, const char *refname)
{}

static int apply_save_autostash_oid(const char *stash_oid, int attempt_apply)
{}

static int apply_save_autostash(const char *path, int attempt_apply)
{}

int save_autostash(const char *path)
{}

int apply_autostash(const char *path)
{}

int apply_autostash_oid(const char *stash_oid)
{}

static int apply_save_autostash_ref(struct repository *r, const char *refname,
				    int attempt_apply)
{}

int save_autostash_ref(struct repository *r, const char *refname)
{}

int apply_autostash_ref(struct repository *r, const char *refname)
{}

static int checkout_onto(struct repository *r, struct replay_opts *opts,
			 const char *onto_name, const struct object_id *onto,
			 const struct object_id *orig_head)
{}

static int stopped_at_head(struct repository *r)
{}

static int reread_todo_if_changed(struct repository *r,
				  struct todo_list *todo_list,
				  struct replay_opts *opts)
{}

static const char rescheduled_advice[] =);

static int pick_one_commit(struct repository *r,
			   struct todo_list *todo_list,
			   struct replay_opts *opts,
			   int *check_todo, int* reschedule)
{}

static int pick_commits(struct repository *r,
			struct todo_list *todo_list,
			struct replay_opts *opts)
{}

static int continue_single_pick(struct repository *r, struct replay_opts *opts)
{}

static int commit_staged_changes(struct repository *r,
				 struct replay_opts *opts,
				 struct todo_list *todo_list)
{}

int sequencer_continue(struct repository *r, struct replay_opts *opts)
{}

static int single_pick(struct repository *r,
		       struct commit *cmit,
		       struct replay_opts *opts)
{}

int sequencer_pick_revisions(struct repository *r,
			     struct replay_opts *opts)
{}

void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)
{}

struct labels_entry {};

static int labels_cmp(const void *fndata UNUSED,
		      const struct hashmap_entry *eptr,
		      const struct hashmap_entry *entry_or_key, const void *key)
{}

struct string_entry {};

struct label_state {};

static const char *label_oid(struct object_id *oid, const char *label,
			     struct label_state *state)
{}

static int make_script_with_merges(struct pretty_print_context *pp,
				   struct rev_info *revs, struct strbuf *out,
				   unsigned flags)
{}

int sequencer_make_script(struct repository *r, struct strbuf *out, int argc,
			  const char **argv, unsigned flags)
{}

/*
 * Add commands after pick and (series of) squash/fixup commands
 * in the todo list.
 */
static void todo_list_add_exec_commands(struct todo_list *todo_list,
					struct string_list *commands)
{}

static void todo_list_to_strbuf(struct repository *r,
				struct todo_list *todo_list,
				struct strbuf *buf, int num, unsigned flags)
{}

int todo_list_write_to_file(struct repository *r, struct todo_list *todo_list,
			    const char *file, const char *shortrevisions,
			    const char *shortonto, int num, unsigned flags)
{}

/* skip picking commits whose parents are unchanged */
static int skip_unnecessary_picks(struct repository *r,
				  struct todo_list *todo_list,
				  struct object_id *base_oid)
{}

struct todo_add_branch_context {};

static int add_decorations_to_list(const struct commit *commit,
				   struct todo_add_branch_context *ctx)
{}

/*
 * For each 'pick' command, find out if the commit has a decoration in
 * refs/heads/. If so, then add a 'label for-update-refs/' command.
 */
static int todo_list_add_update_ref_commands(struct todo_list *todo_list)
{}

int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags,
		    const char *shortrevisions, const char *onto_name,
		    struct commit *onto, const struct object_id *orig_head,
		    struct string_list *commands, unsigned autosquash,
		    unsigned update_refs,
		    struct todo_list *todo_list)
{}

struct subject2item_entry {};

static int subject2item_cmp(const void *fndata UNUSED,
			    const struct hashmap_entry *eptr,
			    const struct hashmap_entry *entry_or_key,
			    const void *key)
{}

define_commit_slab(commit_todo_item, struct todo_item *);

static int skip_fixupish(const char *subject, const char **p) {}

/*
 * Rearrange the todo list that has both "pick commit-id msg" and "pick
 * commit-id fixup!/squash! msg" in it so that the latter is put immediately
 * after the former, and change "pick" to "fixup"/"squash".
 *
 * Note that if the config has specified a custom instruction format, each log
 * message will have to be retrieved from the commit (as the oneline in the
 * script cannot be trusted) in order to normalize the autosquash arrangement.
 */
int todo_list_rearrange_squash(struct todo_list *todo_list)
{}

int sequencer_determine_whence(struct repository *r, enum commit_whence *whence)
{}

int sequencer_get_update_refs_state(const char *wt_dir,
				    struct string_list *refs)
{}