Merge branch 'jc/advise-i18n'
authorJunio C Hamano <gitster@pobox.com>
Wed, 1 Feb 2012 06:01:14 +0000 (22:01 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 1 Feb 2012 06:01:14 +0000 (22:01 -0800)
* jc/advise-i18n:
i18n of multi-line advice messages

1  2 
builtin/revert.c
diff --combined builtin/revert.c
index 0d8020cf640e1abe6898308a1656446b327c83f4,3ad14a1f98716cca4ddcfe9f8cbe8054409cde02..df63794e050b0a27082952f458d93e0b254ce310
@@@ -60,14 -60,13 +60,14 @@@ struct replay_opts 
        int allow_rerere_auto;
  
        int mainline;
 -      int commit_argc;
 -      const char **commit_argv;
  
        /* Merge strategy */
        const char *strategy;
        const char **xopts;
        size_t xopts_nr, xopts_alloc;
 +
 +      /* Only used by REPLAY_NONE */
 +      struct rev_info *revs;
  };
  
  #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
@@@ -170,9 -169,9 +170,9 @@@ static void parse_args(int argc, const 
                        die(_("program error"));
        }
  
 -      opts->commit_argc = parse_options(argc, argv, NULL, options, usage_str,
 -                                      PARSE_OPT_KEEP_ARGV0 |
 -                                      PARSE_OPT_KEEP_UNKNOWN);
 +      argc = parse_options(argc, argv, NULL, options, usage_str,
 +                      PARSE_OPT_KEEP_ARGV0 |
 +                      PARSE_OPT_KEEP_UNKNOWN);
  
        /* Check for incompatible subcommands */
        verify_opt_mutually_compatible(me,
                                NULL);
        }
  
 -      else if (opts->commit_argc < 2)
 -              usage_with_options(usage_str, options);
 -
        if (opts->allow_ff)
                verify_opt_compatible(me, "--ff",
                                "--signoff", opts->signoff,
                                "-x", opts->record_origin,
                                "--edit", opts->edit,
                                NULL);
 -      opts->commit_argv = argv;
 +
 +      if (opts->subcommand != REPLAY_NONE) {
 +              opts->revs = NULL;
 +      } else {
 +              opts->revs = xmalloc(sizeof(*opts->revs));
 +              init_revisions(opts->revs, NULL);
 +              opts->revs->no_walk = 1;
 +              if (argc < 2)
 +                      usage_with_options(usage_str, options);
 +              argc = setup_revisions(argc, argv, opts->revs, NULL);
 +      }
 +
 +      if (argc > 1)
 +              usage_with_options(usage_str, options);
  }
  
  struct commit_message {
@@@ -343,11 -332,10 +343,10 @@@ static void print_advice(int show_hint
                return;
        }
  
-       if (show_hint) {
-               advise("after resolving the conflicts, mark the corrected paths");
-               advise("with 'git add <paths>' or 'git rm <paths>'");
-               advise("and commit the result with 'git commit'");
-       }
+       if (show_hint)
+               advise(_("after resolving the conflicts, mark the corrected paths\n"
+                        "with 'git add <paths>' or 'git rm <paths>'\n"
+                        "and commit the result with 'git commit'"));
  }
  
  static void write_message(struct strbuf *msgbuf, const char *filename)
@@@ -642,15 -630,23 +641,15 @@@ static int do_pick_commit(struct commi
        return res;
  }
  
 -static void prepare_revs(struct rev_info *revs, struct replay_opts *opts)
 +static void prepare_revs(struct replay_opts *opts)
  {
 -      int argc;
 -
 -      init_revisions(revs, NULL);
 -      revs->no_walk = 1;
        if (opts->action != REVERT)
 -              revs->reverse = 1;
 -
 -      argc = setup_revisions(opts->commit_argc, opts->commit_argv, revs, NULL);
 -      if (argc > 1)
 -              usage(*revert_or_cherry_pick_usage(opts));
 +              opts->revs->reverse ^= 1;
  
 -      if (prepare_revision_walk(revs))
 +      if (prepare_revision_walk(opts->revs))
                die(_("revision walk setup failed"));
  
 -      if (!revs->commits)
 +      if (!opts->revs->commits)
                die(_("empty commit set passed"));
  }
  
