checkout_merged(): squelch false warning from some gcc
[gitweb.git] / builtin / revert.c
index 1ca08da5eccc4aeeb3b92834bc58ae61b41d837f..f697e6695374d06e7b08c9faac1ebaefe4ff31d7 100644 (file)
@@ -3,7 +3,6 @@
 #include "object.h"
 #include "commit.h"
 #include "tag.h"
-#include "wt-status.h"
 #include "run-command.h"
 #include "exec_cmd.h"
 #include "utf8.h"
@@ -77,7 +76,8 @@ static void parse_args(int argc, const char **argv)
        struct option options[] = {
                OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"),
                OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"),
-               OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"),
+               { OPTION_BOOLEAN, 'r', NULL, &noop, NULL, "no-op (backward compatibility)",
+                 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 0 },
                OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
                OPT_INTEGER('m', "mainline", &mainline, "parent number"),
                OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
@@ -198,54 +198,20 @@ static void add_message_to_msg(struct strbuf *msgbuf, const char *message)
        strbuf_addstr(msgbuf, p);
 }
 
-static void set_author_ident_env(const char *message)
+static void write_cherry_pick_head(void)
 {
-       const char *p = message;
-       if (!p)
-               die (_("Could not read commit message of %s"),
-                               sha1_to_hex(commit->object.sha1));
-       while (*p && *p != '\n') {
-               const char *eol;
-
-               for (eol = p; *eol && *eol != '\n'; eol++)
-                       ; /* do nothing */
-               if (!prefixcmp(p, "author ")) {
-                       char *line, *pend, *email, *timestamp;
-
-                       p += 7;
-                       line = xmemdupz(p, eol - p);
-                       email = strchr(line, '<');
-                       if (!email)
-                               die (_("Could not extract author email from %s"),
-                                       sha1_to_hex(commit->object.sha1));
-                       if (email == line)
-                               pend = line;
-                       else
-                               for (pend = email; pend != line + 1 &&
-                                               isspace(pend[-1]); pend--);
-                                       ; /* do nothing */
-                       *pend = '\0';
-                       email++;
-                       timestamp = strchr(email, '>');
-                       if (!timestamp)
-                               die (_("Could not extract author time from %s"),
-                                       sha1_to_hex(commit->object.sha1));
-                       *timestamp = '\0';
-                       for (timestamp++; *timestamp && isspace(*timestamp);
-                                       timestamp++)
-                               ; /* do nothing */
-                       setenv("GIT_AUTHOR_NAME", line, 1);
-                       setenv("GIT_AUTHOR_EMAIL", email, 1);
-                       setenv("GIT_AUTHOR_DATE", timestamp, 1);
-                       free(line);
-                       return;
-               }
-               p = eol;
-               if (*p == '\n')
-                       p++;
-       }
-       die (_("No author information found in %s"),
-                       sha1_to_hex(commit->object.sha1));
+       int fd;
+       struct strbuf buf = STRBUF_INIT;
+
+       strbuf_addf(&buf, "%s\n", sha1_to_hex(commit->object.sha1));
+
+       fd = open(git_path("CHERRY_PICK_HEAD"), O_WRONLY | O_CREAT, 0666);
+       if (fd < 0)
+               die_errno(_("Could not open '%s' for writing"),
+                         git_path("CHERRY_PICK_HEAD"));
+       if (write_in_full(fd, buf.buf, buf.len) != buf.len || close(fd))
+               die_errno(_("Could not write to '%s'"), git_path("CHERRY_PICK_HEAD"));
+       strbuf_release(&buf);
 }
 
 static void advise(const char *advice, ...)
@@ -263,15 +229,18 @@ static void print_advice(void)
 
        if (msg) {
                fprintf(stderr, "%s\n", msg);
+               /*
+                * A conflict has occured but the porcelain
+                * (typically rebase --interactive) wants to take care
+                * of the commit itself so remove CHERRY_PICK_HEAD
+                */
+               unlink(git_path("CHERRY_PICK_HEAD"));
                return;
        }
 
        advise("after resolving the conflicts, mark the corrected paths");
        advise("with 'git add <paths>' or 'git rm <paths>'");
-
-       if (action == CHERRY_PICK)
-               advise("and commit the result with 'git commit -c %s'",
-                      find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
+       advise("and commit the result with 'git commit'");
 }
 
 static void write_message(struct strbuf *msgbuf, const char *filename)
@@ -302,11 +271,19 @@ static NORETURN void die_dirty_index(const char *me)
        if (read_cache_unmerged()) {
                die_resolve_conflict(me);
        } else {
-               if (advice_commit_before_merge)
-                       die("Your local changes would be overwritten by %s.\n"
-                           "Please, commit your changes or stash them to proceed.", me);
-               else
-                       die("Your local changes would be overwritten by %s.\n", me);
+               if (advice_commit_before_merge) {
+                       if (action == REVERT)
+                               die(_("Your local changes would be overwritten by revert.\n"
+                                         "Please, commit your changes or stash them to proceed."));
+                       else
+                               die(_("Your local changes would be overwritten by cherry-pick.\n"
+                                         "Please, commit your changes or stash them to proceed."));
+               } else {
+                       if (action == REVERT)
+                               die(_("Your local changes would be overwritten by revert.\n"));
+                       else
+                               die(_("Your local changes would be overwritten by cherry-pick.\n"));
+               }
        }
 }
 
@@ -354,7 +331,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
        if (active_cache_changed &&
            (write_cache(index_fd, active_cache, active_nr) ||
             commit_locked_index(&index_lock)))
-               die("%s: Unable to write new index file", me);
+               /* TRANSLATORS: %s will be "revert" or "cherry-pick" */
+               die(_("%s: Unable to write new index file"), me);
        rollback_lock_file(&index_lock);
 
        if (!clean) {
@@ -461,7 +439,9 @@ static int do_pick_commit(void)
                return fast_forward_to(commit->object.sha1, head);
 
        if (parent && parse_commit(parent) < 0)
-               die("%s: cannot parse parent commit %s",
+               /* TRANSLATORS: The first %s will be "revert" or
+                  "cherry-pick", the second %s a SHA1 */
+               die(_("%s: cannot parse parent commit %s"),
                    me, sha1_to_hex(parent->object.sha1));
 
        if (get_message(commit->buffer, &msg) != 0)
@@ -497,13 +477,14 @@ static int do_pick_commit(void)
                base_label = msg.parent_label;
                next = commit;
                next_label = msg.label;
-               set_author_ident_env(msg.message);
                add_message_to_msg(&msgbuf, msg.message);
                if (no_replay) {
                        strbuf_addstr(&msgbuf, "(cherry picked from commit ");
                        strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
                        strbuf_addstr(&msgbuf, ")\n");
                }
+               if (!no_commit)
+                       write_cherry_pick_head();
        }
 
        if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) {
@@ -525,8 +506,9 @@ static int do_pick_commit(void)
        }
 
        if (res) {
-               error("could not %s %s... %s",
-                     action == REVERT ? "revert" : "apply",
+               error(action == REVERT
+                     ? _("could not revert %s... %s")
+                     : _("could not apply %s... %s"),
                      find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),
                      msg.subject);
                print_advice();