sequencer: support a new action: 'interactive rebase'
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Mon, 2 Jan 2017 15:26:28 +0000 (16:26 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Jan 2017 22:57:29 +0000 (14:57 -0800)
This patch introduces a new action for the sequencer. It really does not
do a whole lot of its own right now, but lays the ground work for
patches to come. The intention, of course, is to finally make the
sequencer the work horse of the interactive rebase (the original idea
behind the "sequencer" concept).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sequencer.c
sequencer.h
index 720857bedaa051a30663dab2fff11bf25d52fd66..690460bc6759ab4bfbd046b941742b5e39eedba4 100644 (file)
@@ -30,6 +30,14 @@ 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'.
+ */
+static GIT_PATH_FUNC(rebase_path_todo, "rebase-merge/git-rebase-todo")
 /*
  * 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
@@ -42,19 +50,22 @@ static GIT_PATH_FUNC(rebase_path_author_script, "rebase-merge/author-script")
  */
 static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
 
-/* We will introduce the 'interactive rebase' mode later */
 static inline int is_rebase_i(const struct replay_opts *opts)
 {
-       return 0;
+       return opts->action == REPLAY_INTERACTIVE_REBASE;
 }
 
 static const char *get_dir(const struct replay_opts *opts)
 {
+       if (is_rebase_i(opts))
+               return rebase_path();
        return git_path_seq_dir();
 }
 
 static const char *get_todo_path(const struct replay_opts *opts)
 {
+       if (is_rebase_i(opts))
+               return rebase_path_todo();
        return git_path_todo_file();
 }
 
@@ -122,7 +133,15 @@ int sequencer_remove_state(struct replay_opts *opts)
 
 static const char *action_name(const struct replay_opts *opts)
 {
-       return opts->action == REPLAY_REVERT ? N_("revert") : N_("cherry-pick");
+       switch (opts->action) {
+       case REPLAY_REVERT:
+               return N_("revert");
+       case REPLAY_PICK:
+               return N_("cherry-pick");
+       case REPLAY_INTERACTIVE_REBASE:
+               return N_("rebase -i");
+       }
+       die(_("Unknown action: %d"), opts->action);
 }
 
 struct commit_message {
@@ -364,7 +383,9 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
 
        if (active_cache_changed &&
            write_locked_index(&the_index, &index_lock, COMMIT_LOCK))
-               /* TRANSLATORS: %s will be "revert" or "cherry-pick" */
+               /* TRANSLATORS: %s will be "revert", "cherry-pick" or
+                * "rebase -i".
+                */
                return error(_("%s: Unable to write new index file"),
                        _(action_name(opts)));
        rollback_lock_file(&index_lock);
@@ -1198,6 +1219,13 @@ static int save_todo(struct todo_list *todo_list, struct replay_opts *opts)
        const char *todo_path = get_todo_path(opts);
        int next = todo_list->current, offset, fd;
 
+       /*
+        * rebase -i writes "git-rebase-todo" without the currently executing
+        * command, appending it to "done" instead.
+        */
+       if (is_rebase_i(opts))
+               next++;
+
        fd = hold_lock_file_for_update(&todo_lock, todo_path, 0);
        if (fd < 0)
                return error_errno(_("could not lock '%s'"), todo_path);
index 7a513c576bdccf8730828fdaa586ec9d0af4af6b..cb21cfddeec5db9cf74b37d179ea0b1f8c9b147f 100644 (file)
@@ -7,7 +7,8 @@ const char *git_path_seq_dir(void);
 
 enum replay_action {
        REPLAY_REVERT,
-       REPLAY_PICK
+       REPLAY_PICK,
+       REPLAY_INTERACTIVE_REBASE
 };
 
 struct replay_opts {