@@@ -700,47 -696,44 +699,47 @@@ static int format_todo(struct strbuf *b
                struct replay_opts *opts)
  {
        struct commit_list *cur = NULL;
 -      struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
        const char *sha1_abbrev = NULL;
        const char *action_str = opts->action == REVERT ? "revert" : "pick";
 +      const char *subject;
 +      int subject_len;
  
        for (cur = todo_list; cur; cur = cur->next) {
                sha1_abbrev = find_unique_abbrev(cur->item->object.sha1, DEFAULT_ABBREV);
 -              if (get_message(cur->item, &msg))
 -                      return error(_("Cannot get commit message for %s"), sha1_abbrev);
 -              strbuf_addf(buf, "%s %s %s\n", action_str, sha1_abbrev, msg.subject);
 +              subject_len = find_commit_subject(cur->item->buffer, &subject);
 +              strbuf_addf(buf, "%s %s %.*s\n", action_str, sha1_abbrev,
 +                      subject_len, subject);
        }
        return 0;
  }
  
 -static struct commit *parse_insn_line(char *start, struct replay_opts *opts)
 +static struct commit *parse_insn_line(char *bol, char *eol, struct replay_opts *opts)
  {
        unsigned char commit_sha1[20];
 -      char sha1_abbrev[40];
        enum replay_action action;
 -      int insn_len = 0;
 -      char *p, *q;
 +      char *end_of_object_name;
 +      int saved, status, padding;
  
 -      if (!prefixcmp(start, "pick ")) {
 +      if (!prefixcmp(bol, "pick")) {
                action = CHERRY_PICK;
 -              insn_len = strlen("pick");
 -              p = start + insn_len + 1;
 -      } else if (!prefixcmp(start, "revert ")) {
 +              bol += strlen("pick");
 +      } else if (!prefixcmp(bol, "revert")) {
                action = REVERT;
 -              insn_len = strlen("revert");
 -              p = start + insn_len + 1;
 +              bol += strlen("revert");
        } else
                return NULL;
  
 -      q = strchr(p, ' ');
 -      if (!q)
 +      /* Eat up extra spaces/ tabs before object name */
 +      padding = strspn(bol, " \t");
 +      if (!padding)
                return NULL;
 -      q++;
 +      bol += padding;
  
 -      strlcpy(sha1_abbrev, p, q - p);
 +      end_of_object_name = bol + strcspn(bol, " \t\n");
 +      saved = *end_of_object_name;
 +      *end_of_object_name = '\0';
 +      status = get_sha1(bol, commit_sha1);
 +      *end_of_object_name = saved;
  
        /*
         * Verify that the action matches up with the one in
                return NULL;
        }
  
 -      if (get_sha1(sha1_abbrev, commit_sha1) < 0)
 +      if (status < 0)
                return NULL;
  
        return lookup_commit_reference(commit_sha1);
@@@ -768,12 -761,13 +767,12 @@@ static int parse_insn_buffer(char *buf
        int i;
  
        for (i = 1; *p; i++) {
 -              commit = parse_insn_line(p, opts);
 +              char *eol = strchrnul(p, '\n');
 +              commit = parse_insn_line(p, eol, opts);
                if (!commit)
                        return error(_("Could not parse line %d."), i);
                next = commit_list_append(commit, next);
 -              p = strchrnul(p, '\n');
 -              if (*p)
 -                      p++;
 +              p = *eol ? eol + 1 : eol;
        }
        if (!*todo_list)
                return error(_("No commits parsed."));
@@@ -849,13 -843,14 +848,13 @@@ static void read_populate_opts(struct r
  static void walk_revs_populate_todo(struct commit_list **todo_list,
                                struct replay_opts *opts)
  {
 -      struct rev_info revs;
        struct commit *commit;
        struct commit_list **next;
  
 -      prepare_revs(&revs, opts);
 +      prepare_revs(opts);
  
        next = todo_list;
 -      while ((commit = get_revision(&revs)))
 +      while ((commit = get_revision(opts->revs)))
                next = commit_list_append(commit, next);
  }
  
@@@ -905,7 -900,7 +904,7 @@@ static int rollback_single_pick(void
        if (!file_exists(git_path("CHERRY_PICK_HEAD")) &&
            !file_exists(git_path("REVERT_HEAD")))
                return error(_("no cherry-pick or revert in progress"));
 -      if (!resolve_ref("HEAD", head_sha1, 0, NULL))
 +      if (read_ref_full("HEAD", head_sha1, 0, NULL))
                return error(_("cannot resolve HEAD"));
        if (is_null_sha1(head_sha1))
                return error(_("cannot abort from a branch yet to be born"));
@@@ -946,7 -941,7 +945,7 @@@ static int sequencer_rollback(struct re
        }
        if (reset_for_rollback(sha1))
                goto fail;
 -      remove_sequencer_state(1);
 +      remove_sequencer_state();
        strbuf_release(&buf);
        return 0;
  fail:
@@@ -1020,64 -1015,33 +1019,64 @@@ static int pick_commits(struct commit_l
        for (cur = todo_list; cur; cur = cur->next) {
                save_todo(cur, opts);
                res = do_pick_commit(cur->item, opts);
 -              if (res) {
 -                      if (!cur->next)
 -                              /*
 -                               * An error was encountered while
 -                               * picking the last commit; the
 -                               * sequencer state is useless now --
 -                               * the user simply needs to resolve
 -                               * the conflict and commit
 -                               */
 -                              remove_sequencer_state(0);
 +              if (res)
                        return res;
 -              }
        }
  
        /*
         * Sequence of picks finished successfully; cleanup by
         * removing the .git/sequencer directory
         */
 -      remove_sequencer_state(1);
 +      remove_sequencer_state();
        return 0;
  }
  
 +static int continue_single_pick(void)
 +{
 +      const char *argv[] = { "commit", NULL };
 +
 +      if (!file_exists(git_path("CHERRY_PICK_HEAD")) &&
 +          !file_exists(git_path("REVERT_HEAD")))
 +              return error(_("no cherry-pick or revert in progress"));
 +      return run_command_v_opt(argv, RUN_GIT_CMD);
 +}
 +
 +static int sequencer_continue(struct replay_opts *opts)
 +{
 +      struct commit_list *todo_list = NULL;
 +
 +      if (!file_exists(git_path(SEQ_TODO_FILE)))
 +              return continue_single_pick();
 +      read_populate_opts(&opts);
 +      read_populate_todo(&todo_list, opts);
 +
 +      /* Verify that the conflict has been resolved */
 +      if (file_exists(git_path("CHERRY_PICK_HEAD")) ||
 +          file_exists(git_path("REVERT_HEAD"))) {
 +              int ret = continue_single_pick();
 +              if (ret)
 +                      return ret;
 +      }
 +      if (index_differs_from("HEAD", 0))
 +              return error_dirty_index(opts);
 +      todo_list = todo_list->next;
 +      return pick_commits(todo_list, opts);
 +}
 +
 +static int single_pick(struct commit *cmit, struct replay_opts *opts)
 +{
 +      setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
 +      return do_pick_commit(cmit, opts);
 +}
 +
  static int pick_revisions(struct replay_opts *opts)
  {
        struct commit_list *todo_list = NULL;
        unsigned char sha1[20];
  
 +      if (opts->subcommand == REPLAY_NONE)
 +              assert(opts->revs);
 +
        read_and_refresh_cache(opts);
  
        /*
         * one that is being continued
         */
        if (opts->subcommand == REPLAY_REMOVE_STATE) {
 -              remove_sequencer_state(1);
 +              remove_sequencer_state();
                return 0;
        }
        if (opts->subcommand == REPLAY_ROLLBACK)
                return sequencer_rollback(opts);
 -      if (opts->subcommand == REPLAY_CONTINUE) {
 -              if (!file_exists(git_path(SEQ_TODO_FILE)))
 -                      return error(_("No %s in progress"), action_name(opts));
 -              read_populate_opts(&opts);
 -              read_populate_todo(&todo_list, opts);
 -
 -              /* Verify that the conflict has been resolved */
 -              if (!index_differs_from("HEAD", 0))
 -                      todo_list = todo_list->next;
 -              return pick_commits(todo_list, opts);
 +      if (opts->subcommand == REPLAY_CONTINUE)
 +              return sequencer_continue(opts);
 +
 +      /*
 +       * If we were called as "git cherry-pick <commit>", just
 +       * cherry-pick/revert it, set CHERRY_PICK_HEAD /
 +       * REVERT_HEAD, and don't touch the sequencer state.
 +       * This means it is possible to cherry-pick in the middle
 +       * of a cherry-pick sequence.
 +       */
 +      if (opts->revs->cmdline.nr == 1 &&
 +          opts->revs->cmdline.rev->whence == REV_CMD_REV &&
 +          opts->revs->no_walk &&
 +          !opts->revs->cmdline.rev->flags) {
 +              struct commit *cmit;
 +              if (prepare_revision_walk(opts->revs))
 +                      die(_("revision walk setup failed"));
 +              cmit = get_revision(opts->revs);
 +              if (!cmit || get_revision(opts->revs))
 +                      die("BUG: expected exactly one commit from walk");
 +              return single_pick(cmit, opts);
        }
  
        /*