merge-recursive: enforce rule that index matches head before merging
[gitweb.git] / sequencer.c
index 6ee251849d7a45a989b28a9f87bd9c6ca95c22ba..f9d1001dee9ad10e243aaeafc46fbdd13597fce7 100644 (file)
@@ -1868,22 +1868,31 @@ static int count_commands(struct todo_list *todo_list)
        return count;
 }
 
+static ssize_t strbuf_read_file_or_whine(struct strbuf *sb, const char *path)
+{
+       int fd;
+       ssize_t len;
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return error_errno(_("could not open '%s'"), path);
+       len = strbuf_read(sb, fd, 0);
+       close(fd);
+       if (len < 0)
+               return error(_("could not read '%s'."), path);
+       return len;
+}
+
 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;
+       int res;
 
        strbuf_reset(&todo_list->buf);
-       fd = open(todo_file, O_RDONLY);
-       if (fd < 0)
-               return error_errno(_("could not open '%s'"), todo_file);
-       if (strbuf_read(&todo_list->buf, fd, 0) < 0) {
-               close(fd);
-               return error(_("could not read '%s'."), todo_file);
-       }
-       close(fd);
+       if (strbuf_read_file_or_whine(&todo_list->buf, todo_file) < 0)
+               return -1;
 
        res = stat(todo_file, &st);
        if (res)
@@ -2309,6 +2318,9 @@ static int make_patch(struct commit *commit, struct replay_opts *opts)
        p = short_commit_name(commit);
        if (write_message(p, strlen(p), rebase_path_stopped_sha(), 1) < 0)
                return -1;
+       if (update_ref("rebase", "REBASE_HEAD", &commit->object.oid,
+                      NULL, REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR))
+               res |= error(_("could not update %s"), "REBASE_HEAD");
 
        strbuf_addf(&buf, "%s/patch", get_dir(opts));
        memset(&log_tree_opt, 0, sizeof(log_tree_opt));
@@ -2560,6 +2572,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                        unlink(rebase_path_author_script());
                        unlink(rebase_path_stopped_sha());
                        unlink(rebase_path_amend());
+                       delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
                }
                if (item->command <= TODO_SQUASH) {
                        if (is_rebase_i(opts))
@@ -2865,7 +2878,7 @@ int sequencer_pick_revisions(struct replay_opts *opts)
                        if (!lookup_commit_reference_gently(&oid, 1)) {
                                enum object_type type = sha1_object_info(oid.hash, NULL);
                                return error(_("%s: can't cherry-pick a %s"),
-                                       name, typename(type));
+                                       name, type_name(type));
                        }
                } else
                        return error(_("%s: bad revision"), name);
@@ -3146,20 +3159,13 @@ int check_todo_list(void)
        struct strbuf todo_file = STRBUF_INIT;
        struct todo_list todo_list = TODO_LIST_INIT;
        struct strbuf missing = STRBUF_INIT;
-       int advise_to_edit_todo = 0, res = 0, fd, i;
+       int advise_to_edit_todo = 0, res = 0, i;
 
        strbuf_addstr(&todo_file, rebase_path_todo());
-       fd = open(todo_file.buf, O_RDONLY);
-       if (fd < 0) {
-               res = error_errno(_("could not open '%s'"), todo_file.buf);
-               goto leave_check;
-       }
-       if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
-               close(fd);
-               res = error(_("could not read '%s'."), todo_file.buf);
+       if (strbuf_read_file_or_whine(&todo_list.buf, todo_file.buf) < 0) {
+               res = -1;
                goto leave_check;
        }
-       close(fd);
        advise_to_edit_todo = res =
                parse_insn_buffer(todo_list.buf.buf, &todo_list);
 
@@ -3175,17 +3181,10 @@ int check_todo_list(void)
 
        todo_list_release(&todo_list);
        strbuf_addstr(&todo_file, ".backup");
-       fd = open(todo_file.buf, O_RDONLY);
-       if (fd < 0) {
-               res = error_errno(_("could not open '%s'"), todo_file.buf);
-               goto leave_check;
-       }
-       if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
-               close(fd);
-               res = error(_("could not read '%s'."), todo_file.buf);
+       if (strbuf_read_file_or_whine(&todo_list.buf, todo_file.buf) < 0) {
+               res = -1;
                goto leave_check;
        }
-       close(fd);
        strbuf_release(&todo_file);
        res = !!parse_insn_buffer(todo_list.buf.buf, &todo_list);
 
@@ -3266,15 +3265,8 @@ int skip_unnecessary_picks(void)
        }
        strbuf_release(&buf);
 
-       fd = open(todo_file, O_RDONLY);
-       if (fd < 0) {
-               return error_errno(_("could not open '%s'"), todo_file);
-       }
-       if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
-               close(fd);
-               return error(_("could not read '%s'."), todo_file);
-       }
-       close(fd);
+       if (strbuf_read_file_or_whine(&todo_list.buf, todo_file) < 0)
+               return -1;
        if (parse_insn_buffer(todo_list.buf.buf, &todo_list) < 0) {
                todo_list_release(&todo_list);
                return -1;
@@ -3365,17 +3357,11 @@ int rearrange_squash(void)
        const char *todo_file = rebase_path_todo();
        struct todo_list todo_list = TODO_LIST_INIT;
        struct hashmap subject2item;
-       int res = 0, rearranged = 0, *next, *tail, fd, i;
+       int res = 0, rearranged = 0, *next, *tail, i;
        char **subjects;
 
-       fd = open(todo_file, O_RDONLY);
-       if (fd < 0)
-               return error_errno(_("could not open '%s'"), todo_file);
-       if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
-               close(fd);
-               return error(_("could not read '%s'."), todo_file);
-       }
-       close(fd);
+       if (strbuf_read_file_or_whine(&todo_list.buf, todo_file) < 0)
+               return -1;
        if (parse_insn_buffer(todo_list.buf.buf, &todo_list) < 0) {
                todo_list_release(&todo_list);
                return -1;