Code

Merge branch 'ab/i18n-st'
authorJunio C Hamano <gitster@pobox.com>
Sat, 2 Apr 2011 00:55:55 +0000 (17:55 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 2 Apr 2011 00:55:55 +0000 (17:55 -0700)
* ab/i18n-st: (69 commits)
  i18n: git-shortlog basic messages
  i18n: git-revert split up "could not revert/apply" message
  i18n: git-revert literal "me" messages
  i18n: git-revert "Your local changes" message
  i18n: git-revert basic messages
  i18n: git-notes GIT_NOTES_REWRITE_MODE error message
  i18n: git-notes basic commands
  i18n: git-gc "Auto packing the repository" message
  i18n: git-gc basic messages
  i18n: git-describe basic messages
  i18n: git-clean clean.requireForce messages
  i18n: git-clean basic messages
  i18n: git-bundle basic messages
  i18n: git-archive basic messages
  i18n: git-status "renamed: " message
  i18n: git-status "Initial commit" message
  i18n: git-status "Changes to be committed" message
  i18n: git-status shortstatus messages
  i18n: git-status "nothing to commit" messages
  i18n: git-status basic messages
  ...

Conflicts:
builtin/branch.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/grep.c
builtin/merge.c
builtin/push.c
builtin/revert.c
t/t3507-cherry-pick-conflict.sh
t/t7607-merge-overwrite.sh

27 files changed:
1  2 
builtin/add.c
builtin/branch.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/describe.c
builtin/diff.c
builtin/fetch.c
builtin/grep.c
builtin/init-db.c
builtin/log.c
builtin/merge.c
builtin/notes.c
builtin/push.c
builtin/reset.c
builtin/revert.c
builtin/tag.c
t/t0001-init.sh
t/t3200-branch.sh
t/t3507-cherry-pick-conflict.sh
t/t4014-format-patch.sh
t/t5601-clone.sh
t/t6040-tracking-info.sh
t/t7201-co.sh
t/t7500-commit.sh
t/t7607-merge-overwrite.sh
wt-status.c

diff --cc builtin/add.c
Simple merge
index b9ba011f7b3f37a9448afae909d743249c3d8e1f,244589e73657bf1f2eaa1450c36f59869c0a44d6..9cca1b9afc20caf6333d0269386249f41fa8746f
@@@ -133,12 -133,12 +133,12 @@@ static int branch_merged(int kind, cons
        if ((head_rev != reference_rev) &&
            in_merge_bases(rev, &head_rev, 1) != merged) {
                if (merged)
-                       warning("deleting branch '%s' that has been merged to\n"
-                               "         '%s', but not yet been merged to HEAD.",
+                       warning(_("deleting branch '%s' that has been merged to\n"
 -                              "         '%s', but it is not yet merged to HEAD."),
++                              "         '%s', but not yet merged to HEAD."),
                                name, reference_name);
                else
-                       warning("not deleting branch '%s' that is not yet merged to\n"
-                               "         '%s', even though it is merged to HEAD.",
+                       warning(_("not deleting branch '%s' that is not yet merged to\n"
+                               "         '%s', even though it is merged to HEAD."),
                                name, reference_name);
        }
        return merged;
index 686d0ffd300e3e23cfd31b12d4267b5930787317,9f8e41e37c271f7c76ac2ec58265414ef8334c39..eece5d6ac0f48ae76dc76c0f2ebda633cc0ded58
@@@ -542,29 -543,21 +544,31 @@@ static void update_refs_for_switch(stru
        strbuf_addf(&msg, "checkout: moving from %s to %s",
                    old_desc ? old_desc : "(invalid)", new->name);
  
 -      if (new->path) {
 +      if (!strcmp(new->name, "HEAD") && !new->path && !opts->force_detach) {
 +              /* Nothing to do. */
 +      } else if (opts->force_detach || !new->path) {  /* No longer on any branch. */
 +              update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
 +                         REF_NODEREF, DIE_ON_ERR);
 +              if (!opts->quiet) {
 +                      if (old->path && advice_detached_head)
 +                              detach_advice(old->path, new->name);
-                       describe_detached_head("HEAD is now at", new->commit);
++                      describe_detached_head(_("HEAD is now at"), new->commit);
 +              }
 +      } else if (new->path) { /* Switch branches. */
                create_symref("HEAD", new->path, msg.buf);
                if (!opts->quiet) {
-                       if (old->path && !strcmp(new->path, old->path))
-                               fprintf(stderr, "Already on '%s'\n",
-                                       new->name);
-                       else if (opts->new_branch)
-                               fprintf(stderr, "Switched to%s branch '%s'\n",
-                                       opts->branch_exists ? " and reset" : " a new",
+                       if (old->path && !strcmp(new->path, old->path)) {
+                               fprintf(stderr, _("Already on '%s'\n"),
                                        new->name);
-                       else
-                               fprintf(stderr, "Switched to branch '%s'\n",
+                       } else if (opts->new_branch) {
+                               if (opts->branch_exists)
+                                       fprintf(stderr, _("Switched to and reset branch '%s'\n"), new->name);
+                               else
+                                       fprintf(stderr, _("Switched to a new branch '%s'\n"), new->name);
+                       } else {
+                               fprintf(stderr, _("Switched to branch '%s'\n"),
                                        new->name);
+                       }
                }
                if (old->path && old->name) {
                        char log_file[PATH_MAX], ref_file[PATH_MAX];
                report_tracking(new);
  }
  
-               die("internal error: only -- alone should have been left");
 +struct rev_list_args {
 +      int argc;
 +      int alloc;
 +      const char **argv;
 +};
 +
 +static void add_one_rev_list_arg(struct rev_list_args *args, const char *s)
 +{
 +      ALLOC_GROW(args->argv, args->argc + 1, args->alloc);
 +      args->argv[args->argc++] = s;
 +}
 +
 +static int add_one_ref_to_rev_list_arg(const char *refname,
 +                                     const unsigned char *sha1,
 +                                     int flags,
 +                                     void *cb_data)
 +{
 +      add_one_rev_list_arg(cb_data, refname);
 +      return 0;
 +}
 +
 +static int clear_commit_marks_from_one_ref(const char *refname,
 +                                    const unsigned char *sha1,
 +                                    int flags,
 +                                    void *cb_data)
 +{
 +      struct commit *commit = lookup_commit_reference_gently(sha1, 1);
 +      if (commit)
 +              clear_commit_marks(commit, -1);
 +      return 0;
 +}
 +
 +static void describe_one_orphan(struct strbuf *sb, struct commit *commit)
 +{
 +      struct pretty_print_context ctx = { 0 };
 +
 +      parse_commit(commit);
 +      strbuf_addstr(sb, "  ");
 +      strbuf_addstr(sb,
 +              find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
 +      strbuf_addch(sb, ' ');
 +      pretty_print_commit(CMIT_FMT_ONELINE, commit, sb, &ctx);
 +      strbuf_addch(sb, '\n');
 +}
 +
 +#define ORPHAN_CUTOFF 4
 +static void suggest_reattach(struct commit *commit, struct rev_info *revs)
 +{
 +      struct commit *c, *last = NULL;
 +      struct strbuf sb = STRBUF_INIT;
 +      int lost = 0;
 +      while ((c = get_revision(revs)) != NULL) {
 +              if (lost < ORPHAN_CUTOFF)
 +                      describe_one_orphan(&sb, c);
 +              last = c;
 +              lost++;
 +      }
 +      if (ORPHAN_CUTOFF < lost) {
 +              int more = lost - ORPHAN_CUTOFF;
 +              if (more == 1)
 +                      describe_one_orphan(&sb, last);
 +              else
 +                      strbuf_addf(&sb, " ... and %d more.\n", more);
 +      }
 +
 +      fprintf(stderr,
 +              "Warning: you are leaving %d commit%s behind, "
 +              "not connected to\n"
 +              "any of your branches:\n\n"
 +              "%s\n"
 +              "If you want to keep them by creating a new branch, "
 +              "this may be a good time\nto do so with:\n\n"
 +              " git branch new_branch_name %s\n\n",
 +              lost, ((1 < lost) ? "s" : ""),
 +              sb.buf,
 +              sha1_to_hex(commit->object.sha1));
 +      strbuf_release(&sb);
 +}
 +
 +/*
 + * We are about to leave commit that was at the tip of a detached
 + * HEAD.  If it is not reachable from any ref, this is the last chance
 + * for the user to do so without resorting to reflog.
 + */
 +static void orphaned_commit_warning(struct commit *commit)
 +{
 +      struct rev_list_args args = { 0, 0, NULL };
 +      struct rev_info revs;
 +
 +      add_one_rev_list_arg(&args, "(internal)");
 +      add_one_rev_list_arg(&args, sha1_to_hex(commit->object.sha1));
 +      add_one_rev_list_arg(&args, "--not");
 +      for_each_ref(add_one_ref_to_rev_list_arg, &args);
 +      add_one_rev_list_arg(&args, "--");
 +      add_one_rev_list_arg(&args, NULL);
 +
 +      init_revisions(&revs, NULL);
 +      if (setup_revisions(args.argc - 1, args.argv, &revs, NULL) != 1)
-               die("internal error in revision walk");
++              die(_("internal error: only -- alone should have been left"));
 +      if (prepare_revision_walk(&revs))
-               describe_detached_head("Previous HEAD position was", commit);
++              die(_("internal error in revision walk"));
 +      if (!(commit->object.flags & UNINTERESTING))
 +              suggest_reattach(commit, &revs);
 +      else
++              describe_detached_head(_("Previous HEAD position was"), commit);
 +
 +      clear_commit_marks(commit, -1);
 +      for_each_ref(clear_commit_marks_from_one_ref, NULL);
 +}
 +
  static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
  {
        int ret = 0;
@@@ -784,119 -679,6 +788,119 @@@ static const char *unique_tracking_name
        return NULL;
  }
  
-                       die("invalid reference: %s", arg);
 +static int parse_branchname_arg(int argc, const char **argv,
 +                              int dwim_new_local_branch_ok,
 +                              struct branch_info *new,
 +                              struct tree **source_tree,
 +                              unsigned char rev[20],
 +                              const char **new_branch)
 +{
 +      int argcount = 0;
 +      unsigned char branch_rev[20];
 +      const char *arg;
 +      int has_dash_dash;
 +
 +      /*
 +       * case 1: git checkout <ref> -- [<paths>]
 +       *
 +       *   <ref> must be a valid tree, everything after the '--' must be
 +       *   a path.
 +       *
 +       * case 2: git checkout -- [<paths>]
 +       *
 +       *   everything after the '--' must be paths.
 +       *
 +       * case 3: git checkout <something> [<paths>]
 +       *
 +       *   With no paths, if <something> is a commit, that is to
 +       *   switch to the branch or detach HEAD at it.  As a special case,
 +       *   if <something> is A...B (missing A or B means HEAD but you can
 +       *   omit at most one side), and if there is a unique merge base
 +       *   between A and B, A...B names that merge base.
 +       *
 +       *   With no paths, if <something> is _not_ a commit, no -t nor -b
 +       *   was given, and there is a tracking branch whose name is
 +       *   <something> in one and only one remote, then this is a short-hand
 +       *   to fork local <something> from that remote-tracking branch.
 +       *
 +       *   Otherwise <something> shall not be ambiguous.
 +       *   - If it's *only* a reference, treat it like case (1).
 +       *   - If it's only a path, treat it like case (2).
 +       *   - else: fail.
 +       *
 +       */
 +      if (!argc)
 +              return 0;
 +
 +      if (!strcmp(argv[0], "--"))     /* case (2) */
 +              return 1;
 +
 +      arg = argv[0];
 +      has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
 +
 +      if (!strcmp(arg, "-"))
 +              arg = "@{-1}";
 +
 +      if (get_sha1_mb(arg, rev)) {
 +              if (has_dash_dash)          /* case (1) */
-               die("reference is not a tree: %s", arg);
++                      die(_("invalid reference: %s"), arg);
 +              if (dwim_new_local_branch_ok &&
 +                  !check_filename(NULL, arg) &&
 +                  argc == 1) {
 +                      const char *remote = unique_tracking_name(arg);
 +                      if (!remote || get_sha1(remote, rev))
 +                              return argcount;
 +                      *new_branch = arg;
 +                      arg = remote;
 +                      /* DWIMmed to create local branch */
 +              } else {
 +                      return argcount;
 +              }
 +      }
 +
 +      /* we can't end up being in (2) anymore, eat the argument */
 +      argcount++;
 +      argv++;
 +      argc--;
 +
 +      new->name = arg;
 +      setup_branch_path(new);
 +
 +      if (check_ref_format(new->path) == CHECK_REF_FORMAT_OK &&
 +          resolve_ref(new->path, branch_rev, 1, NULL))
 +              hashcpy(rev, branch_rev);
 +      else
 +              new->path = NULL; /* not an existing branch */
 +
 +      new->commit = lookup_commit_reference_gently(rev, 1);
 +      if (!new->commit) {
 +              /* not a commit */
 +              *source_tree = parse_tree_indirect(rev);
 +      } else {
 +              parse_commit(new->commit);
 +              *source_tree = new->commit->tree;
 +      }
 +
 +      if (!*source_tree)                   /* case (1): want a tree */
++              die(_("reference is not a tree: %s"), arg);
 +      if (!has_dash_dash) {/* case (3 -> 1) */
 +              /*
 +               * Do not complain the most common case
 +               *      git checkout branch
 +               * even if there happen to be a file called 'branch';
 +               * it would be extremely annoying.
 +               */
 +              if (argc)
 +                      verify_non_filename(NULL, arg);
 +      } else {
 +              argcount++;
 +              argv++;
 +              argc--;
 +      }
 +
 +      return argcount;
 +}
 +
  int cmd_checkout(int argc, const char **argv, const char *prefix)
  {
        struct checkout_opts opts;
                opts.new_branch = opts.new_branch_force;
  
        if (patch_mode && (opts.track > 0 || opts.new_branch
 -                         || opts.new_branch_log || opts.merge || opts.force))
 +                         || opts.new_branch_log || opts.merge || opts.force
 +                         || opts.force_detach))
-               die ("--patch is incompatible with all other options");
+               die (_("--patch is incompatible with all other options"));
  
 +      if (opts.force_detach && (opts.new_branch || opts.new_orphan_branch))
 +              die("--detach cannot be used with -b/-B/--orphan");
 +      if (opts.force_detach && 0 < opts.track)
 +              die("--detach cannot be used with -t");
 +
        /* --track without -b should DWIM */
        if (0 < opts.track && !opts.new_branch) {
                const char *argv0 = argv[0];
        }
  
        if (opts.force && opts.merge)
-               die("git checkout: -f and -m are incompatible");
+               die(_("git checkout: -f and -m are incompatible"));
  
        /*
 -       * case 1: git checkout <ref> -- [<paths>]
 +       * Extract branch name from command line arguments, so
 +       * all that is left is pathspecs.
         *
 -       *   <ref> must be a valid tree, everything after the '--' must be
 -       *   a path.
 -       *
 -       * case 2: git checkout -- [<paths>]
 -       *
 -       *   everything after the '--' must be paths.
 -       *
 -       * case 3: git checkout <something> [<paths>]
 -       *
 -       *   With no paths, if <something> is a commit, that is to
 -       *   switch to the branch or detach HEAD at it.  As a special case,
 -       *   if <something> is A...B (missing A or B means HEAD but you can
 -       *   omit at most one side), and if there is a unique merge base
 -       *   between A and B, A...B names that merge base.
 -       *
 -       *   With no paths, if <something> is _not_ a commit, no -t nor -b
 -       *   was given, and there is a remote-tracking branch whose name is
 -       *   <something> in one and only one remote, then this is a short-hand
 -       *   to fork local <something> from that remote-tracking branch.
 +       * Handle
         *
 -       *   Otherwise <something> shall not be ambiguous.
 -       *   - If it's *only* a reference, treat it like case (1).
 -       *   - If it's only a path, treat it like case (2).
 -       *   - else: fail.
 +       *  1) git checkout <tree> -- [<paths>]
 +       *  2) git checkout -- [<paths>]
 +       *  3) git checkout <something> [<paths>]
         *
 +       * including "last branch" syntax and DWIM-ery for names of
 +       * remote branches, erroring out for invalid or ambiguous cases.
         */
        if (argc) {
 -              if (!strcmp(argv[0], "--")) {       /* case (2) */
 -                      argv++;
 -                      argc--;
 -                      goto no_reference;
 -              }
 -
 -              arg = argv[0];
 -              has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
 -
 -              if (!strcmp(arg, "-"))
 -                      arg = "@{-1}";
 -
 -              if (get_sha1_mb(arg, rev)) {
 -                      if (has_dash_dash)          /* case (1) */
 -                              die(_("invalid reference: %s"), arg);
 -                      if (!patch_mode &&
 -                          dwim_new_local_branch &&
 -                          opts.track == BRANCH_TRACK_UNSPECIFIED &&
 -                          !opts.new_branch &&
 -                          !check_filename(NULL, arg) &&
 -                          argc == 1) {
 -                              const char *remote = unique_tracking_name(arg);
 -                              if (!remote || get_sha1(remote, rev))
 -                                      goto no_reference;
 -                              opts.new_branch = arg;
 -                              arg = remote;
 -                              /* DWIMmed to create local branch */
 -                      }
 -                      else
 -                              goto no_reference;
 -              }
 -
 -              /* we can't end up being in (2) anymore, eat the argument */
 -              argv++;
 -              argc--;
 -
 -              new.name = arg;
 -              if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
 -                      setup_branch_path(&new);
 -
 -                      if ((check_ref_format(new.path) == CHECK_REF_FORMAT_OK) &&
 -                          resolve_ref(new.path, rev, 1, NULL))
 -                              ;
 -                      else
 -                              new.path = NULL;
 -                      parse_commit(new.commit);
 -                      source_tree = new.commit->tree;
 -              } else
 -                      source_tree = parse_tree_indirect(rev);
 -
 -              if (!source_tree)                   /* case (1): want a tree */
 -                      die(_("reference is not a tree: %s"), arg);
 -              if (!has_dash_dash) {/* case (3 -> 1) */
 -                      /*
 -                       * Do not complain the most common case
 -                       *      git checkout branch
 -                       * even if there happen to be a file called 'branch';
 -                       * it would be extremely annoying.
 -                       */
 -                      if (argc)
 -                              verify_non_filename(NULL, arg);
 -              }
 -              else {
 -                      argv++;
 -                      argc--;
 -              }
 +              int dwim_ok =
 +                      !patch_mode &&
 +                      dwim_new_local_branch &&
 +                      opts.track == BRANCH_TRACK_UNSPECIFIED &&
 +                      !opts.new_branch;
 +              int n = parse_branchname_arg(argc, argv, dwim_ok,
 +                              &new, &source_tree, rev, &opts.new_branch);
 +              argv += n;
 +              argc -= n;
        }
  
 -no_reference:
 -
        if (opts.track == BRANCH_TRACK_UNSPECIFIED)
                opts.track = git_branch_track;
  
                        }
                }
  
 +              if (opts.force_detach)
 +                      die("git checkout: --detach does not take a path argument");
 +
                if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
-                       die("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index.");
+                       die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index."));
  
                return checkout_paths(source_tree, pathspec, &opts);
        }
diff --cc builtin/clone.c
index c6e10bb9e916a21ad5c71018d6380ad85540dc65,b9394c41520407379b16297efac35c781cc0475f..0b5601a9b080e079ec077a8a765be24f2bf9bd29
@@@ -466,12 -465,15 +466,15 @@@ int cmd_clone(int argc, const char **ar
        setenv(CONFIG_ENVIRONMENT, mkpath("%s/config", git_dir), 1);
  
        if (safe_create_leading_directories_const(git_dir) < 0)
-               die("could not create leading directories of '%s'", git_dir);
+               die(_("could not create leading directories of '%s'"), git_dir);
 -      set_git_dir(make_absolute_path(git_dir));
 +      set_git_dir(real_path(git_dir));
  
-       if (0 <= option_verbosity)
-               printf("Cloning into %s%s...\n",
-                      option_bare ? "bare repository " : "", dir);
+       if (0 <= option_verbosity) {
+               if (option_bare)
+                       printf(_("Cloning into bare repository %s...\n"), dir);
+               else
+                       printf(_("Cloning into %s...\n"), dir);
+       }
        init_db(option_template, INIT_DB_QUIET);
  
        /*
index 54b20497b120bc2bf5ee6e4904eca0ca5d83ff4f,271f31127cc338359fddf423d266bc2abba9dc23..67757e999fba514b62767d3351031e9eb6ef8c10
@@@ -47,24 -47,16 +47,24 @@@ N_("Your name and email address were co
  "\n"
  "After doing this, you may fix the identity used for this commit with:\n"
  "\n"
- "    git commit --amend --reset-author\n";
+ "    git commit --amend --reset-author\n");
  
  static const char empty_amend_advice[] =
- "You asked to amend the most recent commit, but doing so would make\n"
N_("You asked to amend the most recent commit, but doing so would make\n"
  "it empty. You can repeat your command with --allow-empty, or you can\n"
- "remove the commit entirely with \"git reset HEAD^\".\n";
+ "remove the commit entirely with \"git reset HEAD^\".\n");
  
- "The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
 +static const char empty_cherry_pick_advice[] =
- "Otherwise, please use 'git reset'\n";
++N_("The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
 +"If you wish to commit it anyway, use:\n"
 +"\n"
 +"    git commit --allow-empty\n"
 +"\n"
++"Otherwise, please use 'git reset'\n");
 +
  static unsigned char head_sha1[20];
  
 -static char *use_message_buffer;
 +static const char *use_message_buffer;
  static const char commit_editmsg[] = "COMMIT_EDITMSG";
  static struct lock_file index_lock; /* real index */
  static struct lock_file false_lock; /* used only for partial commits */
@@@ -422,8 -378,8 +422,8 @@@ static char *prepare_index(int argc, co
         */
        commit_style = COMMIT_PARTIAL;
  
 -      if (in_merge)
 -              die(_("cannot do a partial commit during a merge."));
 +      if (whence != FROM_COMMIT)
-               die("cannot do a partial commit during a %s.", whence_s());
++              die(_("cannot do a partial commit during a %s."), whence_s());
  
        memset(&partial, 0, sizeof(partial));
        partial.strdup_strings = 1;
@@@ -513,18 -469,18 +513,18 @@@ static void determine_author_info(struc
        email = getenv("GIT_AUTHOR_EMAIL");
        date = getenv("GIT_AUTHOR_DATE");
  
 -      if (use_message && !renew_authorship) {
 +      if (author_message) {
                const char *a, *lb, *rb, *eol;
  
 -              a = strstr(use_message_buffer, "\nauthor ");
 +              a = strstr(author_message_buffer, "\nauthor ");
                if (!a)
-                       die("invalid commit: %s", author_message);
 -                      die(_("invalid commit: %s"), use_message);
++                      die(_("invalid commit: %s"), author_message);
  
                lb = strchrnul(a + strlen("\nauthor "), '<');
                rb = strchrnul(lb, '>');
                eol = strchrnul(rb, '\n');
                if (!*lb || !*rb || !*eol)
-                       die("invalid commit: %s", author_message);
 -                      die(_("invalid commit: %s"), use_message);
++                      die(_("invalid commit: %s"), author_message);
  
                if (lb == a + strlen("\nauthor "))
                        /* \nauthor <foo@example.com> */
@@@ -675,11 -631,11 +675,11 @@@ static int prepare_to_commit(const cha
                hook_arg1 = "merge";
        } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
                if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
-                       die_errno("could not read SQUASH_MSG");
+                       die_errno(_("could not read SQUASH_MSG"));
                hook_arg1 = "squash";
 -      } else if (template_file && !stat(template_file, &statbuf)) {
 +      } else if (template_file) {
                if (strbuf_read_file(&sb, template_file, 0) < 0)
-                       die_errno("could not read '%s'", template_file);
+                       die_errno(_("could not read '%s'"), template_file);
                hook_arg1 = "template";
        }
  
        strbuf_addstr(&committer_ident, git_committer_info(0));
        if (use_editor && include_status) {
                char *ai_tmp, *ci_tmp;
 -              if (in_merge)
 +              if (whence != FROM_COMMIT)
                        status_printf_ln(s, GIT_COLOR_NORMAL,
-                               "\n"
+                               _("\n"
 -                              "It looks like you may be committing a MERGE.\n"
 +                              "It looks like you may be committing a %s.\n"
                                "If this is not correct, please remove the file\n"
                                "       %s\n"
                                "and try again.\n"
-                               "",
+                               ""),
 -                              git_path("MERGE_HEAD"));
 +                              whence_s(),
 +                              git_path(whence == FROM_MERGE
 +                                       ? "MERGE_HEAD"
 +                                       : "CHERRY_PICK_HEAD"));
  
                fprintf(s->fp, "\n");
                status_printf(s, GIT_COLOR_NORMAL,
            !(amend && is_a_merge(head_sha1))) {
                run_status(stdout, index_file, prefix, 0, s);
                if (amend)
-                       fputs(empty_amend_advice, stderr);
+                       fputs(_(empty_amend_advice), stderr);
 +              else if (whence == FROM_CHERRY_PICK)
-                       fputs(empty_cherry_pick_advice, stderr);
++                      fputs(_(empty_cherry_pick_advice), stderr);
                return 0;
        }
  
@@@ -953,31 -895,9 +953,31 @@@ static void handle_untracked_files_arg(
        else if (!strcmp(untracked_files_arg, "all"))
                s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
        else
-               die("Invalid untracked files mode '%s'", untracked_files_arg);
+               die(_("Invalid untracked files mode '%s'"), untracked_files_arg);
  }
  
-               die("could not lookup commit %s", name);
 +static const char *read_commit_message(const char *name)
 +{
 +      const char *out_enc, *out;
 +      struct commit *commit;
 +
 +      commit = lookup_commit_reference_by_name(name);
 +      if (!commit)
++              die(_("could not lookup commit %s"), name);
 +      out_enc = get_commit_output_encoding();
 +      out = logmsg_reencode(commit, out_enc);
 +
 +      /*
 +       * If we failed to reencode the buffer, just copy it
 +       * byte for byte so the user can try to fix it up.
 +       * This also handles the case where input and output
 +       * encodings are identical.
 +       */
 +      if (out == NULL)
 +              out = xstrdup(commit->buffer);
 +      return out;
 +}
 +
  static int parse_and_validate_options(int argc, const char *argv[],
                                      const char * const usage[],
                                      const char *prefix,
  
        /* Sanity check options */
        if (amend && initial_commit)
-               die("You have nothing to amend.");
+               die(_("You have nothing to amend."));
 -      if (amend && in_merge)
 -              die(_("You are in the middle of a merge -- cannot amend."));
 +      if (amend && whence != FROM_COMMIT)
-               die("You are in the middle of a %s -- cannot amend.", whence_s());
++              die(_("You are in the middle of a %s -- cannot amend."), whence_s());
        if (fixup_message && squash_message)
-               die("Options --squash and --fixup cannot be used together");
+               die(_("Options --squash and --fixup cannot be used together"));
        if (use_message)
                f++;
        if (edit_message)
                use_message = edit_message;
        if (amend && !use_message && !fixup_message)
                use_message = "HEAD";
 -      if (!use_message && renew_authorship)
 +      if (!use_message && whence != FROM_CHERRY_PICK && renew_authorship)
-               die("--reset-author can be used only with -C, -c or --amend.");
+               die(_("--reset-author can be used only with -C, -c or --amend."));
        if (use_message) {
 -              const char *out_enc;
 -              struct commit *commit;
 -
 -              commit = lookup_commit_reference_by_name(use_message);
 -              if (!commit)
 -                      die(_("could not lookup commit %s"), use_message);
 -              out_enc = get_commit_output_encoding();
 -              use_message_buffer = logmsg_reencode(commit, out_enc);
 -
 -              /*
 -               * If we failed to reencode the buffer, just copy it
 -               * byte for byte so the user can try to fix it up.
 -               * This also handles the case where input and output
 -               * encodings are identical.
 -               */
 -              if (use_message_buffer == NULL)
 -                      use_message_buffer = xstrdup(commit->buffer);
 +              use_message_buffer = read_commit_message(use_message);
 +              if (!renew_authorship) {
 +                      author_message = use_message;
 +                      author_message_buffer = use_message_buffer;
 +              }
 +      }
 +      if (whence == FROM_CHERRY_PICK && !renew_authorship) {
 +              author_message = "CHERRY_PICK_HEAD";
 +              author_message_buffer = read_commit_message(author_message);
        }
  
        if (!!also + !!only + !!all + !!interactive > 1)
@@@ -1487,10 -1421,9 +1487,10 @@@ int cmd_commit(int argc, const char **a
        }
        if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
                rollback_index_files();
-               die("cannot update HEAD ref");
+               die(_("cannot update HEAD ref"));
        }
  
 +      unlink(git_path("CHERRY_PICK_HEAD"));
        unlink(git_path("MERGE_HEAD"));
        unlink(git_path("MERGE_MSG"));
        unlink(git_path("MERGE_MODE"));
index 4afd1504a666d670ec71bdbd61b09bc0530ed04b,037691e3d30ef2c6b80b23fa0fbcad67759560e2..66fc291c8a81de71dee7b597c9ab0dc9d70e8e29
@@@ -284,12 -284,12 +284,12 @@@ static void describe(const char *arg, i
        }
  
        if (!max_candidates)
-               die("no tag exactly matches '%s'", sha1_to_hex(cmit->object.sha1));
+               die(_("no tag exactly matches '%s'"), sha1_to_hex(cmit->object.sha1));
        if (debug)
-               fprintf(stderr, "searching to describe %s\n", arg);
+               fprintf(stderr, _("searching to describe %s\n"), arg);
  
        if (!have_util) {
 -              for_each_hash(&names, set_util);
 +              for_each_hash(&names, set_util, NULL);
                have_util = 1;
        }
  
diff --cc builtin/diff.c
index 655a013ed05edd369225aa9ee9f39f347d687172,00342730b651c89d38e3f8af14f350a1077ffde2..717fa1a3414e18cbdd4c6eb1e0785761687688d7
@@@ -367,12 -372,16 +367,12 @@@ int cmd_diff(int argc, const char **arg
                        continue;
  
                }
-               die("unhandled object '%s' given.", name);
+               die(_("unhandled object '%s' given."), name);
        }
 -      if (rev.prune_data) {
 -              const char **pathspec = rev.prune_data;
 -              while (*pathspec) {
 -                      if (!path)
 -                              path = *pathspec;
 -                      paths++;
 -                      pathspec++;
 -              }
 +      if (rev.prune_data.nr) {
 +              if (!path)
 +                      path = rev.prune_data.items[0].match;
 +              paths += rev.prune_data.nr;
        }
  
        /*
diff --cc builtin/fetch.c
Simple merge
diff --cc builtin/grep.c
index 85e9583a1335330f8e852d7937abb10c97798bc0,dfc32fbe6f87cb2959098640d583990552815607..5b8f30d3ed472bb74f1b992b5098a08f5d5377a1
@@@ -548,16 -664,12 +548,16 @@@ static int grep_tree(struct grep_opt *o
  
                        data = lock_and_read_sha1_file(entry.sha1, &type, &size);
                        if (!data)
-                               die("unable to read tree (%s)",
+                               die(_("unable to read tree (%s)"),
                                    sha1_to_hex(entry.sha1));
 +
 +                      strbuf_addch(base, '/');
                        init_tree_desc(&sub, data, size);
 -                      hit |= grep_tree(opt, paths, &sub, tree_name, down);
 +                      hit |= grep_tree(opt, pathspec, &sub, base, tn_len);
                        free(data);
                }
 +              strbuf_setlen(base, old_baselen);
 +
                if (hit && opt->status_only)
                        break;
        }
@@@ -579,24 -690,16 +579,24 @@@ static int grep_object(struct grep_opt 
                data = read_object_with_reference(obj->sha1, tree_type,
                                                  &size, NULL);
                if (!data)
-                       die("unable to read tree (%s)", sha1_to_hex(obj->sha1));
+                       die(_("unable to read tree (%s)"), sha1_to_hex(obj->sha1));
 +
 +              len = name ? strlen(name) : 0;
 +              strbuf_init(&base, PATH_MAX + len + 1);
 +              if (len) {
 +                      strbuf_add(&base, name, len);
 +                      strbuf_addch(&base, ':');
 +              }
                init_tree_desc(&tree, data, size);
 -              hit = grep_tree(opt, paths, &tree, name, "");
 +              hit = grep_tree(opt, pathspec, &tree, &base, base.len);
 +              strbuf_release(&base);
                free(data);
                return hit;
        }
-       die("unable to grep from object of type %s", typename(obj->type));
+       die(_("unable to grep from object of type %s"), typename(obj->type));
  }
  
 -static int grep_objects(struct grep_opt *opt, const char **paths,
 +static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
                        const struct object_array *list)
  {
        unsigned int i;
@@@ -664,9 -762,9 +664,9 @@@ static int file_callback(const struct o
        int lno = 0;
        struct strbuf sb = STRBUF_INIT;
  
 -      patterns = fopen(arg, "r");
 +      patterns = from_stdin ? stdin : fopen(arg, "r");
        if (!patterns)
-               die_errno("cannot open '%s'", arg);
+               die_errno(_("cannot open '%s'"), arg);
        while (strbuf_getline(&sb, patterns, '\n') == 0) {
                char *s;
                size_t len;
@@@ -963,12 -1059,9 +963,12 @@@ int cmd_grep(int argc, const char **arg
                paths[0] = prefix;
                paths[1] = NULL;
        }
 +      init_pathspec(&pathspec, paths);
 +      pathspec.max_depth = opt.max_depth;
 +      pathspec.recursive = 1;
  
        if (show_in_pager && (cached || list.nr))
-               die("--open-files-in-pager only works on the worktree");
+               die(_("--open-files-in-pager only works on the worktree"));
  
        if (show_in_pager && opt.pattern_list && !opt.pattern_list->next) {
                const char *pager = path_list.items[0].string;
  
        if (!use_index) {
                if (cached)
-                       die("--cached cannot be used with --no-index.");
+                       die(_("--cached cannot be used with --no-index."));
                if (list.nr)
-                       die("--no-index cannot be used with revs.");
+                       die(_("--no-index cannot be used with revs."));
 -              hit = grep_directory(&opt, paths);
 +              hit = grep_directory(&opt, &pathspec);
        } else if (!list.nr) {
                if (!cached)
                        setup_work_tree();
  
 -              hit = grep_cache(&opt, paths, cached);
 +              hit = grep_cache(&opt, &pathspec, cached);
        } else {
                if (cached)
-                       die("both --cached and trees are given.");
+                       die(_("both --cached and trees are given."));
 -              hit = grep_objects(&opt, paths, &list);
 +              hit = grep_objects(&opt, &pathspec, &list);
        }
  
        if (use_threads)
index 8f5cfd712243975dacd08cb51c69c2e174e470b1,e0e5ce3b1985cd2aba66d8c00d134d5c7a5a62ef..6621e5671cbc4cbe5631a40f918aa4f0f05bb62e
@@@ -507,10 -515,10 +513,10 @@@ int cmd_init_db(int argc, const char **
                if (!git_work_tree_cfg) {
                        git_work_tree_cfg = xcalloc(PATH_MAX, 1);
                        if (!getcwd(git_work_tree_cfg, PATH_MAX))
-                               die_errno ("Cannot access current working directory");
+                               die_errno (_("Cannot access current working directory"));
                }
                if (work_tree)
 -                      set_git_work_tree(make_absolute_path(work_tree));
 +                      set_git_work_tree(real_path(work_tree));
                else
                        set_git_work_tree(git_work_tree_cfg);
                if (access(get_git_work_tree(), X_OK))
diff --cc builtin/log.c
Simple merge
diff --cc builtin/merge.c
index c8d028cbccdc001efed2991e477b898606396114,f9982066139de64a3ad536b5970cb04e1c9f53cf..1e0bcfd792e4fb550fea8786ff2f84e7925aca86
@@@ -801,32 -797,6 +801,32 @@@ static void add_strategies(const char *
  
  }
  
-               die_errno("Could not open '%s' for writing",
 +static void write_merge_msg(void)
 +{
 +      int fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
 +      if (fd < 0)
-               die_errno("Could not write to '%s'", git_path("MERGE_MSG"));
++              die_errno(_("Could not open '%s' for writing"),
 +                        git_path("MERGE_MSG"));
 +      if (write_in_full(fd, merge_msg.buf, merge_msg.len) != merge_msg.len)
++              die_errno(_("Could not write to '%s'"), git_path("MERGE_MSG"));
 +      close(fd);
 +}
 +
 +static void read_merge_msg(void)
 +{
 +      strbuf_reset(&merge_msg);
 +      if (strbuf_read_file(&merge_msg, git_path("MERGE_MSG"), 0) < 0)
 +              die_errno("Could not read from '%s'", git_path("MERGE_MSG"));
 +}
 +
 +static void run_prepare_commit_msg(void)
 +{
 +      write_merge_msg();
 +      run_hook(get_index_file(), "prepare-commit-msg",
 +               git_path("MERGE_MSG"), "merge", NULL, NULL);
 +      read_merge_msg();
 +}
 +
  static int merge_trivial(void)
  {
        unsigned char result_tree[20], result_commit[20];
@@@ -1001,18 -966,11 +1001,18 @@@ int cmd_merge(int argc, const char **ar
                 * add/rm <file>', just 'git commit'.
                 */
                if (advice_resolve_conflict)
-                       die("You have not concluded your merge (MERGE_HEAD exists).\n"
-                           "Please, commit your changes before you can merge.");
+                       die(_("You have not concluded your merge (MERGE_HEAD exists).\n"
+                                 "Please, commit your changes before you can merge."));
                else
-                       die("You have not concluded your merge (MERGE_HEAD exists).");
+                       die(_("You have not concluded your merge (MERGE_HEAD exists)."));
        }
 +      if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
 +              if (advice_resolve_conflict)
 +                      die("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 +                          "Please, commit your changes before you can merge.");
 +              else
 +                      die("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).");
 +      }
        resolve_undo_clear();
  
        if (verbosity < 0)
                 * We do the same for "git pull".
                 */
                if (argc != 1)
-                       die("Can merge only exactly one commit into "
-                               "empty head");
+                       die(_("Can merge only exactly one commit into "
+                               "empty head"));
                if (squash)
-                       die("Squash commit into empty head not supported yet");
+                       die(_("Squash commit into empty head not supported yet"));
                if (!allow_fast_forward)
-                       die("Non-fast-forward commit does not make sense into "
-                           "an empty head");
+                       die(_("Non-fast-forward commit does not make sense into "
+                           "an empty head"));
                remote_head = peel_to_type(argv[0], 0, NULL, OBJ_COMMIT);
                if (!remote_head)
-                       die("%s - not something we can merge", argv[0]);
+                       die(_("%s - not something we can merge"), argv[0]);
 +              read_empty(remote_head->sha1, 0);
                update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0,
                                DIE_ON_ERR);
 -              read_empty(remote_head->sha1, 0);
                return 0;
        } else {
                struct strbuf merge_names = STRBUF_INIT;
                                sha1_to_hex(j->item->object.sha1));
                fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
                if (fd < 0)
-                       die_errno("Could not open '%s' for writing",
+                       die_errno(_("Could not open '%s' for writing"),
                                  git_path("MERGE_HEAD"));
                if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-                       die_errno("Could not write to '%s'", git_path("MERGE_HEAD"));
+                       die_errno(_("Could not write to '%s'"), git_path("MERGE_HEAD"));
                close(fd);
                strbuf_addch(&merge_msg, '\n');
 -              fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
 -              if (fd < 0)
 -                      die_errno(_("Could not open '%s' for writing"),
 -                                git_path("MERGE_MSG"));
 -              if (write_in_full(fd, merge_msg.buf, merge_msg.len) !=
 -                      merge_msg.len)
 -                      die_errno(_("Could not write to '%s'"), git_path("MERGE_MSG"));
 -              close(fd);
 +              write_merge_msg();
                fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
                if (fd < 0)
-                       die_errno("Could not open '%s' for writing",
+                       die_errno(_("Could not open '%s' for writing"),
                                  git_path("MERGE_MODE"));
                strbuf_reset(&buf);
                if (!allow_fast_forward)
diff --cc builtin/notes.c
Simple merge
diff --cc builtin/push.c
index 6f6a66f9862d5ee5eaf4a4ce07934832569eacf9,8c8d8c717be6be5b4c701d6af53307ac684c54a5..9cebf9ea234d968eab638f7dcdc65370f77c0047
@@@ -69,23 -69,13 +69,23 @@@ static void setup_push_upstream(struct 
        struct strbuf refspec = STRBUF_INIT;
        struct branch *branch = branch_get(NULL);
        if (!branch)
-               die("You are not currently on a branch.\n"
 -              die(_("You are not currently on a branch."));
++              die(_("You are not currently on a branch.\n"
 +                  "To push the history leading to the current (detached HEAD)\n"
 +                  "state now, use\n"
 +                  "\n"
-                   "    git push %s HEAD:<name-of-remote-branch>\n",
++                  "    git push %s HEAD:<name-of-remote-branch>\n"),
 +                  remote->name);
        if (!branch->merge_nr || !branch->merge)
-               die("The current branch %s has no upstream branch.\n"
 -              die(_("The current branch %s is not tracking anything."),
++              die(_("The current branch %s has no upstream branch.\n"
 +                  "To push the current branch and set the remote as upstream, use\n"
 +                  "\n"
-                   "    git push --set-upstream %s %s\n",
++                  "    git push --set-upstream %s %s\n"),
 +                  branch->name,
 +                  remote->name,
                    branch->name);
        if (branch->merge_nr != 1)
-               die("The current branch %s has multiple upstream branches, "
-                   "refusing to push.", branch->name);
 -              die(_("The current branch %s is tracking multiple branches, "
++              die(_("The current branch %s has multiple upstream branches, "
+                   "refusing to push."), branch->name);
        strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
        add_refspec(refspec.buf);
  }
@@@ -156,15 -146,8 +156,15 @@@ static int do_push(const char *repo, in
  
        if (!remote) {
                if (repo)
-                       die("bad repository '%s'", repo);
-               die("No configured push destination.\n"
+                       die(_("bad repository '%s'"), repo);
 -              die(_("No destination configured to push to."));
++              die(_("No configured push destination.\n"
 +                  "Either specify the URL from the command-line or configure a remote repository using\n"
 +                  "\n"
 +                  "    git remote add <name> <url>\n"
 +                  "\n"
 +                  "and then push using the remote name\n"
 +                  "\n"
-                   "    git push <name>\n");
++                  "    git push <name>\n"));
        }
  
        if (remote->mirror)
diff --cc builtin/reset.c
Simple merge
index c57b872fe114145ec82bf33717c2a8d7f0982204,98dfd4d131444e0b1893d734b16a231781024321..2bb13ebb1de48e793e01d18ced29a468aa273b34
@@@ -197,20 -198,54 +197,20 @@@ static void add_message_to_msg(struct s
        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",
++              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"));
++              die_errno(_("Could not write to '%s'"), git_path("CHERRY_PICK_HEAD"));
 +      strbuf_release(&buf);
  }
  
  static void advise(const char *advice, ...)
diff --cc builtin/tag.c
Simple merge
diff --cc t/t0001-init.sh
Simple merge
Simple merge
index 95741801b0007b6ecbf22f665c4dcf3c744d5221,f7e40723198b6935b306409033241cfdd3a014a8..c0c8330c20e80f26d51b62c8999533c5692094de
@@@ -44,8 -38,13 +44,8 @@@ test_expect_success 'failed cherry-pic
        test "$head" = "$newhead"
  '
  
- test_expect_success 'advice from failed cherry-pick' "
+ test_expect_success C_LOCALE_OUTPUT 'advice from failed cherry-pick' "
 -      git checkout -f initial^0 &&
 -      git read-tree -u --reset HEAD &&
 -      git clean -d -f -f -q -x &&
 -
 -      git update-index --refresh &&
 -      git diff-index --exit-code HEAD &&
 +      pristine_detach initial &&
  
        picked=\$(git rev-parse --short picked) &&
        cat <<-EOF >expected &&
Simple merge
Simple merge
Simple merge
diff --cc t/t7201-co.sh
Simple merge
Simple merge
index b54e840ee2ab09a67afc663a2f475bfc9fcb9d8b,0a9b90b33f4bc5b66c7e5d9b1334eab9f84c5118..ef84f04102ed067768c66ea9608b98d47851eb8b
@@@ -150,9 -150,14 +150,15 @@@ test_expect_success 'will not overwrit
        git rm -fr . &&
        git checkout --orphan new &&
        cp important c0.c &&
-       test_must_fail git merge c0 2>out &&
-       test_cmp out expect &&
+       test_must_fail git merge c0 2>out
+ '
+ test_expect_success C_LOCALE_OUTPUT 'will not overwrite untracked file on unborn branch: output' '
+       test_cmp out expect
+ '
+ test_expect_success 'will not overwrite untracked file on unborn branch .git/MERGE_HEAD sanity etc.' '
 +      test_when_finished "rm c0.c" &&
        test_path_is_missing .git/MERGE_HEAD &&
        test_cmp important c0.c
  '
diff --cc wt-status.c
index 53558d7e5f517479af478e375076718189c2d2d5,9ff059012249821fe36cb2060f19a77db16efcc0..9f4e0ba9c17120ca2903b30b95b6d8fbcc62cd9c
@@@ -131,16 -131,16 +131,16 @@@ static void wt_status_print_unmerged_he
  {
        const char *c = color(WT_STATUS_HEADER, s);
  
-       status_printf_ln(s, c, "Unmerged paths:");
+       status_printf_ln(s, c, _("Unmerged paths:"));
        if (!advice_status_hints)
                return;
 -      if (s->in_merge)
 +      if (s->whence != FROM_COMMIT)
                ;
        else if (!s->is_initial)
-               status_printf_ln(s, c, "  (use \"git reset %s <file>...\" to unstage)", s->reference);
+               status_printf_ln(s, c, _("  (use \"git reset %s <file>...\" to unstage)"), s->reference);
        else
-               status_printf_ln(s, c, "  (use \"git rm --cached <file>...\" to unstage)");
-       status_printf_ln(s, c, "  (use \"git add/rm <file>...\" as appropriate to mark resolution)");
+               status_printf_ln(s, c, _("  (use \"git rm --cached <file>...\" to unstage)"));
+       status_printf_ln(s, c, _("  (use \"git add/rm <file>...\" as appropriate to mark resolution)"));
        status_printf_ln(s, c, "");
  }
  
@@@ -148,15 -148,15 +148,15 @@@ static void wt_status_print_cached_head
  {
        const char *c = color(WT_STATUS_HEADER, s);
  
-       status_printf_ln(s, c, "Changes to be committed:");
+       status_printf_ln(s, c, _("Changes to be committed:"));
        if (!advice_status_hints)
                return;
 -      if (s->in_merge)
 +      if (s->whence != FROM_COMMIT)
                ; /* NEEDSWORK: use "git reset --unresolve"??? */
        else if (!s->is_initial)
-               status_printf_ln(s, c, "  (use \"git reset %s <file>...\" to unstage)", s->reference);
+               status_printf_ln(s, c, _("  (use \"git reset %s <file>...\" to unstage)"), s->reference);
        else
-               status_printf_ln(s, c, "  (use \"git rm --cached <file>...\" to unstage)");
+               status_printf_ln(s, c, _("  (use \"git rm --cached <file>...\" to unstage)"));
        status_printf_ln(s, c, "");
  }