Merge branch 'js/bs-is-a-dir-sep-on-windows' into maint
[gitweb.git] / sequencer.c
index 130cc868e511e646badde9ebc0894602e27ea37b..8c72cf16145dc80edec90c6d4fb68811c0c65399 100644 (file)
@@ -464,7 +464,8 @@ 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", "cherry-pick" or
+               /*
+                * TRANSLATORS: %s will be "revert", "cherry-pick" or
                 * "rebase -i".
                 */
                return error(_("%s: Unable to write new index file"),
@@ -1045,6 +1046,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                        strbuf_addstr(&msgbuf, p);
 
                if (opts->record_origin) {
+                       strbuf_complete_line(&msgbuf);
                        if (!has_conforming_footer(&msgbuf, NULL, 0))
                                strbuf_addch(&msgbuf, '\n');
                        strbuf_addstr(&msgbuf, cherry_picked_prefix);
@@ -1200,6 +1202,7 @@ struct todo_list {
        struct todo_item *items;
        int nr, alloc, current;
        int done_nr, total_nr;
+       struct stat_data stat;
 };
 
 #define TODO_LIST_INIT { STRBUF_INIT }
@@ -1330,6 +1333,7 @@ static int count_commands(struct todo_list *todo_list)
 static int read_populate_todo(struct todo_list *todo_list,
                        struct replay_opts *opts)
 {
+       struct stat st;
        const char *todo_file = get_todo_path(opts);
        int fd, res;
 
@@ -1343,6 +1347,11 @@ static int read_populate_todo(struct todo_list *todo_list,
        }
        close(fd);
 
+       res = stat(todo_file, &st);
+       if (res)
+               return error(_("could not stat '%s'"), todo_file);
+       fill_stat_data(&todo_list->stat, &st);
+
        res = parse_insn_buffer(todo_list->buf.buf, todo_list);
        if (res) {
                if (is_rebase_i(opts))
@@ -1906,11 +1915,13 @@ static int apply_autostash(struct replay_opts *opts)
        strbuf_trim(&stash_sha1);
 
        child.git_cmd = 1;
+       child.no_stdout = 1;
+       child.no_stderr = 1;
        argv_array_push(&child.args, "stash");
        argv_array_push(&child.args, "apply");
        argv_array_push(&child.args, stash_sha1.buf);
        if (!run_command(&child))
-               printf(_("Applied autostash."));
+               printf(_("Applied autostash.\n"));
        else {
                struct child_process store = CHILD_PROCESS_INIT;
 
@@ -2028,10 +2039,25 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                } else if (item->command == TODO_EXEC) {
                        char *end_of_arg = (char *)(item->arg + item->arg_len);
                        int saved = *end_of_arg;
+                       struct stat st;
 
                        *end_of_arg = '\0';
                        res = do_exec(item->arg);
                        *end_of_arg = saved;
+
+                       /* Reread the todo file if it has changed. */
+                       if (res)
+                               ; /* fall through */
+                       else if (stat(get_todo_path(opts), &st))
+                               res = error_errno(_("could not stat '%s'"),
+                                                 get_todo_path(opts));
+                       else if (match_stat_data(&todo_list->stat, &st)) {
+                               todo_list_release(todo_list);
+                               if (read_populate_todo(todo_list, opts))
+                                       res = -1; /* message was printed */
+                               /* `current` will be incremented below */
+                               todo_list->current = -1;
+                       }
                } else if (!is_noop(item->command))
                        return error(_("unknown command %d"), item->command);
 
@@ -2066,6 +2092,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                                res = error(_("could not read orig-head"));
                                goto cleanup_head_ref;
                        }
+                       strbuf_reset(&buf);
                        if (!read_oneliner(&buf, rebase_path_onto(), 0)) {
                                res = error(_("could not read 'onto'"));
                                goto cleanup_head_ref;
@@ -2335,6 +2362,9 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
                                getenv("GIT_COMMITTER_EMAIL")));
        strbuf_addch(&sob, '\n');
 
+       if (!ignore_footer)
+               strbuf_complete_line(msgbuf);
+
        /*
         * If the whole message buffer is equal to the sob, pretend that we
         * found a conforming footer with a matching sob
@@ -2355,13 +2385,6 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
                         * the title and body to be filled in by the user.
                         */
                        append_newlines = "\n\n";
-               } else if (msgbuf->buf[len - 1] != '\n') {
-                       /*
-                        * Incomplete line.  Complete the line and add a
-                        * blank one so that there is an empty line between
-                        * the message body and the sob.
-                        */
-                       append_newlines = "\n\n";
                } else if (len == 1) {
                        /*
                         * Buffer contains a single newline.  Add another