Code

Merge branch 'ab/i18n' into pu
authorJunio C Hamano <gitster@pobox.com>
Mon, 31 Jan 2011 03:03:20 +0000 (19:03 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 31 Jan 2011 03:03:20 +0000 (19:03 -0800)
* ab/i18n: (161 commits)
  po/de.po: complete German translation
  po/sv.po: add Swedish translation
  gettextize: git-bisect bisect_next_check "You need to" message
  gettextize: git-bisect [Y/n] messages
  gettextize: git-bisect bisect_replay + $1 messages
  gettextize: git-bisect bisect_reset + $1 messages
  gettextize: git-bisect bisect_run + $@ messages
  gettextize: git-bisect die + eval_gettext messages
  gettextize: git-bisect die + gettext messages
  gettextize: git-bisect echo + eval_gettext message
  gettextize: git-bisect echo + gettext messages
  gettextize: git-bisect gettext + echo message
  gettextize: git-bisect add git-sh-i18n
  gettextize: git-stash drop_stash say/die messages
  gettextize: git-stash "unknown option" message
  gettextize: git-stash die + eval_gettext $1 messages
  gettextize: git-stash die + eval_gettext $* messages
  gettextize: git-stash die + eval_gettext messages
  gettextize: git-stash die + gettext messages
  gettextize: git-stash say + gettext messages
  ...

Conflicts:
Documentation/CodingGuidelines
Makefile
builtin/clean.c
builtin/commit.c
builtin/describe.c
builtin/grep.c
builtin/init-db.c
builtin/merge.c
builtin/notes.c
builtin/revert.c
fast-import.c
git-bisect.sh
git-pull.sh
git-submodule.sh
t/t3501-revert-cherry-pick.sh
t/t7004-tag.sh
wt-status.c

65 files changed:
1  2 
.gitignore
Documentation/CodingGuidelines
INSTALL
Makefile
builtin.h
builtin/add.c
builtin/branch.c
builtin/checkout.c
builtin/clean.c
builtin/clone.c
builtin/commit.c
builtin/describe.c
builtin/diff.c
builtin/fetch-pack.c
builtin/fetch.c
builtin/gc.c
builtin/grep.c
builtin/init-db.c
builtin/log.c
builtin/merge.c
builtin/mv.c
builtin/notes.c
builtin/remote.c
builtin/reset.c
builtin/revert.c
builtin/rm.c
builtin/send-pack.c
builtin/shortlog.c
builtin/tag.c
config.mak.in
configure.ac
daemon.c
fast-import.c
git-am.sh
git-bisect.sh
git-pull.sh
git-submodule.sh
git.c
http-backend.c
http-fetch.c
http-push.c
t/lib-httpd.sh
t/t0001-init.sh
t/t1200-tutorial.sh
t/t2200-add-update.sh
t/t3030-merge-recursive.sh
t/t3200-branch.sh
t/t3203-branch-output.sh
t/t3501-revert-cherry-pick.sh
t/t4014-format-patch.sh
t/t4150-am.sh
t/t4151-am-abort.sh
t/t6040-tracking-info.sh
t/t7004-tag.sh
t/t7300-clean.sh
t/t7400-submodule-basic.sh
t/t7407-submodule-foreach.sh
t/t7500-commit.sh
t/t7501-commit.sh
t/t7502-commit.sh
t/t7508-status.sh
t/t7600-merge.sh
t/test-lib.sh
upload-pack.c
wt-status.c

diff --cc .gitignore
Simple merge
index ba2006d892ec09d606f8846588c7727396b1ee28,93fac9127328bd8b97f8f3c6d20c8962d6b72371..2ed2329834a8fceeb03b6d3243e73f463bb0e956
@@@ -144,54 -144,5 +148,57 @@@ For C programs
   - When we pass <string, length> pair to functions, we should try to
     pass them in that order.
  
+  - Use Git's gettext wrappers to make the user interface
+    translatable. See "Marking strings for translation" in po/README.
++
 +Writing Documentation:
 +
 + Every user-visible change should be reflected in the documentation.
 + The same general rule as for code applies -- imitate the existing
 + conventions.  A few commented examples follow to provide reference
 + when writing or modifying command usage strings and synopsis sections
 + in the manual pages:
 +
 + Placeholders are enclosed in angle brackets:
 +   <file>
 +   --sort=<key>
 +   --abbrev[=<n>]
 +
 + Possibility of multiple occurrences is indicated by three dots:
 +   <file>...
 +   (One or more of <file>.)
 +
 + Optional parts are enclosed in square brackets:
 +   [<extra>]
 +   (Zero or one <extra>.)
 +
 +   --exec-path[=<path>]
 +   (Option with an optional argument.  Note that the "=" is inside the
 +   brackets.)
 +
 +   [<patch>...]
 +   (Zero or more of <patch>.  Note that the dots are inside, not
 +   outside the brackets.)
 +
 + Multiple alternatives are indicated with vertical bar:
 +   [-q | --quiet]
 +   [--utf8 | --no-utf8]
 +
 + Parentheses are used for grouping:
 +   [(<rev>|<range>)...]
 +   (Any number of either <rev> or <range>.  Parens are needed to make
 +   it clear that "..." pertains to both <rev> and <range>.)
 +
 +   [(-p <parent>)...]
 +   (Any number of option -p, each with one <parent> argument.)
 +
 +   git remote set-head <name> (-a | -d | <branch>)
 +   (One and only one of "-a", "-d" or "<branch>" _must_ (no square
 +   brackets) be provided.)
 +
 + And a somewhat more contrived example:
 +   --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]
 +   Here "=" is outside the brackets, because "--diff-filter=" is a
 +   valid usage.  "*" has its own pair of brackets, because it can
 +   (optionally) be specified only when one or more of the letters is
 +   also provided.
