sequencer: lib'ify save_todo()
[gitweb.git] / sequencer.c
index c73cdfdac112318829613119a56369ab70a22929..32c53bb2b7138dc0fe2f21f81fc3b0bec098ebdd 100644 (file)
@@ -808,12 +808,20 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
        return 0;
 }
 
-static void read_populate_opts(struct replay_opts **opts_ptr)
+static int read_populate_opts(struct replay_opts **opts)
 {
        if (!file_exists(git_path_opts_file()))
-               return;
-       if (git_config_from_file(populate_opts_cb, git_path_opts_file(), *opts_ptr) < 0)
-               die(_("Malformed options sheet: %s"), git_path_opts_file());
+               return 0;
+       /*
+        * The function git_parse_source(), called from git_config_from_file(),
+        * may die() in case of a syntactically incorrect file. We do not care
+        * about this case, though, because we wrote that file ourselves, so we
+        * are pretty certain that it is syntactically correct.
+        */
+       if (git_config_from_file(populate_opts_cb, git_path_opts_file(), *opts) < 0)
+               return error(_("Malformed options sheet: %s"),
+                       git_path_opts_file());
+       return 0;
 }
 
 static int walk_revs_populate_todo(struct commit_list **todo_list,
@@ -839,23 +847,33 @@ static int create_seq_dir(void)
                return -1;
        }
        else if (mkdir(git_path_seq_dir(), 0777) < 0)
-               die_errno(_("Could not create sequencer directory %s"),
-                         git_path_seq_dir());
+               return error_errno(_("Could not create sequencer directory %s"),
+                                  git_path_seq_dir());
        return 0;
 }
 
-static void save_head(const char *head)
+static int save_head(const char *head)
 {
        static struct lock_file head_lock;
        struct strbuf buf = STRBUF_INIT;
        int fd;
 
-       fd = hold_lock_file_for_update(&head_lock, git_path_head_file(), LOCK_DIE_ON_ERROR);
+       fd = hold_lock_file_for_update(&head_lock, git_path_head_file(), 0);
+       if (fd < 0) {
+               rollback_lock_file(&head_lock);
+               return error_errno(_("Could not lock HEAD"));
+       }
        strbuf_addf(&buf, "%s\n", head);
-       if (write_in_full(fd, buf.buf, buf.len) < 0)
-               die_errno(_("Could not write to %s"), git_path_head_file());
-       if (commit_lock_file(&head_lock) < 0)
-               die(_("Error wrapping up %s."), git_path_head_file());
+       if (write_in_full(fd, buf.buf, buf.len) < 0) {
+               rollback_lock_file(&head_lock);
+               return error_errno(_("Could not write to %s"),
+                                  git_path_head_file());
+       }
+       if (commit_lock_file(&head_lock) < 0) {
+               rollback_lock_file(&head_lock);
+               return error(_("Error wrapping up %s."), git_path_head_file());
+       }
+       return 0;
 }
 
 static int reset_for_rollback(const unsigned char *sha1)
@@ -925,24 +943,31 @@ static int sequencer_rollback(struct replay_opts *opts)
        return -1;
 }
 
-static void save_todo(struct commit_list *todo_list, struct replay_opts *opts)
+static int save_todo(struct commit_list *todo_list, struct replay_opts *opts)
 {
        static struct lock_file todo_lock;
        struct strbuf buf = STRBUF_INIT;
        int fd;
 
-       fd = hold_lock_file_for_update(&todo_lock, git_path_todo_file(), LOCK_DIE_ON_ERROR);
-       if (format_todo(&buf, todo_list, opts) < 0)
-               die(_("Could not format %s."), git_path_todo_file());
+       fd = hold_lock_file_for_update(&todo_lock, git_path_todo_file(), 0);
+       if (fd < 0)
+               return error_errno(_("Could not lock '%s'"),
+                                  git_path_todo_file());
+       if (format_todo(&buf, todo_list, opts) < 0) {
+               strbuf_release(&buf);
+               return error(_("Could not format %s."), git_path_todo_file());
+       }
        if (write_in_full(fd, buf.buf, buf.len) < 0) {
                strbuf_release(&buf);
-               die_errno(_("Could not write to %s"), git_path_todo_file());
+               return error_errno(_("Could not write to %s"),
+                                  git_path_todo_file());
        }
        if (commit_lock_file(&todo_lock) < 0) {
                strbuf_release(&buf);
-               die(_("Error wrapping up %s."), git_path_todo_file());
+               return error(_("Error wrapping up %s."), git_path_todo_file());
        }
        strbuf_release(&buf);
+       return 0;
 }
 
 static void save_opts(struct replay_opts *opts)
@@ -991,7 +1016,8 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
                return -1;
 
        for (cur = todo_list; cur; cur = cur->next) {
-               save_todo(cur, opts);
+               if (save_todo(cur, opts))
+                       return -1;
                res = do_pick_commit(cur->item, opts);
                if (res)
                        return res;
@@ -1021,8 +1047,8 @@ static int sequencer_continue(struct replay_opts *opts)
 
        if (!file_exists(git_path_todo_file()))
                return continue_single_pick();
-       read_populate_opts(&opts);
-       if (read_populate_todo(&todo_list, opts))
+       if (read_populate_opts(&opts) ||
+                       read_populate_todo(&todo_list, opts))
                return -1;
 
        /* Verify that the conflict has been resolved */
@@ -1119,7 +1145,8 @@ int sequencer_pick_revisions(struct replay_opts *opts)
                return -1;
        if (get_sha1("HEAD", sha1) && (opts->action == REPLAY_REVERT))
                return error(_("Can't revert as initial commit"));
-       save_head(sha1_to_hex(sha1));
+       if (save_head(sha1_to_hex(sha1)))
+               return -1;
        save_opts(opts);
        return pick_commits(todo_list, opts);
 }