builtin/help.c: add list_common_guides_help() function
[gitweb.git] / sequencer.c
index 965b954baf65dc81e1e219ef3a91234b76ab5c73..baa031052e4e3f77bb6d4a257a5669ca5a5d617e 100644 (file)
@@ -269,14 +269,15 @@ static int error_dirty_index(struct replay_opts *opts)
        return -1;
 }
 
-static int fast_forward_to(const unsigned char *to, const unsigned char *from)
+static int fast_forward_to(const unsigned char *to, const unsigned char *from,
+                          int unborn)
 {
        struct ref_lock *ref_lock;
 
        read_cache();
        if (checkout_fast_forward(from, to, 1))
                exit(1); /* the callee should have complained already */
-       ref_lock = lock_any_ref_for_update("HEAD", from, 0);
+       ref_lock = lock_any_ref_for_update("HEAD", unborn ? null_sha1 : from, 0);
        return write_ref_sha1(ref_lock, to, "cherry-pick");
 }
 
@@ -473,7 +474,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
        struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
        char *defmsg = NULL;
        struct strbuf msgbuf = STRBUF_INIT;
-       int res;
+       int res, unborn = 0;
 
        if (opts->no_commit) {
                /*
@@ -485,9 +486,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
                if (write_cache_as_tree(head, 0, NULL))
                        die (_("Your index file is unmerged."));
        } else {
-               if (get_sha1("HEAD", head))
-                       return error(_("You do not have a valid HEAD"));
-               if (index_differs_from("HEAD", 0))
+               unborn = get_sha1("HEAD", head);
+               if (unborn)
+                       hashcpy(head, EMPTY_TREE_SHA1_BIN);
+               if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", 0))
                        return error_dirty_index(opts);
        }
        discard_cache();
@@ -518,8 +520,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
        else
                parent = commit->parents->item;
 
-       if (opts->allow_ff && parent && !hashcmp(parent->object.sha1, head))
-               return fast_forward_to(commit->object.sha1, head);
+       if (opts->allow_ff &&
+           ((parent && !hashcmp(parent->object.sha1, head)) ||
+            (!parent && unborn)))
+            return fast_forward_to(commit->object.sha1, head, unborn);
 
        if (parent && parse_commit(parent) < 0)
                /* TRANSLATORS: The first %s will be "revert" or
@@ -1123,8 +1127,42 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
        else
                has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer);
 
-       if (!has_footer)
-               strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, "\n", 1);
+       if (!has_footer) {
+               const char *append_newlines = NULL;
+               size_t len = msgbuf->len - ignore_footer;
+
+               if (!len) {
+                       /*
+                        * The buffer is completely empty.  Leave foom for
+                        * 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
+                        * so that we leave room for the title and body.
+                        */
+                       append_newlines = "\n";
+               } else if (msgbuf->buf[len - 2] != '\n') {
+                       /*
+                        * Buffer ends with a single newline.  Add another
+                        * so that there is an empty line between the message
+                        * body and the sob.
+                        */
+                       append_newlines = "\n";
+               } /* else, the buffer already ends with two newlines. */
+
+               if (append_newlines)
+                       strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
+                               append_newlines, strlen(append_newlines));
+       }
 
        if (has_footer != 3 && (!no_dup_sob || has_footer != 2))
                strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,