diff --cc INSTALL
Simple merge
diff --cc Makefile
index 89c72aca1dca5df15786bd165f286271549f4320,e1650baa25d1e430dd5913006b123f26b046a2bf..7b024534536cc86350ed811b22e9a5886f3d0ae8
+++ b/Makefile
@@@ -863,7 -896,9 +913,10 @@@ ifeq ($(uname_S),SunOS
        NO_MKDTEMP = YesPlease
        NO_MKSTEMPS = YesPlease
        NO_REGEX = YesPlease
 +      NO_FNMATCH_CASEFOLD = YesPlease
+ ifndef NO_GETTEXT
+       GNU_GETTEXT =
+ endif
        ifeq ($(uname_R),5.6)
                SOCKLEN_T = int
                NO_HSTRERROR = YesPlease
diff --cc builtin.h
Simple merge
diff --cc builtin/add.c
index 5f817ad77f1b3ba247c3b76d1d9a50f7fcc5edee,eed37bfed33ae8e5ce0c2d0e2cceb8b936f06cee..ac9a5b4a40b08fb3ac81ec088d03df1de8d219eb
@@@ -447,11 -446,10 +447,11 @@@ int cmd_add(int argc, const char **argv
                        if (!seen[i] && pathspec[i][0]
                            && !file_exists(pathspec[i])) {
                                if (ignore_missing) {
 -                                      if (excluded(&dir, pathspec[i], DT_UNKNOWN))
 +                                      int dtype = DT_UNKNOWN;
 +                                      if (excluded(&dir, pathspec[i], &dtype))
                                                dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
                                } else
-                                       die("pathspec '%s' did not match any files",
+                                       die(_("pathspec '%s' did not match any files"),
                                            pathspec[i]);
                        }
                }
Simple merge
index 0ca8f6a2061b177410136fb89b988806a05eb16e,dd6f3b92ab22ffed4d88c19c7d6dedee4b15a9fd..054f363417c24e41271963f8339673b302bb41a6
@@@ -836,24 -835,21 +839,24 @@@ int cmd_checkout(int argc, const char *
                argc--;
  
                new.name = arg;
 -              if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
 -                      setup_branch_path(&new);
 +              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;
 +              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 */
 +
 +              if (!(new.commit = lookup_commit_reference_gently(rev, 1))) {
 +                      /* not a commit */
 +                      source_tree = parse_tree_indirect(rev);
 +              } else {
                        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);
+                       die(_("reference is not a tree: %s"), arg);
                if (!has_dash_dash) {/* case (3 -> 1) */
                        /*
                         * Do not complain the most common case
diff --cc builtin/clean.c
index 4a312abc6b3ecef5f174b2786ad31385ba058b44,52ec17a8345d815eaf8295bc702bbec75dba4cde..75697f711116e42df1e21e608c21829f49549b08
@@@ -150,10 -155,10 +155,10 @@@ int cmd_clean(int argc, const char **ar
                        } else if (remove_directories ||
                                   (matches == MATCHED_EXACTLY)) {
                                if (!quiet)
-                                       printf("Removing %s\n", qname);
+                                       printf(_("Removing %s\n"), qname);
                                if (remove_dir_recursively(&directory,
                                                           rm_flags) != 0) {
-                                       warning("failed to remove %s", qname);
 -                                      warning(_("failed to remove '%s'"), qname);
++                                      warning(_("failed to remove %s"), qname);
                                        errors++;
                                }
                        } else if (show_only) {
                                continue;
                        qname = quote_path_relative(ent->name, -1, &buf, prefix);
                        if (show_only) {
-                               printf("Would remove %s\n", qname);
+                               printf(_("Would remove %s\n"), qname);
                                continue;
                        } else if (!quiet) {
-                               printf("Removing %s\n", qname);
+                               printf(_("Removing %s\n"), qname);
                        }
                        if (unlink(ent->name) != 0) {
-                               warning("failed to remove %s", qname);
 -                              warning(_("failed to remove '%s'"), qname);
++                              warning(_("failed to remove %s"), qname);
                                errors++;
                        }
                }
diff --cc builtin/clone.c
Simple merge
index 03cff5af631fec975442c528b1ffba264b879c8e,0252dad4fe583b6e7f6f1c7380c4c2ecad17f22d..b6f9b679fd5721d488d862ee6813e3c7a211b1f8
@@@ -45,14 -45,14 +45,14 @@@ N_("Your name and email address were co
  "    git config --global user.name \"Your Name\"\n"
  "    git config --global user.email you@example.com\n"
  "\n"
 -"If the identity used for this commit is wrong, you can fix it with:\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 --author='Your Name <you@example.com>'\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");
  
  static unsigned char head_sha1[20];
  
@@@ -616,19 -586,9 +616,19 @@@ static int prepare_to_commit(const cha
                strbuf_add(&sb, buffer + 2, strlen(buffer + 2));
                hook_arg1 = "commit";
                hook_arg2 = use_message;
 +      } else if (fixup_message) {
 +              struct pretty_print_context ctx = {0};
 +              struct commit *commit;
 +              commit = lookup_commit_reference_by_name(fixup_message);
 +              if (!commit)
 +                      die("could not lookup commit %s", fixup_message);
 +              ctx.output_encoding = get_commit_output_encoding();
 +              format_commit_message(commit, "fixup! %s\n\n",
 +                                    &sb, &ctx);
 +              hook_arg1 = "message";
        } else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
                if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
-                       die_errno("could not read MERGE_MSG");
+                       die_errno(_("could not read MERGE_MSG"));
                hook_arg1 = "merge";
        } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
                if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
        else if (in_merge)
                hook_arg1 = "merge";
  
 +      if (squash_message) {
 +              /*
 +               * If squash_commit was used for the commit subject,
 +               * then we're possibly hijacking other commit log options.
 +               * Reset the hook args to tell the real story.
 +               */
 +              hook_arg1 = "message";
 +              hook_arg2 = "";
 +      }
 +
        fp = fopen(git_path(commit_editmsg), "w");
        if (fp == NULL)
-               die_errno("could not open '%s'", git_path(commit_editmsg));
+               die_errno(_("could not open '%s'"), git_path(commit_editmsg));
  
        if (cleanup_mode != CLEANUP_NONE)
                stripspace(&sb, 0);
  
        strbuf_release(&sb);
  
 -      determine_author_info();
 +      /* This checks and barfs if author is badly specified */
 +      determine_author_info(author_ident);
  
        /* This checks if committer ident is explicitly given */
 -      git_committer_info(0);
 +      strbuf_addstr(&committer_ident, git_committer_info(0));
        if (use_editor && include_status) {
 -              char *author_ident;
 -              const char *committer_ident;
 -
 +              char *ai_tmp, *ci_tmp;
                if (in_merge)
                        fprintf(fp,
-                               "#\n"
+                               _("#\n"
                                "# It looks like you may be committing a MERGE.\n"
                                "# If this is not correct, please remove the file\n"
                                "#      %s\n"
                if (only_include_assumed)
                        fprintf(fp, "# %s\n", only_include_assumed);
  
 -              author_ident = xstrdup(fmt_name(author_name, author_email));
 -              committer_ident = fmt_name(getenv("GIT_COMMITTER_NAME"),
 -                                         getenv("GIT_COMMITTER_EMAIL"));
 -              if (strcmp(author_ident, committer_ident))
 +              ai_tmp = cut_ident_timestamp_part(author_ident->buf);
 +              ci_tmp = cut_ident_timestamp_part(committer_ident.buf);
 +              if (strcmp(author_ident->buf, committer_ident.buf))
                        fprintf(fp,
-                               "%s"
-                               "# Author:    %s\n",
+                               _("%s"
+                               "# Author:    %s\n"),
                                ident_shown++ ? "" : "#\n",
 -                              author_ident);
 -              free(author_ident);
 +                              author_ident->buf);
  
                if (!user_ident_sufficiently_given())
                        fprintf(fp,
-                               "%s"
-                               "# Committer: %s\n",
+                               _("%s"
+                               "# Committer: %s\n"),
                                ident_shown++ ? "" : "#\n",
 -                              committer_ident);
 +                              committer_ident.buf);
  
                if (ident_shown)
                        fprintf(fp, "#\n");
@@@ -912,9 -861,9 +912,9 @@@ static int parse_and_validate_options(i
                force_author = find_author_by_nickname(force_author);
  
        if (force_author && renew_authorship)
-               die("Using both --reset-author and --author does not make sense");
+               die(_("Using both --reset-author and --author does not make sense"));
  
 -      if (logfile || message.len || use_message)
 +      if (logfile || message.len || use_message || fixup_message)
                use_editor = 0;
        if (edit_flag)
                use_editor = 1;
  
        /* 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.");
+               die(_("You are in the middle of a merge -- cannot amend."));
 -
 +      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)
        if (logfile)
                f++;
        if (f > 1)
-               die("Only one of -c/-C/-F/--fixup can be used.");
 -              die(_("Only one of -c/-C/-F can be used."));
++              die(_("Only one of -c/-C/-F/--fixup can be used."));
        if (message.len && f > 0)
-               die("Option -m cannot be combined with -c/-C/-F/--fixup.");
 -              die(_("Option -m cannot be combined with -c/-C/-F."));
++              die(_("Option -m cannot be combined with -c/-C/-F/--fixup."));
        if (edit_message)
                use_message = edit_message;
 -      if (amend && !use_message)
 +      if (amend && !use_message && !fixup_message)
                use_message = "HEAD";
        if (!use_message && 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) {
 -              unsigned char sha1[20];
 -              static char utf8[] = "UTF-8";
                const char *out_enc;
 -              char *enc, *end;
                struct commit *commit;
  
 -              if (get_sha1(use_message, sha1))
 +              commit = lookup_commit_reference_by_name(use_message);
 +              if (!commit)
-                       die("could not lookup commit %s", use_message);
+                       die(_("could not lookup commit %s"), use_message);
 -              commit = lookup_commit_reference(sha1);
 -              if (!commit || parse_commit(commit))
 -                      die(_("could not parse commit %s"), use_message);
 -
 -              enc = strstr(commit->buffer, "\nencoding");
 -              if (enc) {
 -                      end = strchr(enc + 10, '\n');
 -                      enc = xstrndup(enc + 10, end - (enc + 10));
 -              } else {
 -                      enc = utf8;
 -              }
 -              out_enc = git_commit_encoding ? git_commit_encoding : utf8;
 -
 -              if (strcmp(out_enc, enc))
 -                      use_message_buffer =
 -                              reencode_string(commit->buffer, out_enc, enc);
 +              out_enc = get_commit_output_encoding();
 +              use_message_buffer = logmsg_reencode(commit, out_enc);
  
                /*
                 * If we failed to reencode the buffer, just copy it
@@@ -1397,11 -1352,11 +1397,11 @@@ int cmd_commit(int argc, const char **a
        }
  
        if (commit_tree(sb.buf, active_cache_tree->sha1, parents, commit_sha1,
 -                      fmt_ident(author_name, author_email, author_date,
 -                              IDENT_ERROR_ON_NO_NAME))) {
 +                      author_ident.buf)) {
                rollback_index_files();
-               die("failed to write commit object");
+               die(_("failed to write commit object"));
        }
 +      strbuf_release(&author_ident);
  
        ref_lock = lock_any_ref_for_update("HEAD",
                                           initial_commit ? NULL : head_sha1,
index 342129fdbdc534bdf9277de710f8e7b7ba11c5c4,616d405ef526ae86de70fbe4434e8df89c38d4fd..037691e3d30ef2c6b80b23fa0fbcad67759560e2
@@@ -264,12 -235,12 +264,12 @@@ static void describe(const char *arg, i
        unsigned int unannotated_cnt = 0;
  
        if (get_sha1(arg, sha1))
-               die("Not a valid object name %s", arg);
+               die(_("Not a valid object name %s"), arg);
        cmit = lookup_commit_reference(sha1);
        if (!cmit)
-               die("%s is not a valid '%s' object", arg, commit_type);
+               die(_("%s is not a valid '%s' object"), arg, commit_type);
  
 -      n = cmit->util;
 +      n = find_commit_name(cmit->object.sha1);
        if (n && (tags || all || n->prio == 2)) {
                /*
                 * Exact match to an existing ref.
        }
  
        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);
 +              have_util = 1;
 +      }
 +
        list = NULL;
        cmit->object.flags = SEEN;
        commit_list_insert(cmit, &list);
@@@ -452,10 -418,9 +452,10 @@@ int cmd_describe(int argc, const char *
                return cmd_name_rev(i + argc, args, prefix);
        }
  
 -      for_each_ref(get_name, NULL);
 -      if (!found_names && !always)
 +      init_hash(&names);
 +      for_each_rawref(get_name, NULL);
 +      if (!names.nr && !always)
-               die("No names found, cannot describe anything.");
+               die(_("No names found, cannot describe anything."));
  
        if (argc == 0) {
                if (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, diff_index_args, prefix))
diff --cc builtin/diff.c
index d12de8f392fc660c5048062f2a754a9f63e897fb,3ae571519b2c988f6c9c13d944d9fc10e12e8b93..3cefb872e970e6f362550b9ad2485be508725f4a
@@@ -369,12 -369,16 +369,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;
        }
  
        /*
Simple merge
diff --cc builtin/fetch.c
Simple merge
diff --cc builtin/gc.c
Simple merge
diff --cc builtin/grep.c
index c3af8760cc778b4eb835d4fb543f45aa333b214c,3a57b4c8c0c9d8a47357d11079fadc6258c47ee2..dcbc7a936d6ddc96f4d074b87d19d4e5b936ca41
@@@ -549,16 -668,12 +549,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;
        }
@@@ -580,24 -694,16 +580,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;
@@@ -958,12 -1063,9 +958,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 e3af9eaa877089639d6ba4f47d7155a0c1ee106e,28e20f9607497e5fe35632b9fb2ddac44ac5004c..95387b70f715937c35010ac5028df8f5be8e500a
@@@ -481,10 -484,10 +485,10 @@@ int cmd_init_db(int argc, const char **
         * without --bare.  Catch the error early.
         */
        git_dir = getenv(GIT_DIR_ENVIRONMENT);
 -      if ((!git_dir || is_bare_repository_cfg == 1)
 -          && getenv(GIT_WORK_TREE_ENVIRONMENT))
 +      work_tree = getenv(GIT_WORK_TREE_ENVIRONMENT);
 +      if ((!git_dir || is_bare_repository_cfg == 1) && work_tree)
-               die("%s (or --work-tree=<directory>) not allowed without "
-                   "specifying %s (or --git-dir=<directory>)",
+               die(_("%s (or --work-tree=<directory>) not allowed without "
 -                        "specifying %s (or --git-dir=<directory>)"),
++                    "specifying %s (or --git-dir=<directory>)"),
                    GIT_WORK_TREE_ENVIRONMENT,
                    GIT_DIR_ENVIRONMENT);
  
                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));
 +              else
 +                      set_git_work_tree(git_work_tree_cfg);
                if (access(get_git_work_tree(), X_OK))
-                       die_errno ("Cannot access work tree '%s'",
+                       die_errno (_("Cannot access work tree '%s'"),
                                   get_git_work_tree());
        }
 +      else {
 +              if (work_tree)
 +                      set_git_work_tree(make_absolute_path(work_tree));
 +      }
  
        set_git_dir(make_absolute_path(git_dir));
  
diff --cc builtin/log.c
Simple merge
diff --cc builtin/merge.c
index b573d9804a4a20b7a05e56db6f81ce6bf0f16cf3,62bdd6c77577be392825f0208a59bdce4d9e0236..2511361eca0fb7531c912891a9ce0b48e4223c49
@@@ -236,27 -231,9 +236,27 @@@ static void save_state(void
                return;
        strbuf_setlen(&buffer, buffer.len-1);
        if (get_sha1(buffer.buf, stash))
-               die("not a valid object: %s", buffer.buf);
+               die(_("not a valid object: %s"), buffer.buf);
  }
  
 +static void read_empty(unsigned const char *sha1, int verbose)
 +{
 +      int i = 0;
 +      const char *args[7];
 +
 +      args[i++] = "read-tree";
 +      if (verbose)
 +              args[i++] = "-v";
 +      args[i++] = "-m";
 +      args[i++] = "-u";
 +      args[i++] = EMPTY_TREE_SHA1_HEX;
 +      args[i++] = sha1_to_hex(sha1);
 +      args[i] = NULL;
 +
 +      if (run_command_v_opt(args, RUN_GIT_CMD))
 +              die("read-tree failed");
 +}
 +
  static void reset_hard(unsigned const char *sha1, int verbose)
  {
        int i = 0;
@@@ -581,11 -558,10 +581,11 @@@ static int read_tree_trivial(unsigned c
  static void write_tree_trivial(unsigned char *sha1)
  {
        if (write_cache_as_tree(sha1, 0, NULL))
-               die("git write-tree failed to write a tree");
+               die(_("git write-tree failed to write a tree"));
  }
  
 -int try_merge_command(const char *strategy, struct commit_list *common,
 +int try_merge_command(const char *strategy, size_t xopts_nr,
 +                    const char **xopts, struct commit_list *common,
                      const char *head_arg, struct commit_list *remotes)
  {
        const char **args;
@@@ -949,34 -935,6 +949,34 @@@ int cmd_merge(int argc, const char **ar
  
        argc = parse_options(argc, argv, prefix, builtin_merge_options,
                        builtin_merge_usage, 0);
-                       die("There is no merge to abort (MERGE_HEAD missing).");
 +
 +      if (abort_current_merge) {
 +              int nargc = 2;
 +              const char *nargv[] = {"reset", "--merge", NULL};
 +
 +              if (!file_exists(git_path("MERGE_HEAD")))
-                       die("You have not concluded your merge (MERGE_HEAD exists).\n"
-                           "Please, commit your changes before you can merge.");
++                      die(_("There is no merge to abort (MERGE_HEAD missing)."));
 +
 +              /* Invoke 'git reset --merge' */
 +              return cmd_reset(nargc, nargv, prefix);
 +      }
 +
 +      if (read_cache_unmerged())
 +              die_resolve_conflict("merge");
 +
 +      if (file_exists(git_path("MERGE_HEAD"))) {
 +              /*
 +               * There is no unmerged entry, don't advise 'git
 +               * add/rm <file>', just 'git commit'.
 +               */
 +              if (advice_resolve_conflict)
-                       die("You have not concluded your merge (MERGE_HEAD exists).");
++                      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)."));
 +      }
 +      resolve_undo_clear();
 +
        if (verbosity < 0)
                show_diffstat = 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]);
                update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0,
                                DIE_ON_ERR);
 -              reset_hard(remote_head->sha1, 0);
 +              read_empty(remote_head->sha1, 0);
                return 0;
        } else {
                struct strbuf merge_names = STRBUF_INIT;
diff --cc builtin/mv.c
Simple merge
diff --cc builtin/notes.c
index 4d5556e2cb5bccaf0100d9f5019e1a1c493e35e7,e33e39a50a22f2e5c597f06aa6f0bbdc0b2ee048..91d792928d4b2545dd9fd158d46dd214acbfa998
@@@ -306,9 -280,9 +306,9 @@@ void commit_notes(struct notes_tree *t
        if (!t)
                t = &default_notes_tree;
        if (!t->initialized || !t->ref || !*t->ref)
-               die("Cannot commit uninitialized/unreferenced notes tree");
+               die(_("Cannot commit uninitialized/unreferenced notes tree"));
        if (!t->dirty)
 -              return 0; /* don't have to commit an unchanged tree */
 +              return; /* don't have to commit an unchanged tree */
  
        /* Prepare commit message and reflog message */
        strbuf_addstr(&buf, "notes: "); /* commit message starts at index 7 */
@@@ -1066,10 -873,8 +1070,10 @@@ int cmd_notes(int argc, const char **ar
                result = remove_cmd(argc, argv, prefix);
        else if (!strcmp(argv[0], "prune"))
                result = prune(argc, argv, prefix);
 +      else if (!strcmp(argv[0], "get-ref"))
 +              result = get_ref(argc, argv, prefix);
        else {
-               result = error("Unknown subcommand: %s", argv[0]);
+               result = error(_("Unknown subcommand: %s"), argv[0]);
                usage_with_options(git_notes_usage, options);
        }
  
Simple merge
diff --cc builtin/reset.c
Simple merge
index dc1b702edc6b4bd95ebf41c12bf1da6fe9d6850d,c8463d23ca65b8b0d8089288fb2b1b023fd47179..d4631d7d5495469d0cd17be8b6536bcb9cfe19eb
@@@ -556,27 -553,12 +568,28 @@@ static void prepare_revs(struct rev_inf
                usage(*revert_or_cherry_pick_usage());
  
        if (prepare_revision_walk(revs))
-               die("revision walk setup failed");
+               die(_("revision walk setup failed"));
  
        if (!revs->commits)
-               die("empty commit set passed");
+               die(_("empty commit set passed"));
  }
  
-                       die("git %s: failed to refresh the index", me);
 +static void read_and_refresh_cache(const char *me)
 +{
 +      static struct lock_file index_lock;
 +      int index_fd = hold_locked_index(&index_lock, 0);
 +      if (read_index_preload(&the_index, NULL) < 0)
 +              die("git %s: failed to read the index", me);
 +      refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, NULL, NULL, NULL);
 +      if (the_index.cache_changed) {
 +              if (write_index(&the_index, index_fd) ||
 +                  commit_locked_index(&index_lock))
++                      /* TRANSLATORS: %s will be "revert" or "cherry-pick" */
++                      die(_("git %s: failed to read the index"), me);
 +      }
 +      rollback_lock_file(&index_lock);
 +}
 +
  static int revert_or_cherry_pick(int argc, const char **argv)
  {
        struct rev_info revs;
  
        if (allow_ff) {
                if (signoff)
-                       die("cherry-pick --ff cannot be used with --signoff");
+                       die(_("cherry-pick --ff cannot be used with --signoff"));
                if (no_commit)
-                       die("cherry-pick --ff cannot be used with --no-commit");
+                       die(_("cherry-pick --ff cannot be used with --no-commit"));
                if (no_replay)
-                       die("cherry-pick --ff cannot be used with -x");
+                       die(_("cherry-pick --ff cannot be used with -x"));
                if (edit)
-                       die("cherry-pick --ff cannot be used with --edit");
+                       die(_("cherry-pick --ff cannot be used with --edit"));
        }
  
 -      if (read_cache() < 0)
 -              /* TRANSLATORS: %s will be "revert" or "cherry-pick" */
 -              die(_("git %s: failed to read the index"), me);
 +      read_and_refresh_cache(me);
  
        prepare_revs(&revs);
  
diff --cc builtin/rm.c
Simple merge
Simple merge
Simple merge
diff --cc builtin/tag.c
Simple merge
diff --cc config.mak.in
Simple merge
diff --cc configure.ac
Simple merge
diff --cc daemon.c
index 347fd0c52b4cd797f5dafffb6885324f7c7f0274,c69f722588c38dbb1f53457c9d0af105f0decd39..d9f2291cc7e744ad2b815fa74b99ad13588101ff
+++ b/daemon.c
@@@ -4,7 -4,10 +4,8 @@@
  #include "run-command.h"
  #include "strbuf.h"
  #include "string-list.h"
+ #include "gettext.h"
  
 -#include <syslog.h>
 -
  #ifndef HOST_NAME_MAX
  #define HOST_NAME_MAX 256
  #endif
@@@ -1047,12 -994,16 +1048,14 @@@ int main(int argc, char **argv
  {
        int listen_port = 0;
        struct string_list listen_addr = STRING_LIST_INIT_NODUP;
 -      int inetd_mode = 0;
 +      int serve_mode = 0, inetd_mode = 0;
        const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
        int detach = 0;
 -      struct passwd *pass = NULL;
 -      struct group *group;
 -      gid_t gid = 0;
 +      struct credentials *cred = NULL;
        int i;
  
+       git_setup_gettext();
        git_extract_argv0_path(argv[0]);
  
        for (i = 1; i < argc; i++) {
diff --cc fast-import.c
index 60f26fe473ad6922166e952f4f7e5be2b79d45de,bbd7c3968115c850a6c26e526ffec54a533e7e86..3cbc26bbddced46736391c1893af67d7419de27f
@@@ -159,7 -156,7 +159,8 @@@ Format of STDIN stream
  #include "csum-file.h"
  #include "quote.h"
  #include "exec_cmd.h"
 +#include "dir.h"
+ #include "gettext.h"
  
  #define PACK_ID_BITS 16
  #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
diff --cc git-am.sh
Simple merge
diff --cc git-bisect.sh
index c21e33c8d133af0e9e0ae3edaffd0a5593ff4ac3,b5836dd53b680fb400a1e5a0c3a3af0f42c98350..9b79fe47ff332d31e04e6eda85df47f48917a2e1
@@@ -343,8 -348,8 +353,9 @@@ bisect_clean_state() 
  }
  
  bisect_replay () {
-       test -r "$1" || die "cannot read $1 for replaying"
 +      test "$#" -eq 1 || die "No logfile given"
+       file="$1"
+       test -r "$file" || die "$(eval_gettext "cannot read \$file for replaying")"
        bisect_reset
        while read git bisect command rev
        do
diff --cc git-pull.sh
index eb87f49062b70d707adebca4013809822123608b,833e62a92e86dbd2cf9b56712d5e1b16ad360753..cb804546fc707ca3de6683aa845c82a5361d858d
@@@ -204,10 -223,13 +229,10 @@@ test true = "$rebase" && 
                # On an unborn branch
                if test -f "$GIT_DIR/index"
                then
-                       die "updating an unborn branch with changes added to the index"
+                       die "$(gettext "updating an unborn branch with changes added to the index")"
                fi
        else
 -              git update-index --ignore-submodules --refresh &&
 -              git diff-files --ignore-submodules --quiet &&
 -              git diff-index --ignore-submodules --cached --quiet HEAD -- ||
 -              die "$(gettext "refusing to pull with rebase: your working tree is not up-to-date")"
 +              require_clean_work_tree "pull with rebase" "Please commit or stash them."
        fi
        oldremoteref= &&
        . git-parse-remote &&
index 8b9058971767dbb4d94e996876f6ba7ed178ddd6,3de519ac44616b54fbeb8f095cf2518e278ab025..37f8bfab8130d9c38fc167220c0cadebebc7f1f7
@@@ -34,10 -35,9 +35,10 @@@ resolve_relative_url (
  {
        remote=$(get_default_remote)
        remoteurl=$(git config "remote.$remote.url") ||
-               die "remote ($remote) does not have a url defined in .git/config"
+               die "$(eval_gettext "remote (\$remote) does not have a url defined in .git/config")"
        url="$1"
        remoteurl=${remoteurl%/}
 +      sep=/
        while test -n "$url"
        do
                case "$url" in
@@@ -239,9 -242,9 +240,9 @@@ Use -f if you really want to add it.")
                        # ash fails to wordsplit ${branch:+-b "$branch"...}
                        case "$branch" in
                        '') git checkout -f -q ;;
 -                      ?*) git checkout -f -q -b "$branch" "origin/$branch" ;;
 +                      ?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
                        esac
-               ) || die "Unable to checkout submodule '$path'"
+               ) || die "$(eval_gettext "Unable to checkout submodule '\$path'")"
        fi
  
        git add $force "$path" ||
@@@ -494,8 -500,8 +494,8 @@@ Maybe you want to use 'update --init'?"
  
                if test -n "$recursive"
                then
-                       (clear_local_git_env; cd "$path" && eval cmd_update "$orig_flags") ||
-                       die "Failed to recurse into submodule path '$path'"
 -                      (clear_local_git_env; cd "$path" && cmd_update $orig_args) ||
++                      (clear_local_git_env; cd "$path" && eval cmd_update $orig_args) ||
+                       die "$(eval_gettext "Failed to recurse into submodule path '\$path'")"
                fi
        done
  }
@@@ -785,9 -792,9 +787,9 @@@ cmd_status(
                                prefix="$displaypath/"
                                clear_local_git_env
                                cd "$path" &&
 -                              cmd_status $orig_args
 +                              eval cmd_status "$orig_args"
                        ) ||
-                       die "Failed to recurse into submodule path '$path'"
+                       die "$(eval_gettext "Failed to recurse into submodule path '\$path'")"
                fi
        done
  }
@@@ -831,9 -838,6 +833,9 @@@ cmd_sync(
                        ;;
                esac
  
-               say "Synchronizing submodule url for '$name'"
++              say "$(eval_gettext "Synchronizing submodule url for '\$name'")"
 +              git config submodule."$name".url "$url"
 +
                if test -e "$path"/.git
                then
                (
diff --cc git.c
Simple merge
diff --cc http-backend.c
Simple merge
diff --cc http-fetch.c
Simple merge
diff --cc http-push.c
index ff41a0e183dd3a449f5136c6d1488a31b4a8960b,fc2c5f7f652d25c0b26184250f54bc6ccb7c8dee..4ec3741cb0ea581c79725dd845da1a1057d313bb
@@@ -1801,7 -1790,10 +1802,9 @@@ int main(int argc, char **argv
        int new_refs;
        struct ref *ref, *local_refs;
        struct remote *remote;
 -      char *rewritten_url = NULL;
  
+       git_setup_gettext();
        git_extract_argv0_path(argv[0]);
  
        repo = xcalloc(sizeof(*repo), 1);
diff --cc t/lib-httpd.sh
Simple merge
diff --cc t/t0001-init.sh
index f6849932112f1bbea1dafad09150857a707b64e4,b45df242b1f1929ef0a1cdf415a1cdc7cfa439e2..4235ad4385fa7ab51aa201be7d859d6965e83154
@@@ -180,10 -124,10 +180,10 @@@ test_expect_success 'GIT_DIR & GIT_WORK
        fi
  '
  
- test_expect_success 'reinit' '
+ test_expect_success NO_GETTEXT_POISON 'reinit' '
  
        (
 -              unset GIT_CONFIG GIT_WORK_TREE GIT_CONFIG
 +              sane_unset GIT_CONFIG GIT_WORK_TREE GIT_CONFIG &&
  
                mkdir again &&
                cd again &&
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 043954422c82d9afbb318bcb7d1aa5685a391c85,b12b1b47b30b9008781dc07b82b1894414e6d868..76d3252c89ae53e522bf77c9bd6d260504c53f34
@@@ -81,17 -81,7 +81,17 @@@ test_expect_success 'revert after renam
  
  '
  
- test_expect_success 'revert forbidden on dirty working tree' '
 +test_expect_success 'cherry-pick on stat-dirty working tree' '
 +      git clone . copy &&
 +      (
 +              cd copy &&
 +              git checkout initial &&
 +              test-chmtime +40 oops &&
 +              git cherry-pick added
 +      )
 +'
 +
+ test_expect_success NO_GETTEXT_POISON 'revert forbidden on dirty working tree' '
  
        echo content >extra_file &&
        git add extra_file &&
Simple merge
diff --cc t/t4150-am.sh
Simple merge
Simple merge
Simple merge
diff --cc t/t7004-tag.sh
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 50da034cd3934d0509e67a6f20e514a18e5659d4,e1af8adb4d99bdac43d79960bd64adfb60bc2f60..d7c4280e8fcc79e6f3e4109ec61c553a0ed3a182
@@@ -388,9 -402,9 +402,9 @@@ try_commit_status_combo () 
                grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
        '
  
-       test_expect_success 'commit --no-status' '
+       test_expect_success NO_GETTEXT_POISON 'commit --no-status' '
                clear_config commit.status &&
 -              try_commit --no-status
 +              try_commit --no-status &&
                ! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG
        '
  
Simple merge
Simple merge
diff --cc t/test-lib.sh
Simple merge
diff --cc upload-pack.c
Simple merge
diff --cc wt-status.c
index a82b11d341c9dddb541cc72a5568769d9f538780,27cafd9e3c3beb4d2fdfbdd911621db6e5786ac7..57bf1033bb665dd4580abda7d7f6f78422506005
@@@ -92,7 -88,7 +92,7 @@@ static void wt_status_print_dirty_heade
  {
        const char *c = color(WT_STATUS_HEADER, s);
  
-       color_fprintf_ln(s->fp, c, "# Changes not staged for commit:");
 -      color_fprintf_ln(s->fp, c, _("# Changed but not updated:"));
++      color_fprintf_ln(s->fp, c, _("# Changes not staged for commit:"));
        if (!advice_status_hints)
                return;
        if (!has_deleted)
@@@ -632,22 -625,20 +632,22 @@@ static void wt_status_print_tracking(st
  
  void wt_status_print(struct wt_status *s)
  {
 -      const char *branch_color = color(WT_STATUS_HEADER, s);
 +      const char *branch_color = color(WT_STATUS_ONBRANCH, s);
 +      const char *branch_status_color = color(WT_STATUS_HEADER, s);
  
        if (s->branch) {
-               const char *on_what = "On branch ";
+               const char *on_what = _("On branch ");
                const char *branch_name = s->branch;
                if (!prefixcmp(branch_name, "refs/heads/"))
                        branch_name += 11;
                else if (!strcmp(branch_name, "HEAD")) {
                        branch_name = "";
 -                      branch_color = color(WT_STATUS_NOBRANCH, s);
 +                      branch_status_color = color(WT_STATUS_NOBRANCH, s);
-                       on_what = "Not currently on any branch.";
+                       on_what = _("Not currently on any branch.");
                }
                color_fprintf(s->fp, color(WT_STATUS_HEADER, s), "# ");
 -              color_fprintf_ln(s->fp, branch_color, "%s%s", on_what, branch_name);
 +              color_fprintf(s->fp, branch_status_color, "%s", on_what);
 +              color_fprintf_ln(s->fp, branch_color, "%s", branch_name);
                if (!s->is_initial)
                        wt_status_print_tracking(s);
        }