Code

Merge branch 'da/difftool-test'
authorJunio C Hamano <gitster@pobox.com>
Mon, 16 Apr 2012 05:52:04 +0000 (22:52 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 16 Apr 2012 05:52:04 +0000 (22:52 -0700)
Makes sure "difftool" options can be given in any order.

By David Aguilar
* da/difftool-test:
  t7800: Test difftool passing arguments to diff

96 files changed:
.mailmap
Documentation/RelNotes/1.7.10.txt
Documentation/RelNotes/1.7.11.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.9.5.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.9.6.txt [new file with mode: 0644]
Documentation/git-grep.txt
Documentation/git-rebase.txt
Documentation/git-sh-i18n--envsubst.txt
Documentation/git-submodule.txt
Documentation/git.txt
Documentation/gitmodules.txt
Documentation/gitweb.txt
Documentation/howto/using-merge-subtree.txt
Documentation/technical/api-string-list.txt
GIT-VERSION-GEN
RelNotes
attr.h
builtin/cat-file.c
builtin/commit.c
builtin/config.c
builtin/fsck.c
builtin/log.c
builtin/merge.c
builtin/update-server-info.c
cache.h
contrib/completion/git-completion.bash
contrib/subtree/.gitignore [new file with mode: 0644]
contrib/subtree/COPYING [new file with mode: 0644]
contrib/subtree/INSTALL [new file with mode: 0644]
contrib/subtree/Makefile [new file with mode: 0644]
contrib/subtree/README [new file with mode: 0644]
contrib/subtree/git-subtree.sh [new file with mode: 0755]
contrib/subtree/git-subtree.txt [new file with mode: 0644]
contrib/subtree/t/Makefile [new file with mode: 0644]
contrib/subtree/t/t7900-subtree.sh [new file with mode: 0755]
contrib/subtree/todo [new file with mode: 0644]
contrib/svn-fe/svn-fe.txt
diff.c
diff.h
dir.c
dir.h
entry.c
git.spec.in
gitk-git/gitk
gitweb/gitweb.perl
gitweb/static/js/lib/cookies.js
http.c
http.h
ident.c
merge-recursive.c
notes-merge.c
object.c
perl/Git.pm
po/README
po/TEAMS
po/git.pot
po/nl.po [new file with mode: 0644]
po/pt_PT.po [new file with mode: 0644]
po/sv.po
po/zh_CN.po
pretty.c
sha1_file.c
streaming.c
streaming.h
submodule.h
t/t0303-credential-external.sh
t/t1050-large.sh
t/t3300-funny-names.sh
t/t3310-notes-merge-manual-resolve.sh
t/t3508-cherry-pick-many-commits.sh
t/t3903-stash.sh
t/t4012-diff-binary.sh
t/t4013-diff-various.sh
t/t4014-format-patch.sh
t/t4016-diff-quote.sh
t/t4030-diff-textconv.sh
t/t4031-diff-rewrite-binary.sh
t/t4034-diff-words.sh
t/t4043-diff-rename-binary.sh
t/t4045-diff-relative.sh
t/t4047-diff-dirstat.sh
t/t4049-diff-stat-count.sh
t/t4100-apply-stat.sh
t/t5150-request-pull.sh
t/t7503-pre-commit-hook.sh
t/t7602-merge-octopus-many.sh
t/t7607-merge-overwrite.sh
t/test-lib.sh
test-subprocess.c
transport.c
wrapper.c
xdiff/xdiff.h
xdiff/xdiffi.c
xdiff/xhistogram.c
xdiff/xpatience.c
xdiff/xprepare.c

index 19c87262322cf5acc9d4fd5fa06f96eb3e988049..6303782106cc733dd06ad6e85c866610aa020c65 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -29,7 +29,13 @@ Joachim Berdal Haga <cjhaga@fys.uio.no>
 Jon Loeliger <jdl@freescale.com>
 Jon Seymour <jon@blackcubes.dyndns.org>
 Jonathan Nieder <jrnieder@uchicago.edu>
-Junio C Hamano <junio@twinsun.com>
+Junio C Hamano <gitster@pobox.com> <gitster@pobox.com>
+Junio C Hamano <gitster@pobox.com> <junio@pobox.com>
+Junio C Hamano <gitster@pobox.com> <junio@twinsun.com>
+Junio C Hamano <gitster@pobox.com> <junkio@twinsun.com>
+Junio C Hamano <gitster@pobox.com> <junio@hera.kernel.org>
+Junio C Hamano <gitster@pobox.com> <junio@kernel.org>
+Junio C Hamano <gitster@pobox.com> <junkio@cox.net>
 Karl Hasselström <kha@treskal.com>
 Kent Engstrom <kent@lysator.liu.se>
 Lars Doelle <lars.doelle@on-line ! de>
index 238234ed7cc3813804489a8c49051f7811160293..58100bf04e1c3b7e7f4440eb3df9696b3a5343df 100644 (file)
@@ -19,7 +19,7 @@ Compatibility Notes
        GIT_MERGE_AUTOEDIT=no
        export GIT_MERGE_AUTOEDIT
 
-   to disable this behaviour (if you want your users to explain their
+   to disable this behavior (if you want your users to explain their
    merge commits, you do not have to do anything).  Alternatively, you
    can give the "--no-edit" option to individual invocations of the
    "git merge" command if you know everybody who uses your script has
@@ -29,16 +29,37 @@ Compatibility Notes
    while and were deprecated in mid 2008 (v1.6.0).  When you give these
    options to "git am", it will now warn and ask you not to use them.
 
+ * When you do not tell which branches and tags to push to the "git
+   push" command in any way, the command used "matching refs" rule to
+   update remote branches and tags with branches and tags with the
+   same name you locally have.  In future versions of Git, this will
+   change to push out only your current branch according to either the
+   "upstream" or the "current" rule.  Although "upstream" may be more
+   powerful once the user understands Git better, the semantics
+   "current" gives is simpler and easier to understand for beginners
+   and may be a safer and better default option.  We haven't decided
+   yet which one to switch to.
+
 
 Updates since v1.7.9
 --------------------
 
 UI, Workflows & Features
 
+ * various "gitk" updates.
+   - show the path to the top level directory in the window title
+   - update preference edit dialog
+   - display file list correctly when directories are given on command line
+   - make "git-describe" output in the log message into a clickable link
+   - avoid matching the UNIX timestamp part when searching all fields
+   - give preference to symbolic font names like sans & monospace
+   - allow comparing two commits using a mark
+   - "gitk" honors log.showroot configuration.
+
  * Teams for localizing the messages from the Porcelain layer of
    commands are starting to form, thanks to Jiang Xin who volunteered
-   to be the localization coordinator.  An initial set of translated
-   messages for simplified chinese is available.
+   to be the localization coordinator.  Translated messages for
+   simplified Chinese, Swedish and Portuguese are available.
 
  * The configuration mechanism learned an "include" facility; an
    assignment to the include.path pseudo-variable causes the named
@@ -119,6 +140,8 @@ UI, Workflows & Features
  * Project search in "gitweb" shows the substring that matched in the
    project name and description highlighted.
 
+ * HTTP transport learned to authenticate with a proxy if needed.
+
  * A new script "diffall" is added to contrib/; it drives an
    external tool to perform a directory diff of two Git revisions
    in one go, unlike "difftool" that compares one file at a time.
@@ -180,35 +203,17 @@ Unless otherwise noted, all the fixes since v1.7.9 in the maintenance
 releases are contained in this release (see release notes to them for
 details).
 
- * "git fast-import" accepted "ls" command with an empty path by
-   mistake.
-   (merge 178e1de jn/maint-fast-import-empty-ls later to maint).
-
- * The "remaining" subcommand to "git rerere" was not documented.
-   (merge 3e7a1df ph/rerere-doc later to maint).
+ * Build with NO_PERL_MAKEMAKER was broken and Git::I18N did not work
+   with versions of Perl older than 5.8.3.
+   (merge 5eb660e ab/perl-i18n later to maint).
 
  * "git tag -s" honored "gpg.program" configuration variable since
    1.7.9, but "git tag -v" and "git verify-tag" didn't.
    (merge a2c2506 az/verify-tag-use-gpg-config later to maint).
 
- * When "git config" diagnoses an error in a configuration file and
-   shows the line number for the offending line, it miscounted if the
-   error was at the end of line.
-   (merge 4b34059 ms/maint-config-error-at-eol-linecount later to maint).
-
- * "configure" script learned to take "--sane-tool-path" from the
-   command line to record SANE_TOOL_PATH (used to avoid broken
-   platform tools in /usr/bin) in config.mak-autogen.  This may be useful
-   for people on Solaris who have saner tools outside /usr/xpg[46]/bin.
-
- * "gitweb" used to drop warnings in the log file when "heads" view is
-   accessed in a repository whose HEAD does not point at a valid
-   branch.
-
----
-exec >/var/tmp/1
-O=v1.7.10-rc1-18-g0987145
-echo O=$(git describe)
-git log --first-parent --oneline ^maint $O..
-echo
-git shortlog --no-merges ^maint $O..
+ * "configure" script learned to take "--with-sane-tool-path" from the
+   command line to record SANE_TOOL_PATH (used to avoid broken platform
+   tools in /usr/bin) in config.mak.autogen.  This may be useful for
+   people on Solaris who have saner tools outside /usr/xpg[46]/bin.
+
+ * zsh port of bash completion script needed another workaround.
diff --git a/Documentation/RelNotes/1.7.11.txt b/Documentation/RelNotes/1.7.11.txt
new file mode 100644 (file)
index 0000000..a65966e
--- /dev/null
@@ -0,0 +1,29 @@
+Git v1.7.11 Release Notes
+=========================
+
+Updates since v1.7.10
+---------------------
+
+UI, Workflows & Features
+
+ * A third-party tool "git subtree" is distributed in contrib/
+
+
+Foreign Interface
+
+
+Performance
+
+
+Internal Implementation (please report possible regressions)
+
+
+Also contains minor documentation updates and code clean-ups.
+
+
+Fixes since v1.7.10
+-------------------
+
+Unless otherwise noted, all the fixes since v1.7.10 in the maintenance
+releases are contained in this release (see release notes to them for
+details).
diff --git a/Documentation/RelNotes/1.7.9.5.txt b/Documentation/RelNotes/1.7.9.5.txt
new file mode 100644 (file)
index 0000000..95cc2bb
--- /dev/null
@@ -0,0 +1,23 @@
+Git v1.7.9.5 Release Notes
+==========================
+
+Fixes since v1.7.9.4
+--------------------
+
+ * When "git config" diagnoses an error in a configuration file and
+   shows the line number for the offending line, it miscounted if the
+   error was at the end of line.
+
+ * "git fast-import" accepted "ls" command with an empty path by
+   mistake.
+
+ * Various new-ish output decoration modes of "git grep" were not
+   documented in the manual's synopsis section.
+
+ * The "remaining" subcommand to "git rerere" was not documented.
+
+ * "gitweb" used to drop warnings in the log file when "heads" view is
+   accessed in a repository whose HEAD does not point at a valid
+   branch.
+
+Also contains minor fixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.9.6.txt b/Documentation/RelNotes/1.7.9.6.txt
new file mode 100644 (file)
index 0000000..74bf882
--- /dev/null
@@ -0,0 +1,12 @@
+Git v1.7.9.6 Release Notes
+==========================
+
+Fixes since v1.7.9.5
+--------------------
+
+ * "git merge $tag" to merge an annotated tag always opens the editor
+   during an interactive edit session. v1.7.10 series introduced an
+   environment variable GIT_MERGE_AUTOEDIT to help older scripts decline
+   this behaviour, but the maintenance track should also support it.
+
+Also contains minor fixes and documentation updates.
index 6a8b1e3a7d06218903ce5614f51c4e7cbba73b17..343eadd4076664cc66c9d22db22d800e92cc6dc6 100644 (file)
@@ -20,7 +20,9 @@ SYNOPSIS
           [-c | --count] [--all-match] [-q | --quiet]
           [--max-depth <depth>]
           [--color[=<when>] | --no-color]
+          [--break] [--heading] [-p | --show-function]
           [-A <post-context>] [-B <pre-context>] [-C <context>]
+          [-W | --function-context]
           [-f <file>] [-e] <pattern>
           [--and|--or|--not|(|)|-e <pattern>...]
           [ [--exclude-standard] [--cached | --no-index | --untracked] | <tree>...]
index 504945c69153a30252527c16945836fd2aa2ec5a..520aaa94fb7b2be7c11e7eed013acf36055a41ab 100644 (file)
@@ -409,10 +409,13 @@ The interactive mode is meant for this type of workflow:
 
 where point 2. consists of several instances of
 
-a. regular use
+a) regular use
+
  1. finish something worthy of a commit
  2. commit
-b. independent fixup
+
+b) independent fixup
+
  1. realize that something does not work
  2. fix that
  3. commit it
index 5c3ec327bbc5836c53b0b94f9dc0de4772661e36..2ffaf9392e59dac1a4d945b4a5a42dd45371e5cd 100644 (file)
@@ -25,7 +25,7 @@ plumbing scripts and/or are writing new ones.
 'git sh-i18n{litdd}envsubst' is Git's stripped-down copy of the GNU
 `envsubst(1)` program that comes with the GNU gettext package. It's
 used internally by linkgit:git-sh-i18n[1] to interpolate the variables
-passed to the the `eval_gettext` function.
+passed to the `eval_gettext` function.
 
 No promises are made about the interface, or that this
 program won't disappear without warning in the next version
index b72964947afcc39af3b97c5b9eeb1969b44e0d05..c243ee552bb4bc715b8903163b0136b32097af04 100644 (file)
@@ -190,7 +190,7 @@ commit for each submodule.
 sync::
        Synchronizes submodules' remote URL configuration setting
        to the value specified in .gitmodules. It will only affect those
-       submodules which already have an url entry in .git/config (that is the
+       submodules which already have a URL entry in .git/config (that is the
        case when they are initialized or freshly added). This is useful when
        submodule URLs change upstream and you need to update your local
        repositories accordingly.
index d5b7667c15ef45e371b3fd3c4ecdf513f8f7cc02..ca85d1d210dc6015fef205e543f34b6f25733fca 100644 (file)
@@ -44,18 +44,26 @@ unreleased) version of git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v1.7.9.4/git.html[documentation for release 1.7.9.4]
+* link:v1.7.10/git.html[documentation for release 1.7.10]
 
 * release notes for
+  link:RelNotes/1.7.10.txt[1.7.10].
+
+* link:v1.7.9.6/git.html[documentation for release 1.7.9.6]
+
+* release notes for
+  link:RelNotes/1.7.9.6.txt[1.7.9.6],
+  link:RelNotes/1.7.9.5.txt[1.7.9.5],
   link:RelNotes/1.7.9.4.txt[1.7.9.4],
   link:RelNotes/1.7.9.3.txt[1.7.9.3],
   link:RelNotes/1.7.9.2.txt[1.7.9.2],
   link:RelNotes/1.7.9.1.txt[1.7.9.1],
   link:RelNotes/1.7.9.txt[1.7.9].
 
-* link:v1.7.8.4/git.html[documentation for release 1.7.8.4]
+* link:v1.7.8.5/git.html[documentation for release 1.7.8.5]
 
 * release notes for
+  link:RelNotes/1.7.8.5.txt[1.7.8.5],
   link:RelNotes/1.7.8.4.txt[1.7.8.4],
   link:RelNotes/1.7.8.3.txt[1.7.8.3],
   link:RelNotes/1.7.8.2.txt[1.7.8.2],
@@ -711,6 +719,12 @@ other
        a pager.  See also the `core.pager` option in
        linkgit:git-config[1].
 
+'GIT_EDITOR'::
+       This environment variable overrides `$EDITOR` and `$VISUAL`.
+       It is used by several git comands when, on interactive mode,
+       an editor is to be launched. See also linkgit:git-var[1]
+       and the `core.editor` option in linkgit:git-config[1].
+
 'GIT_SSH'::
        If this environment variable is set then 'git fetch'
        and 'git push' will use this command instead
index 4040941e55e88114b70d3d0ae7ecb644794fc8b3..4e1fd52e7d230c8f5e55960e960a68ef5875fe76 100644 (file)
@@ -28,7 +28,7 @@ submodule.<name>.path::
        be unique within the .gitmodules file.
 
 submodule.<name>.url::
-       Defines an url from where the submodule repository can be cloned.
+       Defines a URL from which the submodule repository can be cloned.
        This may be either an absolute URL ready to be passed to
        linkgit:git-clone[1] or (if it begins with ./ or ../) a location
        relative to the superproject's origin repository.
@@ -84,7 +84,7 @@ Consider the following .gitmodules file:
 
 This defines two submodules, `libfoo` and `libbar`. These are expected to
 be checked out in the paths 'include/foo' and 'include/bar', and for both
-submodules an url is specified which can be used for cloning the submodules.
+submodules a URL is specified which can be used for cloning the submodules.
 
 SEE ALSO
 --------
index 605a085326022dec46cf15c0c4e4f435a1bd12bd..168e8bfed644c5f22bfb5e45801884128e306e4a 100644 (file)
@@ -14,7 +14,7 @@ gitweb.
 
 DESCRIPTION
 -----------
-Gitweb provides a web interface to git repositories.  It's features include:
+Gitweb provides a web interface to git repositories.  Its features include:
 
 * Viewing multiple Git repositories with common root.
 * Browsing every revision of the repository.
@@ -60,7 +60,7 @@ to gitweb.  The list of projects is generated by default by scanning the
 more exact; gitweb is not interested in a working area, and is best suited
 to showing "bare" repositories).
 
-The name of repository in gitweb is path to it's `$GIT_DIR` (it's object
+The name of the repository in gitweb is the path to its `$GIT_DIR` (its object
 database) relative to `$projectroot`.  Therefore the repository $repo can be
 found at "$projectroot/$repo".
 
index 2933056120bf0a0d6249c6951ab1e964ae40674b..1ae8d1214ec0e8db1979a7770cf7602403358636 100644 (file)
@@ -25,7 +25,7 @@ What you want is the 'subtree' merge strategy, which helps you in such a
 situation.
 
 In this example, let's say you have the repository at `/path/to/B` (but
-it can be an URL as well, if you want). You want to merge the 'master'
+it can be a URL as well, if you want). You want to merge the 'master'
 branch of that repository to the `dir-B` subdirectory in your current
 branch.
 
index ce24eb96f5efdee579f8600323731368fee4048b..5a0c14fcebfcf4d5cbad4900d062703412c501e1 100644 (file)
@@ -83,7 +83,9 @@ Functions
 
        Insert a new element to the string_list. The returned pointer can be
        handy if you want to write something to the `util` pointer of the
-       string_list_item containing the just added string.
+       string_list_item containing the just added string. If the given
+       string already exists the insertion will be skipped and the
+       pointer to the existing item returned.
 +
 Since this function uses xrealloc() (which die()s if it fails) if the
 list needs to grow, it is safe not to check the pointer. I.e. you may
index 1c06cec047aec084453954b87718fbd4abf87c2b..b982e3329968366a214041cd57de8d4dbdd03c5e 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.10-rc1
+DEF_VER=v1.7.10.GIT
 
 LF='
 '
index 2c2a16955519b3c314ebdb3d2f0c08d544666ca1..bcb4fb98ff925389797125283e40c6e397efc1fd 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/1.7.10.txt
\ No newline at end of file
+Documentation/RelNotes/1.7.11.txt
\ No newline at end of file
diff --git a/attr.h b/attr.h
index eb8ca0d7c067417a8ff2802179e50bddcdff3367..8b08d33af84ebbb376a69d85f3db6c03eeb78a63 100644 (file)
--- a/attr.h
+++ b/attr.h
@@ -40,7 +40,7 @@ int git_check_attr(const char *path, int, struct git_attr_check *);
 
 /*
  * Retrieve all attributes that apply to the specified path.  *num
- * will be set the the number of attributes on the path; **check will
+ * will be set to the number of attributes on the path; **check will
  * be set to point at a newly-allocated array of git_attr_check
  * objects describing the attributes and their values.  *check must be
  * free()ed by the caller.
index 8ed501f220424976cc30f4a4dbf3d59f979902be..36a9104433e23422aab39b1912e998a7f54cd3f4 100644 (file)
@@ -11,6 +11,7 @@
 #include "parse-options.h"
 #include "diff.h"
 #include "userdiff.h"
+#include "streaming.h"
 
 #define BATCH 1
 #define BATCH_CHECK 2
@@ -127,6 +128,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
                        return cmd_ls_tree(2, ls_args, NULL);
                }
 
+               if (type == OBJ_BLOB)
+                       return stream_blob_to_fd(1, sha1, NULL, 0);
                buf = read_sha1_file(sha1, &type, &size);
                if (!buf)
                        die("Cannot read object %s", obj_name);
@@ -149,6 +152,28 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
                break;
 
        case 0:
+               if (type_from_string(exp_type) == OBJ_BLOB) {
+                       unsigned char blob_sha1[20];
+                       if (sha1_object_info(sha1, NULL) == OBJ_TAG) {
+                               enum object_type type;
+                               unsigned long size;
+                               char *buffer = read_sha1_file(sha1, &type, &size);
+                               if (memcmp(buffer, "object ", 7) ||
+                                   get_sha1_hex(buffer + 7, blob_sha1))
+                                       die("%s not a valid tag", sha1_to_hex(sha1));
+                               free(buffer);
+                       } else
+                               hashcpy(blob_sha1, sha1);
+
+                       if (sha1_object_info(blob_sha1, NULL) == OBJ_BLOB)
+                               return stream_blob_to_fd(1, blob_sha1, NULL, 0);
+                       /*
+                        * we attempted to dereference a tag to a blob
+                        * and failed; there may be new dereference
+                        * mechanisms this code is not aware of.
+                        * fall-back to the usual case.
+                        */
+               }
                buf = read_object_with_reference(sha1, exp_type, &size, NULL);
                break;
 
index 3714582e1988f7c286412afb779cbfefe4849657..7808be30e181e9cc4f031cdfea3b155f32970da8 100644 (file)
@@ -533,9 +533,20 @@ static int is_a_merge(const struct commit *current_head)
 
 static const char sign_off_header[] = "Signed-off-by: ";
 
+static void export_one(const char *var, const char *s, const char *e, int hack)
+{
+       struct strbuf buf = STRBUF_INIT;
+       if (hack)
+               strbuf_addch(&buf, hack);
+       strbuf_addf(&buf, "%.*s", (int)(e - s), s);
+       setenv(var, buf.buf, 1);
+       strbuf_release(&buf);
+}
+
 static void determine_author_info(struct strbuf *author_ident)
 {
        char *name, *email, *date;
+       struct ident_split author;
 
        name = getenv("GIT_AUTHOR_NAME");
        email = getenv("GIT_AUTHOR_EMAIL");
@@ -585,6 +596,11 @@ static void determine_author_info(struct strbuf *author_ident)
                date = force_date;
        strbuf_addstr(author_ident, fmt_ident(name, email, date,
                                              IDENT_ERROR_ON_NO_NAME));
+       if (!split_ident_line(&author, author_ident->buf, author_ident->len)) {
+               export_one("GIT_AUTHOR_NAME", author.name_begin, author.name_end, 0);
+               export_one("GIT_AUTHOR_EMAIL", author.mail_begin, author.mail_end, 0);
+               export_one("GIT_AUTHOR_DATE", author.date_begin, author.tz_end, '@');
+       }
 }
 
 static int ends_rfc2822_footer(struct strbuf *sb)
@@ -652,6 +668,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
        int ident_shown = 0;
        int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
 
+       /* This checks and barfs if author is badly specified */
+       determine_author_info(author_ident);
+
        if (!no_verify && run_hook(index_file, "pre-commit", NULL))
                return 0;
 
@@ -771,9 +790,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 
        strbuf_release(&sb);
 
-       /* This checks and barfs if author is badly specified */
-       determine_author_info(author_ident);
-
        /* This checks if committer ident is explicitly given */
        strbuf_addstr(&committer_ident, git_committer_info(0));
        if (use_editor && include_status) {
index d41a9bfb143c2bd82e539c3f390f17914c2e853a..33c8820af6fc73453b749ec6026077f76180e26c 100644 (file)
@@ -397,8 +397,6 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                                xstrdup(prefix_filename(prefix,
                                                        strlen(prefix),
                                                        given_config_file));
-               else
-                       given_config_file = given_config_file;
        }
 
        if (respect_includes == -1)
index 67eb553c7dc3d8ce62fbbefbe64a90c6431963c7..a710227a64a9862c0a70f3022f901fc65b0c7f90 100644 (file)
@@ -12,6 +12,7 @@
 #include "parse-options.h"
 #include "dir.h"
 #include "progress.h"
+#include "streaming.h"
 
 #define REACHABLE 0x0001
 #define SEEN      0x0002
@@ -238,13 +239,8 @@ static void check_unreachable_object(struct object *obj)
                        if (!(f = fopen(filename, "w")))
                                die_errno("Could not open '%s'", filename);
                        if (obj->type == OBJ_BLOB) {
-                               enum object_type type;
-                               unsigned long size;
-                               char *buf = read_sha1_file(obj->sha1,
-                                               &type, &size);
-                               if (buf && fwrite(buf, 1, size, f) != size)
+                               if (stream_blob_to_fd(fileno(f), obj->sha1, NULL, 1))
                                        die_errno("Could not write '%s'", filename);
-                               free(buf);
                        } else
                                fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
                        if (fclose(f))
index 8a47012b0bd2fefe616c44b918d16a18463b5d2a..690caa7830b2a4549012db5e46794118bc36e989 100644 (file)
@@ -20,6 +20,7 @@
 #include "string-list.h"
 #include "parse-options.h"
 #include "branch.h"
+#include "streaming.h"
 
 /* Set a default date-time format for git log ("log.date" config variable) */
 static const char *default_date_mode = NULL;
@@ -383,8 +384,13 @@ static void show_tagger(char *buf, int len, struct rev_info *rev)
        strbuf_release(&out);
 }
 
-static int show_object(const unsigned char *sha1, int show_tag_object,
-       struct rev_info *rev)
+static int show_blob_object(const unsigned char *sha1, struct rev_info *rev)
+{
+       fflush(stdout);
+       return stream_blob_to_fd(1, sha1, NULL, 0);
+}
+
+static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
 {
        unsigned long size;
        enum object_type type;
@@ -394,16 +400,16 @@ static int show_object(const unsigned char *sha1, int show_tag_object,
        if (!buf)
                return error(_("Could not read object %s"), sha1_to_hex(sha1));
 
-       if (show_tag_object)
-               while (offset < size && buf[offset] != '\n') {
-                       int new_offset = offset + 1;
-                       while (new_offset < size && buf[new_offset++] != '\n')
-                               ; /* do nothing */
-                       if (!prefixcmp(buf + offset, "tagger "))
-                               show_tagger(buf + offset + 7,
-                                           new_offset - offset - 7, rev);
-                       offset = new_offset;
-               }
+       assert(type == OBJ_TAG);
+       while (offset < size && buf[offset] != '\n') {
+               int new_offset = offset + 1;
+               while (new_offset < size && buf[new_offset++] != '\n')
+                       ; /* do nothing */
+               if (!prefixcmp(buf + offset, "tagger "))
+                       show_tagger(buf + offset + 7,
+                                   new_offset - offset - 7, rev);
+               offset = new_offset;
+       }
 
        if (offset < size)
                fwrite(buf + offset, size - offset, 1, stdout);
@@ -463,7 +469,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
                const char *name = objects[i].name;
                switch (o->type) {
                case OBJ_BLOB:
-                       ret = show_object(o->sha1, 0, NULL);
+                       ret = show_blob_object(o->sha1, NULL);
                        break;
                case OBJ_TAG: {
                        struct tag *t = (struct tag *)o;
@@ -474,7 +480,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
                                        diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
                                        t->tag,
                                        diff_get_color_opt(&rev.diffopt, DIFF_RESET));
-                       ret = show_object(o->sha1, 1, &rev);
+                       ret = show_tag_object(o->sha1, &rev);
                        rev.shown_one = 1;
                        if (ret)
                                break;
index cb8f14910b93edb7f1bfa6a4ee82f6a3d9fd7e40..08e01e8a60d7d7f9c60e9e7a3a2f8b4d66c12ce3 100644 (file)
@@ -1325,11 +1325,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                if (!fast_forward_only &&
                    merge_remote_util(commit) &&
                    merge_remote_util(commit)->obj &&
-                   merge_remote_util(commit)->obj->type == OBJ_TAG) {
-                       if (option_edit < 0)
-                               option_edit = 1;
+                   merge_remote_util(commit)->obj->type == OBJ_TAG)
                        allow_fast_forward = 0;
-               }
        }
 
        if (option_edit < 0)
index b90dce6358153b274a1e26afde9cc89aad473d14..0d63c4498c0c10193846c020a2d76958bd12e1bd 100644 (file)
@@ -15,6 +15,7 @@ int cmd_update_server_info(int argc, const char **argv, const char *prefix)
                OPT_END()
        };
 
+       git_config(git_default_config, NULL);
        argc = parse_options(argc, argv, prefix, options,
                             update_server_info_usage, 0);
        if (argc > 0)
diff --git a/cache.h b/cache.h
index e5e1aa4e15a336927376c63651d88d63f02c44bf..a8aceb5aee4fef0d7b06693921dea319690965d6 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -928,6 +928,22 @@ extern const char *fmt_name(const char *name, const char *email);
 extern const char *git_editor(void);
 extern const char *git_pager(int stdout_is_tty);
 
+struct ident_split {
+       const char *name_begin;
+       const char *name_end;
+       const char *mail_begin;
+       const char *mail_end;
+       const char *date_begin;
+       const char *date_end;
+       const char *tz_begin;
+       const char *tz_end;
+};
+/*
+ * Signals an success with 0, but time part of the result may be NULL
+ * if the input lacks timestamp and zone
+ */
+extern int split_ident_line(struct ident_split *, const char *, int);
+
 struct checkout {
        const char *base_dir;
        int base_dir_len;
index fba076dde27440eaa90fd4fcfdfa55764410dd11..31f714da927511fb5b2b7ac11dd7af1e3f98ae76 100755 (executable)
@@ -94,9 +94,10 @@ __gitdir ()
 __git_ps1_show_upstream ()
 {
        local key value
-       local svn_remote=() svn_url_pattern count n
+       local svn_remote svn_url_pattern count n
        local upstream=git legacy="" verbose=""
 
+       svn_remote=()
        # get some config options from git-config
        local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')"
        while read -r key value; do
diff --git a/contrib/subtree/.gitignore b/contrib/subtree/.gitignore
new file mode 100644 (file)
index 0000000..7e77c9d
--- /dev/null
@@ -0,0 +1,5 @@
+*~
+git-subtree.xml
+git-subtree.1
+mainline
+subproj
diff --git a/contrib/subtree/COPYING b/contrib/subtree/COPYING
new file mode 100644 (file)
index 0000000..d511905
--- /dev/null
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/contrib/subtree/INSTALL b/contrib/subtree/INSTALL
new file mode 100644 (file)
index 0000000..7ab0cf4
--- /dev/null
@@ -0,0 +1,28 @@
+HOW TO INSTALL git-subtree
+==========================
+
+First, build from the top source directory.
+
+Then, in contrib/subtree, run:
+
+  make
+  make install
+  make install-doc
+
+If you used configure to do the main build the git-subtree build will
+pick up those settings.  If not, you will likely have to provide a
+value for prefix:
+
+  make prefix=<some dir>
+  make prefix=<some dir> install
+  make prefix=<some dir> install-doc
+
+To run tests first copy git-subtree to the main build area so the
+newly-built git can find it:
+
+  cp git-subtree ../..
+
+Then:
+
+  make test
+
diff --git a/contrib/subtree/Makefile b/contrib/subtree/Makefile
new file mode 100644 (file)
index 0000000..05cdd5c
--- /dev/null
@@ -0,0 +1,52 @@
+-include ../../config.mak.autogen
+-include ../../config.mak
+
+prefix ?= /usr/local
+mandir ?= $(prefix)/share/man
+libexecdir ?= $(prefix)/libexec/git-core
+gitdir ?= $(shell git --exec-path)
+man1dir ?= $(mandir)/man1
+
+gitver ?= $(word 3,$(shell git --version))
+
+# this should be set to a 'standard' bsd-type install program
+INSTALL ?= install
+
+ASCIIDOC_CONF      = ../../Documentation/asciidoc.conf
+MANPAGE_NORMAL_XSL =  ../../Documentation/manpage-normal.xsl
+
+GIT_SUBTREE_SH := git-subtree.sh
+GIT_SUBTREE    := git-subtree
+
+GIT_SUBTREE_DOC := git-subtree.1
+GIT_SUBTREE_XML := git-subtree.xml
+GIT_SUBTREE_TXT := git-subtree.txt
+
+all: $(GIT_SUBTREE)
+
+$(GIT_SUBTREE): $(GIT_SUBTREE_SH)
+       cp $< $@ && chmod +x $@
+
+doc: $(GIT_SUBTREE_DOC)
+
+install: $(GIT_SUBTREE)
+       $(INSTALL) -m 755 $(GIT_SUBTREE) $(libexecdir)
+
+install-doc: install-man
+
+install-man: $(GIT_SUBTREE_DOC)
+       $(INSTALL) -m 644 $^ $(man1dir)
+
+$(GIT_SUBTREE_DOC): $(GIT_SUBTREE_XML)
+       xmlto -m $(MANPAGE_NORMAL_XSL)  man $^
+
+$(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT)
+       asciidoc -b docbook -d manpage -f $(ASCIIDOC_CONF) \
+               -agit_version=$(gitver) $^
+
+test:
+       $(MAKE) -C t/ test
+
+clean:
+       rm -f *~ *.xml *.html *.1
+       rm -rf subproj mainline
diff --git a/contrib/subtree/README b/contrib/subtree/README
new file mode 100644 (file)
index 0000000..c686b4a
--- /dev/null
@@ -0,0 +1,8 @@
+
+Please read git-subtree.txt for documentation.
+
+Please don't contact me using github mail; it's slow, ugly, and worst of
+all, redundant. Email me instead at apenwarr@gmail.com and I'll be happy to
+help.
+
+Avery
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
new file mode 100755 (executable)
index 0000000..920c664
--- /dev/null
@@ -0,0 +1,712 @@
+#!/bin/bash
+#
+# git-subtree.sh: split/join git repositories in subdirectories of this one
+#
+# Copyright (C) 2009 Avery Pennarun <apenwarr@gmail.com>
+#
+if [ $# -eq 0 ]; then
+    set -- -h
+fi
+OPTS_SPEC="\
+git subtree add   --prefix=<prefix> <commit>
+git subtree merge --prefix=<prefix> <commit>
+git subtree pull  --prefix=<prefix> <repository> <refspec...>
+git subtree push  --prefix=<prefix> <repository> <refspec...>
+git subtree split --prefix=<prefix> <commit...>
+--
+h,help        show the help
+q             quiet
+d             show debug messages
+P,prefix=     the name of the subdir to split out
+m,message=    use the given message as the commit message for the merge commit
+ options for 'split'
+annotate=     add a prefix to commit message of new commits
+b,branch=     create a new branch from the split subtree
+ignore-joins  ignore prior --rejoin commits
+onto=         try connecting new tree to an existing one
+rejoin        merge the new branch back into HEAD
+ options for 'add', 'merge', 'pull' and 'push'
+squash        merge subtree changes as a single commit
+"
+eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
+
+PATH=$PATH:$(git --exec-path)
+. git-sh-setup
+
+require_work_tree
+
+quiet=
+branch=
+debug=
+command=
+onto=
+rejoin=
+ignore_joins=
+annotate=
+squash=
+message=
+
+debug()
+{
+       if [ -n "$debug" ]; then
+               echo "$@" >&2
+       fi
+}
+
+say()
+{
+       if [ -z "$quiet" ]; then
+               echo "$@" >&2
+       fi
+}
+
+assert()
+{
+       if "$@"; then
+               :
+       else
+               die "assertion failed: " "$@"
+       fi
+}
+
+
+#echo "Options: $*"
+
+while [ $# -gt 0 ]; do
+       opt="$1"
+       shift
+       case "$opt" in
+               -q) quiet=1 ;;
+               -d) debug=1 ;;
+               --annotate) annotate="$1"; shift ;;
+               --no-annotate) annotate= ;;
+               -b) branch="$1"; shift ;;
+               -P) prefix="$1"; shift ;;
+               -m) message="$1"; shift ;;
+               --no-prefix) prefix= ;;
+               --onto) onto="$1"; shift ;;
+               --no-onto) onto= ;;
+               --rejoin) rejoin=1 ;;
+               --no-rejoin) rejoin= ;;
+               --ignore-joins) ignore_joins=1 ;;
+               --no-ignore-joins) ignore_joins= ;;
+               --squash) squash=1 ;;
+               --no-squash) squash= ;;
+               --) break ;;
+               *) die "Unexpected option: $opt" ;;
+       esac
+done
+
+command="$1"
+shift
+case "$command" in
+       add|merge|pull) default= ;;
+       split|push) default="--default HEAD" ;;
+       *) die "Unknown command '$command'" ;;
+esac
+
+if [ -z "$prefix" ]; then
+       die "You must provide the --prefix option."
+fi
+
+case "$command" in
+       add) [ -e "$prefix" ] && 
+               die "prefix '$prefix' already exists." ;;
+       *)   [ -e "$prefix" ] || 
+               die "'$prefix' does not exist; use 'git subtree add'" ;;
+esac
+
+dir="$(dirname "$prefix/.")"
+
+if [ "$command" != "pull" -a "$command" != "add" -a "$command" != "push" ]; then
+       revs=$(git rev-parse $default --revs-only "$@") || exit $?
+       dirs="$(git rev-parse --no-revs --no-flags "$@")" || exit $?
+       if [ -n "$dirs" ]; then
+               die "Error: Use --prefix instead of bare filenames."
+       fi
+fi
+
+debug "command: {$command}"
+debug "quiet: {$quiet}"
+debug "revs: {$revs}"
+debug "dir: {$dir}"
+debug "opts: {$*}"
+debug
+
+cache_setup()
+{
+       cachedir="$GIT_DIR/subtree-cache/$$"
+       rm -rf "$cachedir" || die "Can't delete old cachedir: $cachedir"
+       mkdir -p "$cachedir" || die "Can't create new cachedir: $cachedir"
+       mkdir -p "$cachedir/notree" || die "Can't create new cachedir: $cachedir/notree"
+       debug "Using cachedir: $cachedir" >&2
+}
+
+cache_get()
+{
+       for oldrev in $*; do
+               if [ -r "$cachedir/$oldrev" ]; then
+                       read newrev <"$cachedir/$oldrev"
+                       echo $newrev
+               fi
+       done
+}
+
+cache_miss()
+{
+       for oldrev in $*; do
+               if [ ! -r "$cachedir/$oldrev" ]; then
+                       echo $oldrev
+               fi
+       done
+}
+
+check_parents()
+{
+       missed=$(cache_miss $*)
+       for miss in $missed; do
+               if [ ! -r "$cachedir/notree/$miss" ]; then
+                       debug "  incorrect order: $miss"
+               fi
+       done
+}
+
+set_notree()
+{
+       echo "1" > "$cachedir/notree/$1"
+}
+
+cache_set()
+{
+       oldrev="$1"
+       newrev="$2"
+       if [ "$oldrev" != "latest_old" \
+            -a "$oldrev" != "latest_new" \
+            -a -e "$cachedir/$oldrev" ]; then
+               die "cache for $oldrev already exists!"
+       fi
+       echo "$newrev" >"$cachedir/$oldrev"
+}
+
+rev_exists()
+{
+       if git rev-parse "$1" >/dev/null 2>&1; then
+               return 0
+       else
+               return 1
+       fi
+}
+
+rev_is_descendant_of_branch()
+{
+       newrev="$1"
+       branch="$2"
+       branch_hash=$(git rev-parse $branch)
+       match=$(git rev-list -1 $branch_hash ^$newrev)
+
+       if [ -z "$match" ]; then
+               return 0
+       else
+               return 1
+       fi
+}
+
+# if a commit doesn't have a parent, this might not work.  But we only want
+# to remove the parent from the rev-list, and since it doesn't exist, it won't
+# be there anyway, so do nothing in that case.
+try_remove_previous()
+{
+       if rev_exists "$1^"; then
+               echo "^$1^"
+       fi
+}
+
+find_latest_squash()
+{
+       debug "Looking for latest squash ($dir)..."
+       dir="$1"
+       sq=
+       main=
+       sub=
+       git log --grep="^git-subtree-dir: $dir/*\$" \
+               --pretty=format:'START %H%n%s%n%n%b%nEND%n' HEAD |
+       while read a b junk; do
+               debug "$a $b $junk"
+               debug "{{$sq/$main/$sub}}"
+               case "$a" in
+                       START) sq="$b" ;;
+                       git-subtree-mainline:) main="$b" ;;
+                       git-subtree-split:) sub="$b" ;;
+                       END)
+                               if [ -n "$sub" ]; then
+                                       if [ -n "$main" ]; then
+                                               # a rejoin commit?
+                                               # Pretend its sub was a squash.
+                                               sq="$sub"
+                                       fi
+                                       debug "Squash found: $sq $sub"
+                                       echo "$sq" "$sub"
+                                       break
+                               fi
+                               sq=
+                               main=
+                               sub=
+                               ;;
+               esac
+       done
+}
+
+find_existing_splits()
+{
+       debug "Looking for prior splits..."
+       dir="$1"
+       revs="$2"
+       main=
+       sub=
+       git log --grep="^git-subtree-dir: $dir/*\$" \
+               --pretty=format:'START %H%n%s%n%n%b%nEND%n' $revs |
+       while read a b junk; do
+               case "$a" in
+                       START) sq="$b" ;;
+                       git-subtree-mainline:) main="$b" ;;
+                       git-subtree-split:) sub="$b" ;;
+                       END)
+                               debug "  Main is: '$main'"
+                               if [ -z "$main" -a -n "$sub" ]; then
+                                       # squash commits refer to a subtree
+                                       debug "  Squash: $sq from $sub"
+                                       cache_set "$sq" "$sub"
+                               fi
+                               if [ -n "$main" -a -n "$sub" ]; then
+                                       debug "  Prior: $main -> $sub"
+                                       cache_set $main $sub
+                                       cache_set $sub $sub
+                                       try_remove_previous "$main"
+                                       try_remove_previous "$sub"
+                               fi
+                               main=
+                               sub=
+                               ;;
+               esac
+       done
+}
+
+copy_commit()
+{
+       # We're going to set some environment vars here, so
+       # do it in a subshell to get rid of them safely later
+       debug copy_commit "{$1}" "{$2}" "{$3}"
+       git log -1 --pretty=format:'%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b' "$1" |
+       (
+               read GIT_AUTHOR_NAME
+               read GIT_AUTHOR_EMAIL
+               read GIT_AUTHOR_DATE
+               read GIT_COMMITTER_NAME
+               read GIT_COMMITTER_EMAIL
+               read GIT_COMMITTER_DATE
+               export  GIT_AUTHOR_NAME \
+                       GIT_AUTHOR_EMAIL \
+                       GIT_AUTHOR_DATE \
+                       GIT_COMMITTER_NAME \
+                       GIT_COMMITTER_EMAIL \
+                       GIT_COMMITTER_DATE
+               (echo -n "$annotate"; cat ) |
+               git commit-tree "$2" $3  # reads the rest of stdin
+       ) || die "Can't copy commit $1"
+}
+
+add_msg()
+{
+       dir="$1"
+       latest_old="$2"
+       latest_new="$3"
+       if [ -n "$message" ]; then
+               commit_message="$message"
+       else
+               commit_message="Add '$dir/' from commit '$latest_new'"
+       fi
+       cat <<-EOF
+               $commit_message
+               
+               git-subtree-dir: $dir
+               git-subtree-mainline: $latest_old
+               git-subtree-split: $latest_new
+       EOF
+}
+
+add_squashed_msg()
+{
+       if [ -n "$message" ]; then
+               echo "$message"
+       else
+               echo "Merge commit '$1' as '$2'"
+       fi
+}
+
+rejoin_msg()
+{
+       dir="$1"
+       latest_old="$2"
+       latest_new="$3"
+       if [ -n "$message" ]; then
+               commit_message="$message"
+       else
+               commit_message="Split '$dir/' into commit '$latest_new'"
+       fi
+       cat <<-EOF
+               $commit_message
+               
+               git-subtree-dir: $dir
+               git-subtree-mainline: $latest_old
+               git-subtree-split: $latest_new
+       EOF
+}
+
+squash_msg()
+{
+       dir="$1"
+       oldsub="$2"
+       newsub="$3"
+       newsub_short=$(git rev-parse --short "$newsub")
+       
+       if [ -n "$oldsub" ]; then
+               oldsub_short=$(git rev-parse --short "$oldsub")
+               echo "Squashed '$dir/' changes from $oldsub_short..$newsub_short"
+               echo
+               git log --pretty=tformat:'%h %s' "$oldsub..$newsub"
+               git log --pretty=tformat:'REVERT: %h %s' "$newsub..$oldsub"
+       else
+               echo "Squashed '$dir/' content from commit $newsub_short"
+       fi
+       
+       echo
+       echo "git-subtree-dir: $dir"
+       echo "git-subtree-split: $newsub"
+}
+
+toptree_for_commit()
+{
+       commit="$1"
+       git log -1 --pretty=format:'%T' "$commit" -- || exit $?
+}
+
+subtree_for_commit()
+{
+       commit="$1"
+       dir="$2"
+       git ls-tree "$commit" -- "$dir" |
+       while read mode type tree name; do
+               assert [ "$name" = "$dir" ]
+               assert [ "$type" = "tree" -o "$type" = "commit" ]
+               [ "$type" = "commit" ] && continue  # ignore submodules
+               echo $tree
+               break
+       done
+}
+
+tree_changed()
+{
+       tree=$1
+       shift
+       if [ $# -ne 1 ]; then
+               return 0   # weird parents, consider it changed
+       else
+               ptree=$(toptree_for_commit $1)
+               if [ "$ptree" != "$tree" ]; then
+                       return 0   # changed
+               else
+                       return 1   # not changed
+               fi
+       fi
+}
+
+new_squash_commit()
+{
+       old="$1"
+       oldsub="$2"
+       newsub="$3"
+       tree=$(toptree_for_commit $newsub) || exit $?
+       if [ -n "$old" ]; then
+               squash_msg "$dir" "$oldsub" "$newsub" | 
+                       git commit-tree "$tree" -p "$old" || exit $?
+       else
+               squash_msg "$dir" "" "$newsub" |
+                       git commit-tree "$tree" || exit $?
+       fi
+}
+
+copy_or_skip()
+{
+       rev="$1"
+       tree="$2"
+       newparents="$3"
+       assert [ -n "$tree" ]
+
+       identical=
+       nonidentical=
+       p=
+       gotparents=
+       for parent in $newparents; do
+               ptree=$(toptree_for_commit $parent) || exit $?
+               [ -z "$ptree" ] && continue
+               if [ "$ptree" = "$tree" ]; then
+                       # an identical parent could be used in place of this rev.
+                       identical="$parent"
+               else
+                       nonidentical="$parent"
+               fi
+               
+               # sometimes both old parents map to the same newparent;
+               # eliminate duplicates
+               is_new=1
+               for gp in $gotparents; do
+                       if [ "$gp" = "$parent" ]; then
+                               is_new=
+                               break
+                       fi
+               done
+               if [ -n "$is_new" ]; then
+                       gotparents="$gotparents $parent"
+                       p="$p -p $parent"
+               fi
+       done
+       
+       if [ -n "$identical" ]; then
+               echo $identical
+       else
+               copy_commit $rev $tree "$p" || exit $?
+       fi
+}
+
+ensure_clean()
+{
+       if ! git diff-index HEAD --exit-code --quiet 2>&1; then
+               die "Working tree has modifications.  Cannot add."
+       fi
+       if ! git diff-index --cached HEAD --exit-code --quiet 2>&1; then
+               die "Index has modifications.  Cannot add."
+       fi
+}
+
+cmd_add()
+{
+       if [ -e "$dir" ]; then
+               die "'$dir' already exists.  Cannot add."
+       fi
+
+       ensure_clean
+       
+       if [ $# -eq 1 ]; then
+               "cmd_add_commit" "$@"
+       elif [ $# -eq 2 ]; then
+               "cmd_add_repository" "$@"
+       else
+           say "error: parameters were '$@'"
+           die "Provide either a refspec or a repository and refspec."
+       fi
+}
+
+cmd_add_repository()
+{
+       echo "git fetch" "$@"
+       repository=$1
+       refspec=$2
+       git fetch "$@" || exit $?
+       revs=FETCH_HEAD
+       set -- $revs
+       cmd_add_commit "$@"
+}
+
+cmd_add_commit()
+{
+       revs=$(git rev-parse $default --revs-only "$@") || exit $?
+       set -- $revs
+       rev="$1"
+       
+       debug "Adding $dir as '$rev'..."
+       git read-tree --prefix="$dir" $rev || exit $?
+       git checkout -- "$dir" || exit $?
+       tree=$(git write-tree) || exit $?
+       
+       headrev=$(git rev-parse HEAD) || exit $?
+       if [ -n "$headrev" -a "$headrev" != "$rev" ]; then
+               headp="-p $headrev"
+       else
+               headp=
+       fi
+       
+       if [ -n "$squash" ]; then
+               rev=$(new_squash_commit "" "" "$rev") || exit $?
+               commit=$(add_squashed_msg "$rev" "$dir" |
+                        git commit-tree $tree $headp -p "$rev") || exit $?
+       else
+               commit=$(add_msg "$dir" "$headrev" "$rev" |
+                        git commit-tree $tree $headp -p "$rev") || exit $?
+       fi
+       git reset "$commit" || exit $?
+       
+       say "Added dir '$dir'"
+}
+
+cmd_split()
+{
+       debug "Splitting $dir..."
+       cache_setup || exit $?
+       
+       if [ -n "$onto" ]; then
+               debug "Reading history for --onto=$onto..."
+               git rev-list $onto |
+               while read rev; do
+                       # the 'onto' history is already just the subdir, so
+                       # any parent we find there can be used verbatim
+                       debug "  cache: $rev"
+                       cache_set $rev $rev
+               done
+       fi
+       
+       if [ -n "$ignore_joins" ]; then
+               unrevs=
+       else
+               unrevs="$(find_existing_splits "$dir" "$revs")"
+       fi
+       
+       # We can't restrict rev-list to only $dir here, because some of our
+       # parents have the $dir contents the root, and those won't match.
+       # (and rev-list --follow doesn't seem to solve this)
+       grl='git rev-list --topo-order --reverse --parents $revs $unrevs'
+       revmax=$(eval "$grl" | wc -l)
+       revcount=0
+       createcount=0
+       eval "$grl" |
+       while read rev parents; do
+               revcount=$(($revcount + 1))
+               say -n "$revcount/$revmax ($createcount)\r"
+               debug "Processing commit: $rev"
+               exists=$(cache_get $rev)
+               if [ -n "$exists" ]; then
+                       debug "  prior: $exists"
+                       continue
+               fi
+               createcount=$(($createcount + 1))
+               debug "  parents: $parents"
+               newparents=$(cache_get $parents)
+               debug "  newparents: $newparents"
+               
+               tree=$(subtree_for_commit $rev "$dir")
+               debug "  tree is: $tree"
+
+               check_parents $parents
+               
+               # ugly.  is there no better way to tell if this is a subtree
+               # vs. a mainline commit?  Does it matter?
+               if [ -z $tree ]; then
+                       set_notree $rev
+                       if [ -n "$newparents" ]; then
+                               cache_set $rev $rev
+                       fi
+                       continue
+               fi
+
+               newrev=$(copy_or_skip "$rev" "$tree" "$newparents") || exit $?
+               debug "  newrev is: $newrev"
+               cache_set $rev $newrev
+               cache_set latest_new $newrev
+               cache_set latest_old $rev
+       done || exit $?
+       latest_new=$(cache_get latest_new)
+       if [ -z "$latest_new" ]; then
+               die "No new revisions were found"
+       fi
+       
+       if [ -n "$rejoin" ]; then
+               debug "Merging split branch into HEAD..."
+               latest_old=$(cache_get latest_old)
+               git merge -s ours \
+                       -m "$(rejoin_msg $dir $latest_old $latest_new)" \
+                       $latest_new >&2 || exit $?
+       fi
+       if [ -n "$branch" ]; then
+               if rev_exists "refs/heads/$branch"; then
+                       if ! rev_is_descendant_of_branch $latest_new $branch; then
+                               die "Branch '$branch' is not an ancestor of commit '$latest_new'."
+                       fi
+                       action='Updated'
+               else
+                       action='Created'
+               fi
+               git update-ref -m 'subtree split' "refs/heads/$branch" $latest_new || exit $?
+               say "$action branch '$branch'"
+       fi
+       echo $latest_new
+       exit 0
+}
+
+cmd_merge()
+{
+       revs=$(git rev-parse $default --revs-only "$@") || exit $?
+       ensure_clean
+       
+       set -- $revs
+       if [ $# -ne 1 ]; then
+               die "You must provide exactly one revision.  Got: '$revs'"
+       fi
+       rev="$1"
+       
+       if [ -n "$squash" ]; then
+               first_split="$(find_latest_squash "$dir")"
+               if [ -z "$first_split" ]; then
+                       die "Can't squash-merge: '$dir' was never added."
+               fi
+               set $first_split
+               old=$1
+               sub=$2
+               if [ "$sub" = "$rev" ]; then
+                       say "Subtree is already at commit $rev."
+                       exit 0
+               fi
+               new=$(new_squash_commit "$old" "$sub" "$rev") || exit $?
+               debug "New squash commit: $new"
+               rev="$new"
+       fi
+
+       version=$(git version)
+       if [ "$version" \< "git version 1.7" ]; then
+               if [ -n "$message" ]; then
+                       git merge -s subtree --message="$message" $rev
+               else
+                       git merge -s subtree $rev
+               fi
+       else
+               if [ -n "$message" ]; then
+                       git merge -Xsubtree="$prefix" --message="$message" $rev
+               else
+                       git merge -Xsubtree="$prefix" $rev
+               fi
+       fi
+}
+
+cmd_pull()
+{
+       ensure_clean
+       git fetch "$@" || exit $?
+       revs=FETCH_HEAD
+       set -- $revs
+       cmd_merge "$@"
+}
+
+cmd_push()
+{
+       if [ $# -ne 2 ]; then
+           die "You must provide <repository> <refspec>"
+       fi
+       if [ -e "$dir" ]; then
+           repository=$1
+           refspec=$2
+           echo "git push using: " $repository $refspec
+           git push $repository $(git subtree split --prefix=$prefix):refs/heads/$refspec
+       else
+           die "'$dir' must already exist. Try 'git subtree add'."
+       fi
+}
+
+"cmd_$command" "$@"
diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
new file mode 100644 (file)
index 0000000..0c44fda
--- /dev/null
@@ -0,0 +1,366 @@
+git-subtree(1)
+==============
+
+NAME
+----
+git-subtree - Merge subtrees together and split repository into subtrees
+
+
+SYNOPSIS
+--------
+[verse]
+'git subtree' add   -P <prefix> <commit>
+'git subtree' pull  -P <prefix> <repository> <refspec...>
+'git subtree' push  -P <prefix> <repository> <refspec...>
+'git subtree' merge -P <prefix> <commit>
+'git subtree' split -P <prefix> [OPTIONS] [<commit>]
+
+
+DESCRIPTION
+-----------
+Subtrees allow subprojects to be included within a subdirectory
+of the main project, optionally including the subproject's
+entire history.
+
+For example, you could include the source code for a library
+as a subdirectory of your application.
+
+Subtrees are not to be confused with submodules, which are meant for
+the same task. Unlike submodules, subtrees do not need any special
+constructions (like .gitmodule files or gitlinks) be present in
+your repository, and do not force end-users of your
+repository to do anything special or to understand how subtrees
+work. A subtree is just a subdirectory that can be
+committed to, branched, and merged along with your project in
+any way you want.
+
+They are also not to be confused with using the subtree merge
+strategy. The main difference is that, besides merging
+the other project as a subdirectory, you can also extract the
+entire history of a subdirectory from your project and make it
+into a standalone project. Unlike the subtree merge strategy
+you can alternate back and forth between these
+two operations. If the standalone library gets updated, you can
+automatically merge the changes into your project; if you
+update the library inside your project, you can "split" the
+changes back out again and merge them back into the library
+project.
+
+For example, if a library you made for one application ends up being
+useful elsewhere, you can extract its entire history and publish
+that as its own git repository, without accidentally
+intermingling the history of your application project.
+
+[TIP]
+In order to keep your commit messages clean, we recommend that
+people split their commits between the subtrees and the main
+project as much as possible.  That is, if you make a change that
+affects both the library and the main application, commit it in
+two pieces.  That way, when you split the library commits out
+later, their descriptions will still make sense.  But if this
+isn't important to you, it's not *necessary*.  git subtree will
+simply leave out the non-library-related parts of the commit
+when it splits it out into the subproject later.
+
+
+COMMANDS
+--------
+add::
+       Create the <prefix> subtree by importing its contents
+       from the given <refspec> or <repository> and remote <refspec>.
+       A new commit is created automatically, joining the imported
+       project's history with your own.  With '--squash', imports
+       only a single commit from the subproject, rather than its
+       entire history.
+
+merge::
+       Merge recent changes up to <commit> into the <prefix>
+       subtree.  As with normal 'git merge', this doesn't
+       remove your own local changes; it just merges those
+       changes into the latest <commit>.  With '--squash',
+       creates only one commit that contains all the changes,
+       rather than merging in the entire history.
+
+       If you use '--squash', the merge direction doesn't
+       always have to be forward; you can use this command to
+       go back in time from v2.5 to v2.4, for example.  If your
+       merge introduces a conflict, you can resolve it in the
+       usual ways.
+       
+pull::
+       Exactly like 'merge', but parallels 'git pull' in that
+       it fetches the given commit from the specified remote
+       repository.
+       
+push::
+       Does a 'split' (see above) using the <prefix> supplied
+       and then does a 'git push' to push the result to the 
+       repository and refspec. This can be used to push your
+       subtree to different branches of the remote repository.
+
+split::
+       Extract a new, synthetic project history from the
+       history of the <prefix> subtree.  The new history
+       includes only the commits (including merges) that
+       affected <prefix>, and each of those commits now has the
+       contents of <prefix> at the root of the project instead
+       of in a subdirectory.  Thus, the newly created history
+       is suitable for export as a separate git repository.
+       
+       After splitting successfully, a single commit id is
+       printed to stdout.  This corresponds to the HEAD of the
+       newly created tree, which you can manipulate however you
+       want.
+       
+       Repeated splits of exactly the same history are
+       guaranteed to be identical (ie. to produce the same
+       commit ids).  Because of this, if you add new commits
+       and then re-split, the new commits will be attached as
+       commits on top of the history you generated last time,
+       so 'git merge' and friends will work as expected.
+       
+       Note that if you use '--squash' when you merge, you
+       should usually not just '--rejoin' when you split.
+
+
+OPTIONS
+-------
+-q::
+--quiet::
+       Suppress unnecessary output messages on stderr.
+
+-d::
+--debug::
+       Produce even more unnecessary output messages on stderr.
+
+-P <prefix>::
+--prefix=<prefix>::
+       Specify the path in the repository to the subtree you
+       want to manipulate.  This option is mandatory
+       for all commands.
+
+-m <message>::
+--message=<message>::
+       This option is only valid for add, merge and pull (unsure).
+       Specify <message> as the commit message for the merge commit.
+
+
+OPTIONS FOR add, merge, push, pull
+----------------------------------
+--squash::
+       This option is only valid for add, merge, push and pull
+       commands.
+
+       Instead of merging the entire history from the subtree
+       project, produce only a single commit that contains all
+       the differences you want to merge, and then merge that
+       new commit into your project.
+       
+       Using this option helps to reduce log clutter. People
+       rarely want to see every change that happened between
+       v1.0 and v1.1 of the library they're using, since none of the
+       interim versions were ever included in their application.
+       
+       Using '--squash' also helps avoid problems when the same
+       subproject is included multiple times in the same
+       project, or is removed and then re-added.  In such a
+       case, it doesn't make sense to combine the histories
+       anyway, since it's unclear which part of the history
+       belongs to which subtree.
+       
+       Furthermore, with '--squash', you can switch back and
+       forth between different versions of a subtree, rather
+       than strictly forward.  'git subtree merge --squash'
+       always adjusts the subtree to match the exactly
+       specified commit, even if getting to that commit would
+       require undoing some changes that were added earlier.
+       
+       Whether or not you use '--squash', changes made in your
+       local repository remain intact and can be later split
+       and send upstream to the subproject.
+
+
+OPTIONS FOR split
+-----------------
+--annotate=<annotation>::
+       This option is only valid for the split command.
+
+       When generating synthetic history, add <annotation> as a
+       prefix to each commit message.  Since we're creating new
+       commits with the same commit message, but possibly
+       different content, from the original commits, this can help
+       to differentiate them and avoid confusion.
+       
+       Whenever you split, you need to use the same
+       <annotation>, or else you don't have a guarantee that
+       the new re-created history will be identical to the old
+       one.  That will prevent merging from working correctly. 
+       git subtree tries to make it work anyway, particularly
+       if you use --rejoin, but it may not always be effective.
+
+-b <branch>::
+--branch=<branch>::
+       This option is only valid for the split command.
+
+       After generating the synthetic history, create a new
+       branch called <branch> that contains the new history. 
+       This is suitable for immediate pushing upstream. 
+       <branch> must not already exist.
+
+--ignore-joins::
+       This option is only valid for the split command.
+
+       If you use '--rejoin', git subtree attempts to optimize
+       its history reconstruction to generate only the new
+       commits since the last '--rejoin'.  '--ignore-join'
+       disables this behaviour, forcing it to regenerate the
+       entire history.  In a large project, this can take a
+       long time.
+
+--onto=<onto>::
+       This option is only valid for the split command.
+
+       If your subtree was originally imported using something
+       other than git subtree, its history may not match what
+       git subtree is expecting.  In that case, you can specify
+       the commit id <onto> that corresponds to the first
+       revision of the subproject's history that was imported
+       into your project, and git subtree will attempt to build
+       its history from there.
+       
+       If you used 'git subtree add', you should never need
+       this option.
+
+--rejoin::
+       This option is only valid for the split command.
+
+       After splitting, merge the newly created synthetic
+       history back into your main project.  That way, future
+       splits can search only the part of history that has
+       been added since the most recent --rejoin.
+       
+       If your split commits end up merged into the upstream
+       subproject, and then you want to get the latest upstream
+       version, this will allow git's merge algorithm to more
+       intelligently avoid conflicts (since it knows these
+       synthetic commits are already part of the upstream
+       repository).
+       
+       Unfortunately, using this option results in 'git log'
+       showing an extra copy of every new commit that was
+       created (the original, and the synthetic one).
+       
+       If you do all your merges with '--squash', don't use
+       '--rejoin' when you split, because you don't want the
+       subproject's history to be part of your project anyway.
+
+
+EXAMPLE 1. Add command
+----------------------
+Let's assume that you have a local repository that you would like
+to add an external vendor library to. In this case we will add the
+git-subtree repository as a subdirectory of your already existing
+git-extensions repository in ~/git-extensions/:
+
+       $ git subtree add --prefix=git-subtree --squash \
+               git://github.com/apenwarr/git-subtree.git master
+
+'master' needs to be a valid remote ref and can be a different branch
+name
+
+You can omit the --squash flag, but doing so will increase the number
+of commits that are incldued in your local repository.
+
+We now have a ~/git-extensions/git-subtree directory containing code
+from the master branch of git://github.com/apenwarr/git-subtree.git
+in our git-extensions repository.
+
+EXAMPLE 2. Extract a subtree using commit, merge and pull
+---------------------------------------------------------
+Let's use the repository for the git source code as an example.
+First, get your own copy of the git.git repository:
+
+       $ git clone git://git.kernel.org/pub/scm/git/git.git test-git
+       $ cd test-git
+
+gitweb (commit 1130ef3) was merged into git as of commit
+0a8f4f0, after which it was no longer maintained separately. 
+But imagine it had been maintained separately, and we wanted to
+extract git's changes to gitweb since that time, to share with
+the upstream.  You could do this:
+
+       $ git subtree split --prefix=gitweb --annotate='(split) ' \
+               0a8f4f0^.. --onto=1130ef3 --rejoin \
+               --branch gitweb-latest
+        $ gitk gitweb-latest
+        $ git push git@github.com:whatever/gitweb.git gitweb-latest:master
+        
+(We use '0a8f4f0^..' because that means "all the changes from
+0a8f4f0 to the current version, including 0a8f4f0 itself.")
+
+If gitweb had originally been merged using 'git subtree add' (or
+a previous split had already been done with --rejoin specified)
+then you can do all your splits without having to remember any
+weird commit ids:
+
+       $ git subtree split --prefix=gitweb --annotate='(split) ' --rejoin \
+               --branch gitweb-latest2
+
+And you can merge changes back in from the upstream project just
+as easily:
+
+       $ git subtree pull --prefix=gitweb \
+               git@github.com:whatever/gitweb.git master
+
+Or, using '--squash', you can actually rewind to an earlier
+version of gitweb:
+
+       $ git subtree merge --prefix=gitweb --squash gitweb-latest~10
+
+Then make some changes:
+
+       $ date >gitweb/myfile
+       $ git add gitweb/myfile
+       $ git commit -m 'created myfile'
+
+And fast forward again:
+
+       $ git subtree merge --prefix=gitweb --squash gitweb-latest
+
+And notice that your change is still intact:
+       
+       $ ls -l gitweb/myfile
+
+And you can split it out and look at your changes versus
+the standard gitweb:
+
+       git log gitweb-latest..$(git subtree split --prefix=gitweb)
+
+EXAMPLE 3. Extract a subtree using branch
+-----------------------------------------
+Suppose you have a source directory with many files and
+subdirectories, and you want to extract the lib directory to its own
+git project. Here's a short way to do it:
+
+First, make the new repository wherever you want:
+
+       $ <go to the new location>
+       $ git init --bare
+
+Back in your original directory:
+
+       $ git subtree split --prefix=lib --annotate="(split)" -b split
+
+Then push the new branch onto the new empty repository:
+
+       $ git push <new-repo> split:master
+
+
+AUTHOR
+------
+Written by Avery Pennarun <apenwarr@gmail.com>
+
+
+GIT
+---
+Part of the linkgit:git[1] suite
diff --git a/contrib/subtree/t/Makefile b/contrib/subtree/t/Makefile
new file mode 100644 (file)
index 0000000..c864810
--- /dev/null
@@ -0,0 +1,69 @@
+# Run tests
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+-include ../../../config.mak.autogen
+-include ../../../config.mak
+
+#GIT_TEST_OPTS=--verbose --debug
+SHELL_PATH ?= $(SHELL)
+PERL_PATH ?= /usr/bin/perl
+TAR ?= $(TAR)
+RM ?= rm -f
+PROVE ?= prove
+DEFAULT_TEST_TARGET ?= test
+
+# Shell quote;
+SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+
+T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
+
+all: $(DEFAULT_TEST_TARGET)
+
+test: pre-clean $(TEST_LINT)
+       $(MAKE) aggregate-results-and-cleanup
+
+prove: pre-clean $(TEST_LINT)
+       @echo "*** prove ***"; GIT_CONFIG=.git/config $(PROVE) --exec '$(SHELL_PATH_SQ)' $(GIT_PROVE_OPTS) $(T) :: $(GIT_TEST_OPTS)
+       $(MAKE) clean
+
+$(T):
+       @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
+
+pre-clean:
+       $(RM) -r test-results
+
+clean:
+       $(RM) -r 'trash directory'.* test-results
+       $(RM) -r valgrind/bin
+       $(RM) .prove
+
+test-lint: test-lint-duplicates test-lint-executable
+
+test-lint-duplicates:
+       @dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \
+               test -z "$$dups" || { \
+               echo >&2 "duplicate test numbers:" $$dups; exit 1; }
+
+test-lint-executable:
+       @bad=`for i in $(T); do test -x "$$i" || echo $$i; done` && \
+               test -z "$$bad" || { \
+               echo >&2 "non-executable tests:" $$bad; exit 1; }
+
+aggregate-results-and-cleanup: $(T)
+       $(MAKE) aggregate-results
+       $(MAKE) clean
+
+aggregate-results:
+       for f in ../../../t/test-results/t*-*.counts; do \
+               echo "$$f"; \
+       done | '$(SHELL_PATH_SQ)' ../../../t/aggregate-results.sh
+
+valgrind:
+       $(MAKE) GIT_TEST_OPTS="$(GIT_TEST_OPTS) --valgrind"
+
+test-results:
+       mkdir -p test-results
+
+.PHONY: pre-clean $(T) aggregate-results clean valgrind
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
new file mode 100755 (executable)
index 0000000..bc2eeb0
--- /dev/null
@@ -0,0 +1,508 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Avery Pennaraum
+#
+test_description='Basic porcelain support for subtrees
+
+This test verifies the basic operation of the merge, pull, add
+and split subcommands of git subtree.
+'
+
+export TEST_DIRECTORY=$(pwd)/../../../t
+
+. ../../../t/test-lib.sh
+
+create()
+{
+       echo "$1" >"$1"
+       git add "$1"
+}
+
+
+check_equal()
+{
+       test_debug 'echo'
+       test_debug "echo \"check a:\" \"{$1}\""
+       test_debug "echo \"      b:\" \"{$2}\""
+       if [ "$1" = "$2" ]; then
+               return 0
+       else
+               return 1
+       fi
+}
+
+fixnl()
+{
+       t=""
+       while read x; do
+               t="$t$x "
+       done
+       echo $t
+}
+
+multiline()
+{
+       while read x; do
+               set -- $x
+               for d in "$@"; do
+                       echo "$d"
+               done
+       done
+}
+
+undo()
+{
+       git reset --hard HEAD~
+}
+
+last_commit_message()
+{
+       git log --pretty=format:%s -1
+}
+
+# 1
+test_expect_success 'init subproj' '
+        test_create_repo subproj
+'
+
+# To the subproject!
+cd subproj
+
+# 2
+test_expect_success 'add sub1' '
+        create sub1 &&
+        git commit -m "sub1" &&
+        git branch sub1 &&
+        git branch -m master subproj
+'
+
+# 3
+test_expect_success 'add sub2' '
+        create sub2 &&
+        git commit -m "sub2" &&
+        git branch sub2
+'
+
+# 4
+test_expect_success 'add sub3' '
+        create sub3 &&
+        git commit -m "sub3" &&
+        git branch sub3
+'
+
+# Back to mainline
+cd ..
+
+# 5
+test_expect_success 'add main4' '
+        create main4 &&
+        git commit -m "main4" &&
+        git branch -m master mainline &&
+        git branch subdir
+'
+
+# 6
+test_expect_success 'fetch subproj history' '
+        git fetch ./subproj sub1 &&
+        git branch sub1 FETCH_HEAD
+'
+
+# 7
+test_expect_success 'no subtree exists in main tree' '
+        test_must_fail git subtree merge --prefix=subdir sub1
+'
+
+# 8
+test_expect_success 'no pull from non-existant subtree' '
+        test_must_fail git subtree pull --prefix=subdir ./subproj sub1
+'
+
+# 9
+test_expect_success 'check if --message works for add' '
+        git subtree add --prefix=subdir --message="Added subproject" sub1 &&
+        check_equal ''"$(last_commit_message)"'' "Added subproject" &&
+        undo
+'
+
+# 10
+test_expect_success 'check if --message works as -m and --prefix as -P' '
+        git subtree add -P subdir -m "Added subproject using git subtree" sub1 &&
+        check_equal ''"$(last_commit_message)"'' "Added subproject using git subtree" &&
+        undo
+'
+
+# 11
+test_expect_success 'check if --message works with squash too' '
+        git subtree add -P subdir -m "Added subproject with squash" --squash sub1 &&
+        check_equal ''"$(last_commit_message)"'' "Added subproject with squash" &&
+        undo
+'
+
+# 12
+test_expect_success 'add subproj to mainline' '
+        git subtree add --prefix=subdir/ FETCH_HEAD &&
+        check_equal ''"$(last_commit_message)"'' "Add '"'subdir/'"' from commit '"'"'''"$(git rev-parse sub1)"'''"'"'"
+'
+
+# 13
+# this shouldn't actually do anything, since FETCH_HEAD is already a parent
+test_expect_success 'merge fetched subproj' '
+        git merge -m "merge -s -ours" -s ours FETCH_HEAD
+'
+
+# 14
+test_expect_success 'add main-sub5' '
+        create subdir/main-sub5 &&
+        git commit -m "main-sub5"
+'
+
+# 15
+test_expect_success 'add main6' '
+        create main6 &&
+        git commit -m "main6 boring"
+'
+
+# 16
+test_expect_success 'add main-sub7' '
+        create subdir/main-sub7 &&
+        git commit -m "main-sub7"
+'
+
+# 17
+test_expect_success 'fetch new subproj history' '
+        git fetch ./subproj sub2 &&
+        git branch sub2 FETCH_HEAD
+'
+
+# 18
+test_expect_success 'check if --message works for merge' '
+        git subtree merge --prefix=subdir -m "Merged changes from subproject" sub2 &&
+        check_equal ''"$(last_commit_message)"'' "Merged changes from subproject" &&
+        undo
+'
+
+# 19
+test_expect_success 'check if --message for merge works with squash too' '
+        git subtree merge --prefix subdir -m "Merged changes from subproject using squash" --squash sub2 &&
+        check_equal ''"$(last_commit_message)"'' "Merged changes from subproject using squash" &&
+        undo
+'
+
+# 20
+test_expect_success 'merge new subproj history into subdir' '
+        git subtree merge --prefix=subdir FETCH_HEAD &&
+        git branch pre-split &&
+        check_equal ''"$(last_commit_message)"'' "Merge commit '"'"'"$(git rev-parse sub2)"'"'"' into mainline"
+'
+
+# 21
+test_expect_success 'Check that prefix argument is required for split' '
+        echo "You must provide the --prefix option." > expected &&
+        test_must_fail git subtree split > actual 2>&1 &&
+        test_debug "echo -n expected: " &&
+        test_debug "cat expected" &&
+        test_debug "echo -n actual: " &&
+        test_debug "cat actual" &&
+        test_cmp expected actual &&
+        rm -f expected actual
+'
+
+# 22
+test_expect_success 'Check that the <prefix> exists for a split' '
+        echo "'"'"'non-existent-directory'"'"'" does not exist\; use "'"'"'git subtree add'"'"'" > expected &&
+        test_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&
+        test_debug "echo -n expected: " &&
+        test_debug "cat expected" &&
+        test_debug "echo -n actual: " &&
+        test_debug "cat actual" &&
+        test_cmp expected actual
+#        rm -f expected actual
+'
+
+# 23
+test_expect_success 'check if --message works for split+rejoin' '
+        spl1=''"$(git subtree split --annotate='"'*'"' --prefix subdir --onto FETCH_HEAD --message "Split & rejoin" --rejoin)"'' &&
+        git branch spl1 "$spl1" &&
+        check_equal ''"$(last_commit_message)"'' "Split & rejoin" &&
+        undo
+'
+
+# 24
+test_expect_success 'check split with --branch' '
+        spl1=$(git subtree split --annotate='"'*'"' --prefix subdir --onto FETCH_HEAD --message "Split & rejoin" --rejoin) &&
+        undo &&
+        git subtree split --annotate='"'*'"' --prefix subdir --onto FETCH_HEAD --branch splitbr1 &&
+        check_equal ''"$(git rev-parse splitbr1)"'' "$spl1"
+'
+
+# 25
+test_expect_success 'check split with --branch for an existing branch' '
+        spl1=''"$(git subtree split --annotate='"'*'"' --prefix subdir --onto FETCH_HEAD --message "Split & rejoin" --rejoin)"'' &&
+        undo &&
+        git branch splitbr2 sub1 &&
+        git subtree split --annotate='"'*'"' --prefix subdir --onto FETCH_HEAD --branch splitbr2 &&
+        check_equal ''"$(git rev-parse splitbr2)"'' "$spl1"
+'
+
+# 26
+test_expect_success 'check split with --branch for an incompatible branch' '
+        test_must_fail git subtree split --prefix subdir --onto FETCH_HEAD --branch subdir
+'
+
+
+# 27
+test_expect_success 'check split+rejoin' '
+        spl1=''"$(git subtree split --annotate='"'*'"' --prefix subdir --onto FETCH_HEAD --message "Split & rejoin" --rejoin)"'' &&
+        undo &&
+        git subtree split --annotate='"'*'"' --prefix subdir --onto FETCH_HEAD --rejoin &&
+        check_equal ''"$(last_commit_message)"'' "Split '"'"'subdir/'"'"' into commit '"'"'"$spl1"'"'"'"
+'
+
+# 28
+test_expect_success 'add main-sub8' '
+        create subdir/main-sub8 &&
+        git commit -m "main-sub8"
+'
+
+# To the subproject!
+cd ./subproj
+
+# 29
+test_expect_success 'merge split into subproj' '
+        git fetch .. spl1 &&
+        git branch spl1 FETCH_HEAD &&
+        git merge FETCH_HEAD
+'
+
+# 30
+test_expect_success 'add sub9' '
+        create sub9 &&
+        git commit -m "sub9"
+'
+
+# Back to mainline
+cd ..
+
+# 31
+test_expect_success 'split for sub8' '
+        split2=''"$(git subtree split --annotate='"'*'"' --prefix subdir/ --rejoin)"''
+        git branch split2 "$split2"
+'
+
+# 32
+test_expect_success 'add main-sub10' '
+        create subdir/main-sub10 &&
+        git commit -m "main-sub10"
+'
+
+# 33
+test_expect_success 'split for sub10' '
+        spl3=''"$(git subtree split --annotate='"'*'"' --prefix subdir --rejoin)"'' &&
+        git branch spl3 "$spl3"
+'
+
+# To the subproject!
+cd ./subproj
+
+# 34
+test_expect_success 'merge split into subproj' '
+        git fetch .. spl3 &&
+        git branch spl3 FETCH_HEAD &&
+        git merge FETCH_HEAD &&
+        git branch subproj-merge-spl3
+'
+
+chkm="main4 main6"
+chkms="main-sub10 main-sub5 main-sub7 main-sub8"
+chkms_sub=$(echo $chkms | multiline | sed 's,^,subdir/,' | fixnl)
+chks="sub1 sub2 sub3 sub9"
+chks_sub=$(echo $chks | multiline | sed 's,^,subdir/,' | fixnl)
+
+# 35
+test_expect_success 'make sure exactly the right set of files ends up in the subproj' '
+        subfiles=''"$(git ls-files | fixnl)"'' &&
+        check_equal "$subfiles" "$chkms $chks"
+'
+
+# 36
+test_expect_success 'make sure the subproj history *only* contains commits that affect the subdir' '
+        allchanges=''"$(git log --name-only --pretty=format:'"''"' | sort | fixnl)"'' &&
+        check_equal "$allchanges" "$chkms $chks"
+'
+
+# Back to mainline
+cd ..
+
+# 37
+test_expect_success 'pull from subproj' '
+        git fetch ./subproj subproj-merge-spl3 &&
+        git branch subproj-merge-spl3 FETCH_HEAD &&
+        git subtree pull --prefix=subdir ./subproj subproj-merge-spl3
+'
+
+# 38
+test_expect_success 'make sure exactly the right set of files ends up in the mainline' '
+        mainfiles=''"$(git ls-files | fixnl)"'' &&
+        check_equal "$mainfiles" "$chkm $chkms_sub $chks_sub"
+'
+
+# 39
+test_expect_success 'make sure each filename changed exactly once in the entire history' '
+        # main-sub?? and /subdir/main-sub?? both change, because those are the
+        # changes that were split into their own history.  And subdir/sub?? never
+        # change, since they were *only* changed in the subtree branch.
+        allchanges=''"$(git log --name-only --pretty=format:'"''"' | sort | fixnl)"'' &&
+        check_equal "$allchanges" ''"$(echo $chkms $chkm $chks $chkms_sub | multiline | sort | fixnl)"''
+'
+
+# 40
+test_expect_success 'make sure the --rejoin commits never make it into subproj' '
+        check_equal ''"$(git log --pretty=format:'"'%s'"' HEAD^2 | grep -i split)"'' ""
+'
+
+# 41
+test_expect_success 'make sure no "git subtree" tagged commits make it into subproj' '
+        # They are meaningless to subproj since one side of the merge refers to the mainline
+        check_equal ''"$(git log --pretty=format:'"'%s%n%b'"' HEAD^2 | grep "git-subtree.*:")"'' ""
+'
+
+# prepare second pair of repositories
+mkdir test2
+cd test2
+
+# 42
+test_expect_success 'init main' '
+        test_create_repo main
+'
+
+cd main
+
+# 43
+test_expect_success 'add main1' '
+        create main1 &&
+        git commit -m "main1"
+'
+
+cd ..
+
+# 44
+test_expect_success 'init sub' '
+        test_create_repo sub
+'
+
+cd sub
+
+# 45
+test_expect_success 'add sub2' '
+        create sub2 &&
+        git commit -m "sub2"
+'
+
+cd ../main
+
+# check if split can find proper base without --onto
+
+# 46
+test_expect_success 'add sub as subdir in main' '
+        git fetch ../sub master &&
+        git branch sub2 FETCH_HEAD &&
+        git subtree add --prefix subdir sub2
+'
+
+cd ../sub
+
+# 47
+test_expect_success 'add sub3' '
+        create sub3 &&
+        git commit -m "sub3"
+'
+
+cd ../main
+
+# 48
+test_expect_success 'merge from sub' '
+        git fetch ../sub master &&
+        git branch sub3 FETCH_HEAD &&
+        git subtree merge --prefix subdir sub3
+'
+
+# 49
+test_expect_success 'add main-sub4' '
+        create subdir/main-sub4 &&
+        git commit -m "main-sub4"
+'
+
+# 50
+test_expect_success 'split for main-sub4 without --onto' '
+        git subtree split --prefix subdir --branch mainsub4
+'
+
+# at this point, the new commit parent should be sub3 if it is not,
+# something went wrong (the "newparent" of "master~" commit should
+# have been sub3, but it was not, because its cache was not set to
+# itself)
+
+# 51
+test_expect_success 'check that the commit parent is sub3' '
+        check_equal ''"$(git log --pretty=format:%P -1 mainsub4)"'' ''"$(git rev-parse sub3)"''
+'
+
+# 52
+test_expect_success 'add main-sub5' '
+        mkdir subdir2 &&
+        create subdir2/main-sub5 &&
+        git commit -m "main-sub5"
+'
+
+# 53
+test_expect_success 'split for main-sub5 without --onto' '
+        # also test that we still can split out an entirely new subtree
+        # if the parent of the first commit in the tree is not empty,
+        # then the new subtree has accidently been attached to something
+        git subtree split --prefix subdir2 --branch mainsub5 &&
+        check_equal ''"$(git log --pretty=format:%P -1 mainsub5)"'' ""
+'
+
+# make sure no patch changes more than one file.  The original set of commits
+# changed only one file each.  A multi-file change would imply that we pruned
+# commits too aggressively.
+joincommits()
+{
+       commit=
+       all=
+       while read x y; do
+               #echo "{$x}" >&2
+               if [ -z "$x" ]; then
+                       continue
+               elif [ "$x" = "commit:" ]; then
+                       if [ -n "$commit" ]; then
+                               echo "$commit $all"
+                               all=
+                       fi
+                       commit="$y"
+               else
+                       all="$all $y"
+               fi
+       done
+       echo "$commit $all"
+}
+
+# 54
+test_expect_success 'verify one file change per commit' '
+        x= &&
+        list=''"$(git log --pretty=format:'"'commit: %H'"' | joincommits)"'' &&
+#        test_debug "echo HERE" &&
+#        test_debug "echo ''"$list"''" &&
+        (git log --pretty=format:'"'commit: %H'"' | joincommits |
+        (       while read commit a b; do
+                       test_debug "echo Verifying commit "''"$commit"''
+                       test_debug "echo a: "''"$a"''
+                       test_debug "echo b: "''"$b"''
+                       check_equal "$b" ""
+                       x=1
+               done
+               check_equal "$x" 1
+        ))
+'
+
+test_done
diff --git a/contrib/subtree/todo b/contrib/subtree/todo
new file mode 100644 (file)
index 0000000..7e44b00
--- /dev/null
@@ -0,0 +1,50 @@
+
+       delete tempdir
+
+       'git subtree rejoin' option to do the same as --rejoin, eg. after a
+         rebase
+
+       --prefix doesn't force the subtree correctly in merge/pull:
+       "-s subtree" should be given an explicit subtree option?
+               There doesn't seem to be a way to do this.  We'd have to
+               patch git-merge-subtree.  Ugh.
+               (but we could avoid this problem by generating squashes with
+               exactly the right subtree structure, rather than using
+               subtree merge...)
+
+       add a 'push' subcommand to parallel 'pull'
+       
+       add a 'log' subcommand to see what's new in a subtree?
+
+       add to-submodule and from-submodule commands
+
+       automated tests for --squash stuff
+
+       "add" command non-obviously requires a commitid; would be easier if
+               it had a "pull" sort of mode instead
+
+       "pull" and "merge" commands should fail if you've never merged
+               that --prefix before
+               
+       docs should provide an example of "add"
+       
+       note that the initial split doesn't *have* to have a commitid
+               specified... that's just an optimization
+
+       if you try to add (or maybe merge?) with an invalid commitid, you
+               get a misleading "prefix must end with /" message from
+               one of the other git tools that git-subtree calls.  Should
+               detect this situation and print the *real* problem.
+       
+       "pull --squash" should do fetch-synthesize-merge, but instead just
+               does "pull" directly, which doesn't work at all.
+
+       make a 'force-update' that does what 'add' does even if the subtree
+               already exists.  That way we can help people who imported
+               subtrees "incorrectly" (eg. by just copying in the files) in
+               the past.
+
+       guess --prefix automatically if possible based on pwd
+
+       make a 'git subtree grafts' that automatically expands --squash'd
+               commits so you can see the full history if you want it.
index 2dd27ceb0e41c81faa12d44468b46316fa07b32f..1128ab2ce46c42c5b5c9bf2adb3425ebc2720944 100644 (file)
@@ -51,7 +51,7 @@ as committer, where 'user' is the value of the `svn:author` property
 and 'UUID' the repository's identifier.
 
 To support incremental imports, 'svn-fe' puts a `git-svn-id` line at
-the end of each commit log message if passed an url on the command
+the end of each commit log message if passed a URL on the command
 line.  This line has the form `git-svn-id: URL@REVNO UUID`.
 
 The resulting repository will generally require further processing
diff --git a/diff.c b/diff.c
index 377ec1ea4cd90524f7c7525846fc95c3a9e66920..b020c070cac15e7448178db67a480fc311f18ad9 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -989,10 +989,74 @@ static void diff_words_flush(struct emit_callback *ecbdata)
                diff_words_show(ecbdata->diff_words);
 }
 
+static void diff_filespec_load_driver(struct diff_filespec *one)
+{
+       /* Use already-loaded driver */
+       if (one->driver)
+               return;
+
+       if (S_ISREG(one->mode))
+               one->driver = userdiff_find_by_path(one->path);
+
+       /* Fallback to default settings */
+       if (!one->driver)
+               one->driver = userdiff_find_by_name("default");
+}
+
+static const char *userdiff_word_regex(struct diff_filespec *one)
+{
+       diff_filespec_load_driver(one);
+       return one->driver->word_regex;
+}
+
+static void init_diff_words_data(struct emit_callback *ecbdata,
+                                struct diff_options *orig_opts,
+                                struct diff_filespec *one,
+                                struct diff_filespec *two)
+{
+       int i;
+       struct diff_options *o = xmalloc(sizeof(struct diff_options));
+       memcpy(o, orig_opts, sizeof(struct diff_options));
+
+       ecbdata->diff_words =
+               xcalloc(1, sizeof(struct diff_words_data));
+       ecbdata->diff_words->type = o->word_diff;
+       ecbdata->diff_words->opt = o;
+       if (!o->word_regex)
+               o->word_regex = userdiff_word_regex(one);
+       if (!o->word_regex)
+               o->word_regex = userdiff_word_regex(two);
+       if (!o->word_regex)
+               o->word_regex = diff_word_regex_cfg;
+       if (o->word_regex) {
+               ecbdata->diff_words->word_regex = (regex_t *)
+                       xmalloc(sizeof(regex_t));
+               if (regcomp(ecbdata->diff_words->word_regex,
+                           o->word_regex,
+                           REG_EXTENDED | REG_NEWLINE))
+                       die ("Invalid regular expression: %s",
+                            o->word_regex);
+       }
+       for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) {
+               if (o->word_diff == diff_words_styles[i].type) {
+                       ecbdata->diff_words->style =
+                               &diff_words_styles[i];
+                       break;
+               }
+       }
+       if (want_color(o->use_color)) {
+               struct diff_words_style *st = ecbdata->diff_words->style;
+               st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD);
+               st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW);
+               st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN);
+       }
+}
+
 static void free_diff_words_data(struct emit_callback *ecbdata)
 {
        if (ecbdata->diff_words) {
                diff_words_flush(ecbdata);
+               free (ecbdata->diff_words->opt);
                free (ecbdata->diff_words->minus.text.ptr);
                free (ecbdata->diff_words->minus.orig);
                free (ecbdata->diff_words->plus.text.ptr);
@@ -2061,20 +2125,6 @@ static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two, char *pre
        emit_binary_diff_body(file, two, one, prefix);
 }
 
-static void diff_filespec_load_driver(struct diff_filespec *one)
-{
-       /* Use already-loaded driver */
-       if (one->driver)
-               return;
-
-       if (S_ISREG(one->mode))
-               one->driver = userdiff_find_by_path(one->path);
-
-       /* Fallback to default settings */
-       if (!one->driver)
-               one->driver = userdiff_find_by_name("default");
-}
-
 int diff_filespec_is_binary(struct diff_filespec *one)
 {
        if (one->is_binary == -1) {
@@ -2100,12 +2150,6 @@ static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespe
        return one->driver->funcname.pattern ? &one->driver->funcname : NULL;
 }
 
-static const char *userdiff_word_regex(struct diff_filespec *one)
-{
-       diff_filespec_load_driver(one);
-       return one->driver->word_regex;
-}
-
 void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b)
 {
        if (!options->a_prefix)
@@ -2292,42 +2336,8 @@ static void builtin_diff(const char *name_a,
                        xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
                else if (!prefixcmp(diffopts, "-u"))
                        xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
-               if (o->word_diff) {
-                       int i;
-
-                       ecbdata.diff_words =
-                               xcalloc(1, sizeof(struct diff_words_data));
-                       ecbdata.diff_words->type = o->word_diff;
-                       ecbdata.diff_words->opt = o;
-                       if (!o->word_regex)
-                               o->word_regex = userdiff_word_regex(one);
-                       if (!o->word_regex)
-                               o->word_regex = userdiff_word_regex(two);
-                       if (!o->word_regex)
-                               o->word_regex = diff_word_regex_cfg;
-                       if (o->word_regex) {
-                               ecbdata.diff_words->word_regex = (regex_t *)
-                                       xmalloc(sizeof(regex_t));
-                               if (regcomp(ecbdata.diff_words->word_regex,
-                                               o->word_regex,
-                                               REG_EXTENDED | REG_NEWLINE))
-                                       die ("Invalid regular expression: %s",
-                                                       o->word_regex);
-                       }
-                       for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) {
-                               if (o->word_diff == diff_words_styles[i].type) {
-                                       ecbdata.diff_words->style =
-                                               &diff_words_styles[i];
-                                       break;
-                               }
-                       }
-                       if (want_color(o->use_color)) {
-                               struct diff_words_style *st = ecbdata.diff_words->style;
-                               st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD);
-                               st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW);
-                               st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN);
-                       }
-               }
+               if (o->word_diff)
+                       init_diff_words_data(&ecbdata, o, one, two);
                xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
                              &xpp, &xecfg);
                if (o->word_diff)
@@ -3525,9 +3535,9 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
        else if (!strcmp(arg, "--ignore-space-at-eol"))
                DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
        else if (!strcmp(arg, "--patience"))
-               DIFF_XDL_SET(options, PATIENCE_DIFF);
+               options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
        else if (!strcmp(arg, "--histogram"))
-               DIFF_XDL_SET(options, HISTOGRAM_DIFF);
+               options->xdl_opts = DIFF_WITH_ALG(options, HISTOGRAM_DIFF);
 
        /* flags options */
        else if (!strcmp(arg, "--binary")) {
diff --git a/diff.h b/diff.h
index cb687436a0ddb9a08fc1a9e9cec569233284e01f..e9e3d44c674a39bb1912ca366ca12512dfb4d2c7 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -91,6 +91,8 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)
 #define DIFF_XDL_SET(opts, flag)    ((opts)->xdl_opts |= XDF_##flag)
 #define DIFF_XDL_CLR(opts, flag)    ((opts)->xdl_opts &= ~XDF_##flag)
 
+#define DIFF_WITH_ALG(opts, flag)   (((opts)->xdl_opts & ~XDF_DIFF_ALGORITHM_MASK) | XDF_##flag)
+
 enum diff_words_type {
        DIFF_WORDS_NONE = 0,
        DIFF_WORDS_PORCELAIN,
diff --git a/dir.c b/dir.c
index 0a78d00b545ac4f302ea89b6393773669907599e..2087d23b6bce5280e54770923cb7b7274361d667 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -1178,6 +1178,7 @@ int remove_dir_recursively(struct strbuf *path, int flag)
        struct dirent *e;
        int ret = 0, original_len = path->len, len;
        int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);
+       int keep_toplevel = (flag & REMOVE_DIR_KEEP_TOPLEVEL);
        unsigned char submodule_head[20];
 
        if ((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
@@ -1185,9 +1186,14 @@ int remove_dir_recursively(struct strbuf *path, int flag)
                /* Do not descend and nuke a nested git work tree. */
                return 0;
 
+       flag &= ~(REMOVE_DIR_KEEP_TOPLEVEL|REMOVE_DIR_KEEP_NESTED_GIT);
        dir = opendir(path->buf);
-       if (!dir)
-               return rmdir(path->buf);
+       if (!dir) {
+               if (!keep_toplevel)
+                       return rmdir(path->buf);
+               else
+                       return -1;
+       }
        if (path->buf[original_len - 1] != '/')
                strbuf_addch(path, '/');
 
@@ -1202,7 +1208,7 @@ int remove_dir_recursively(struct strbuf *path, int flag)
                if (lstat(path->buf, &st))
                        ; /* fall thru */
                else if (S_ISDIR(st.st_mode)) {
-                       if (!remove_dir_recursively(path, only_empty))
+                       if (!remove_dir_recursively(path, flag))
                                continue; /* happy */
                } else if (!only_empty && !unlink(path->buf))
                        continue; /* happy, too */
@@ -1214,7 +1220,7 @@ int remove_dir_recursively(struct strbuf *path, int flag)
        closedir(dir);
 
        strbuf_setlen(path, original_len);
-       if (!ret)
+       if (!ret && !keep_toplevel)
                ret = rmdir(path->buf);
        return ret;
 }
diff --git a/dir.h b/dir.h
index dd6947e1d46098732ff1d8c3f23087c1e7163fe9..58b6fc7c86df1bd5ac6f072672027a1474732ac6 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -102,6 +102,7 @@ extern void setup_standard_excludes(struct dir_struct *dir);
 
 #define REMOVE_DIR_EMPTY_ONLY 01
 #define REMOVE_DIR_KEEP_NESTED_GIT 02
+#define REMOVE_DIR_KEEP_TOPLEVEL 04
 extern int remove_dir_recursively(struct strbuf *path, int flag);
 
 /* tries to remove the path with empty directories along it, ignores ENOENT */
diff --git a/entry.c b/entry.c
index 852fea13955475c1e2fda9cfc25a63a54a1f61c7..17a6bccec64e0e523aacc124611c43bd818372e3 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -120,58 +120,15 @@ static int streaming_write_entry(struct cache_entry *ce, char *path,
                                 const struct checkout *state, int to_tempfile,
                                 int *fstat_done, struct stat *statbuf)
 {
-       struct git_istream *st;
-       enum object_type type;
-       unsigned long sz;
        int result = -1;
-       ssize_t kept = 0;
-       int fd = -1;
-
-       st = open_istream(ce->sha1, &type, &sz, filter);
-       if (!st)
-               return -1;
-       if (type != OBJ_BLOB)
-               goto close_and_exit;
+       int fd;
 
        fd = open_output_fd(path, ce, to_tempfile);
-       if (fd < 0)
-               goto close_and_exit;
-
-       for (;;) {
-               char buf[1024 * 16];
-               ssize_t wrote, holeto;
-               ssize_t readlen = read_istream(st, buf, sizeof(buf));
-
-               if (!readlen)
-                       break;
-               if (sizeof(buf) == readlen) {
-                       for (holeto = 0; holeto < readlen; holeto++)
-                               if (buf[holeto])
-                                       break;
-                       if (readlen == holeto) {
-                               kept += holeto;
-                               continue;
-                       }
-               }
-
-               if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)
-                       goto close_and_exit;
-               else
-                       kept = 0;
-               wrote = write_in_full(fd, buf, readlen);
-
-               if (wrote != readlen)
-                       goto close_and_exit;
-       }
-       if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
-                    write(fd, "", 1) != 1))
-               goto close_and_exit;
-       *fstat_done = fstat_output(fd, state, statbuf);
-
-close_and_exit:
-       close_istream(st);
-       if (0 <= fd)
+       if (0 <= fd) {
+               result = stream_blob_to_fd(fd, ce->sha1, filter, 1);
+               *fstat_done = fstat_output(fd, state, statbuf);
                result = close(fd);
+       }
        if (result && 0 <= fd)
                unlink(path);
        return result;
index b93df109c8f34ec25bd837aa7f1301b9f492efb0..d61d537ef0cbdfa9d4a719ca622e148bbe436fd1 100644 (file)
@@ -101,6 +101,7 @@ Group:          Development/Libraries
 Requires:       git = %{version}-%{release}
 Requires:       perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
 BuildRequires:  perl(Error)
+BuildRequires:  perl(ExtUtils::MakeMaker)
 
 %description -n perl-Git
 Perl interface to Git
index 64ef3c401367c96236d81de3d88957a6459867cd..22270ce46bb73bc8fc8e82409ef0179576f7ba20 100755 (executable)
@@ -14,6 +14,35 @@ proc hasworktree {} {
                  [exec git rev-parse --is-inside-git-dir] == "false"}]
 }
 
+proc reponame {} {
+    global gitdir
+    set n [file normalize $gitdir]
+    if {[string match "*/.git" $n]} {
+       set n [string range $n 0 end-5]
+    }
+    return [file tail $n]
+}
+
+proc gitworktree {} {
+    variable _gitworktree
+    if {[info exists _gitworktree]} {
+       return $_gitworktree
+    }
+    # v1.7.0 introduced --show-toplevel to return the canonical work-tree
+    if {[catch {set _gitworktree [exec git rev-parse --show-toplevel]}]} {
+        # try to set work tree from environment, core.worktree or use
+        # cdup to obtain a relative path to the top of the worktree. If
+        # run from the top, the ./ prefix ensures normalize expands pwd.
+        if {[catch { set _gitworktree $env(GIT_WORK_TREE) }]} {
+           catch {set _gitworktree [exec git config --get core.worktree]}
+           if {$_gitworktree eq ""} {
+               set _gitworktree [file normalize ./[exec git rev-parse --show-cdup]]
+           }
+        }
+    }
+    return $_gitworktree
+}
+
 # A simple scheduler for compute-intensive stuff.
 # The aim is to make sure that event handlers for GUI actions can
 # run at least every 50-100 ms.  Unfortunately fileevent handlers are
@@ -612,12 +641,16 @@ proc varcinit {view} {
 
 proc resetvarcs {view} {
     global varcid varccommits parents children vseedcount ordertok
+    global vshortids
 
     foreach vid [array names varcid $view,*] {
        unset varcid($vid)
        unset children($vid)
        unset parents($vid)
     }
+    foreach vid [array names vshortids $view,*] {
+       unset vshortids($vid)
+    }
     # some commits might have children but haven't been seen yet
     foreach vid [array names children $view,*] {
        unset children($vid)
@@ -904,7 +937,7 @@ proc fix_reversal {p a v} {
 proc insertrow {id p v} {
     global cmitlisted children parents varcid varctok vtokmod
     global varccommits ordertok commitidx numcommits curview
-    global targetid targetrow
+    global targetid targetrow vshortids
 
     readcommit $id
     set vid $v,$id
@@ -913,6 +946,7 @@ proc insertrow {id p v} {
     set parents($vid) [list $p]
     set a [newvarc $v $id]
     set varcid($vid) $a
+    lappend vshortids($v,[string range $id 0 3]) $id
     if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
        modify_arc $v $a
     }
@@ -1368,7 +1402,7 @@ proc getcommitlines {fd inst view updating}  {
     global commitidx commitdata vdatemode
     global parents children curview hlview
     global idpending ordertok
-    global varccommits varcid varctok vtokmod vfilelimit
+    global varccommits varcid varctok vtokmod vfilelimit vshortids
 
     set stuff [read $fd 500000]
     # git log doesn't terminate the last commit with a null...
@@ -1468,6 +1502,8 @@ proc getcommitlines {fd inst view updating}  {
        set id [lindex $ids 0]
        set vid $view,$id
 
+       lappend vshortids($view,[string range $id 0 3]) $id
+
        if {!$listed && $updating && ![info exists varcid($vid)] &&
            $vfilelimit($view) ne {}} {
            # git log doesn't rewrite parents for unlisted commits
@@ -1690,11 +1726,26 @@ proc getcommit {id} {
 # and are present in the current view.
 # This is fairly slow...
 proc longid {prefix} {
-    global varcid curview
+    global varcid curview vshortids
 
     set ids {}
-    foreach match [array names varcid "$curview,$prefix*"] {
-       lappend ids [lindex [split $match ","] 1]
+    if {[string length $prefix] >= 4} {
+       set vshortid $curview,[string range $prefix 0 3]
+       if {[info exists vshortids($vshortid)]} {
+           foreach id $vshortids($vshortid) {
+               if {[string match "$prefix*" $id]} {
+                   if {[lsearch -exact $ids $id] < 0} {
+                       lappend ids $id
+                       if {[llength $ids] >= 2} break
+                   }
+               }
+           }
+       }
+    } else {
+       foreach match [array names varcid "$curview,$prefix*"] {
+           lappend ids [lindex [split $match ","] 1]
+           if {[llength $ids] >= 2} break
+       }
     }
     return $ids
 }
@@ -2491,6 +2542,8 @@ proc makewindow {} {
        {mc "Return to mark" command gotomark}
        {mc "Find descendant of this and mark" command find_common_desc}
        {mc "Compare with marked commit" command compare_commits}
+       {mc "Diff this -> marked commit" command {diffvsmark 0}}
+       {mc "Diff marked commit -> this" command {diffvsmark 1}}
     }
     $rowctxmenu configure -tearoff 0
 
@@ -2499,6 +2552,8 @@ proc makewindow {} {
        {mc "Diff this -> selected" command {diffvssel 0}}
        {mc "Diff selected -> this" command {diffvssel 1}}
        {mc "Make patch" command mkpatch}
+       {mc "Diff this -> marked commit" command {diffvsmark 0}}
+       {mc "Diff marked commit -> this" command {diffvsmark 1}}
     }
     $fakerowmenu configure -tearoff 0
 
@@ -4630,8 +4685,9 @@ proc askfindhighlight {row id} {
     }
     set info $commitinfo($id)
     set isbold 0
-    set fldtypes [list [mc Headline] [mc Author] [mc Date] [mc Committer] [mc CDate] [mc Comments]]
+    set fldtypes [list [mc Headline] [mc Author] "" [mc Committer] "" [mc Comments]]
     foreach f $info ty $fldtypes {
+       if {$ty eq ""} continue
        if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
            [doesmatch $f]} {
            if {$ty eq [mc "Author"]} {
@@ -6492,7 +6548,7 @@ proc findmore {} {
     if {![info exists find_dirn]} {
        return 0
     }
-    set fldtypes [list [mc "Headline"] [mc "Author"] [mc "Date"] [mc "Committer"] [mc "CDate"] [mc "Comments"]]
+    set fldtypes [list [mc "Headline"] [mc "Author"] "" [mc "Committer"] "" [mc "Comments"]]
     set l $findcurline
     set moretodo 0
     if {$find_dirn > 0} {
@@ -6553,6 +6609,7 @@ proc findmore {} {
            }
            set info $commitinfo($id)
            foreach f $info ty $fldtypes {
+               if {$ty eq ""} continue
                if {($findloc eq [mc "All fields"] || $findloc eq $ty) &&
                    [doesmatch $f]} {
                    set found 1
@@ -6705,7 +6762,7 @@ proc appendwithlinks {text tags} {
 
     set start [$ctext index "end - 1c"]
     $ctext insert end $text $tags
-    set links [regexp -indices -all -inline {\m[0-9a-f]{6,40}\M} $text]
+    set links [regexp -indices -all -inline {(?:\m|-g)[0-9a-f]{6,40}\M} $text]
     foreach l $links {
        set s [lindex $l 0]
        set e [lindex $l 1]
@@ -6721,6 +6778,10 @@ proc appendwithlinks {text tags} {
 proc setlink {id lk} {
     global curview ctext pendinglinks
 
+    if {[string range $id 0 1] eq "-g"} {
+      set id [string range $id 2 end]
+    }
+
     set known 0
     if {[string length $id] < 40} {
        set matches [longid $id]
@@ -7393,19 +7454,15 @@ proc startdiff {ids} {
     }
 }
 
+# If the filename (name) is under any of the passed filter paths
+# then return true to include the file in the listing.
 proc path_filter {filter name} {
+    set worktree [gitworktree]
     foreach p $filter {
-       set l [string length $p]
-       if {[string index $p end] eq "/"} {
-           if {[string compare -length $l $p $name] == 0} {
-               return 1
-           }
-       } else {
-           if {[string compare -length $l $p $name] == 0 &&
-               ([string length $name] == $l ||
-                [string index $name $l] eq "/")} {
-               return 1
-           }
+       set fq_p [file normalize $p]
+       set fq_n [file normalize [file join $worktree $name]]
+       if {[string match [file normalize $fq_p]* $fq_n]} {
+           return 1
        }
     }
     return 0
@@ -7419,7 +7476,7 @@ proc addtocflist {ids} {
 }
 
 proc diffcmd {ids flags} {
-    global nullid nullid2
+    global log_showroot nullid nullid2
 
     set i [lsearch -exact $ids $nullid]
     set j [lsearch -exact $ids $nullid2]
@@ -7453,6 +7510,9 @@ proc diffcmd {ids flags} {
            lappend cmd HEAD
        }
     } else {
+       if {$log_showroot} {
+           lappend flags --root
+       }
        set cmd [concat | git diff-tree -r $flags $ids]
     }
     return $cmd
@@ -8442,6 +8502,11 @@ proc rowmenu {x y id} {
     } else {
        set state normal
     }
+    if {[info exists markedid] && $markedid ne $id} {
+       set mstate normal
+    } else {
+       set mstate disabled
+    }
     if {$id ne $nullid && $id ne $nullid2} {
        set menu $rowctxmenu
        if {$mainhead ne {}} {
@@ -8449,21 +8514,17 @@ proc rowmenu {x y id} {
        } else {
            $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled
        }
-       if {[info exists markedid] && $markedid ne $id} {
-           $menu entryconfigure 9 -state normal
-           $menu entryconfigure 10 -state normal
-           $menu entryconfigure 11 -state normal
-       } else {
-           $menu entryconfigure 9 -state disabled
-           $menu entryconfigure 10 -state disabled
-           $menu entryconfigure 11 -state disabled
-       }
+       $menu entryconfigure 9 -state $mstate
+       $menu entryconfigure 10 -state $mstate
+       $menu entryconfigure 11 -state $mstate
     } else {
        set menu $fakerowmenu
     }
     $menu entryconfigure [mca "Diff this -> selected"] -state $state
     $menu entryconfigure [mca "Diff selected -> this"] -state $state
     $menu entryconfigure [mca "Make patch"] -state $state
+    $menu entryconfigure [mca "Diff this -> marked commit"] -state $mstate
+    $menu entryconfigure [mca "Diff marked commit -> this"] -state $mstate
     tk_popup $menu $x $y
 }
 
@@ -8667,6 +8728,21 @@ proc diffvssel {dirn} {
     doseldiff $oldid $newid
 }
 
+proc diffvsmark {dirn} {
+    global rowmenuid markedid
+
+    if {![info exists markedid]} return
+    if {$dirn} {
+       set oldid $markedid
+       set newid $rowmenuid
+    } else {
+       set oldid $rowmenuid
+       set newid $markedid
+    }
+    addtohistory [list doseldiff $oldid $newid] savectextpos
+    doseldiff $oldid $newid
+}
+
 proc doseldiff {oldid newid} {
     global ctext
     global commitinfo
@@ -10719,7 +10795,7 @@ proc fontok {} {
     if {$fontparam(slant) eq "italic"} {
        lappend fontpref($f) "italic"
     }
-    set w $prefstop.$f
+    set w $prefstop.notebook.fonts.$f
     $w conf -text $fontparam(family) -font $fontpref($f)
 
     fontcan
@@ -10773,6 +10849,139 @@ proc chg_fontparam {v sub op} {
     font config sample -$sub $fontparam($sub)
 }
 
+# Create a property sheet tab page
+proc create_prefs_page {w} {
+    global NS
+    set parent [join [lrange [split $w .] 0 end-1] .]
+    if {[winfo class $parent] eq "TNotebook"} {
+       ${NS}::frame $w
+    } else {
+       ${NS}::labelframe $w
+    }
+}
+
+proc prefspage_general {notebook} {
+    global NS maxwidth maxgraphpct showneartags showlocalchanges
+    global tabstop limitdiffs autoselect autosellen extdifftool perfile_attrs
+    global hideremotes want_ttk have_ttk
+
+    set page [create_prefs_page $notebook.general]
+
+    ${NS}::label $page.ldisp -text [mc "Commit list display options"]
+    grid $page.ldisp - -sticky w -pady 10
+    ${NS}::label $page.spacer -text " "
+    ${NS}::label $page.maxwidthl -text [mc "Maximum graph width (lines)"]
+    spinbox $page.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
+    grid $page.spacer $page.maxwidthl $page.maxwidth -sticky w
+    ${NS}::label $page.maxpctl -text [mc "Maximum graph width (% of pane)"]
+    spinbox $page.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
+    grid x $page.maxpctl $page.maxpct -sticky w
+    ${NS}::checkbutton $page.showlocal -text [mc "Show local changes"] \
+       -variable showlocalchanges
+    grid x $page.showlocal -sticky w
+    ${NS}::checkbutton $page.autoselect -text [mc "Auto-select SHA1 (length)"] \
+       -variable autoselect
+    spinbox $page.autosellen -from 1 -to 40 -width 4 -textvariable autosellen
+    grid x $page.autoselect $page.autosellen -sticky w
+    ${NS}::checkbutton $page.hideremotes -text [mc "Hide remote refs"] \
+       -variable hideremotes
+    grid x $page.hideremotes -sticky w
+
+    ${NS}::label $page.ddisp -text [mc "Diff display options"]
+    grid $page.ddisp - -sticky w -pady 10
+    ${NS}::label $page.tabstopl -text [mc "Tab spacing"]
+    spinbox $page.tabstop -from 1 -to 20 -width 4 -textvariable tabstop
+    grid x $page.tabstopl $page.tabstop -sticky w
+    ${NS}::checkbutton $page.ntag -text [mc "Display nearby tags"] \
+       -variable showneartags
+    grid x $page.ntag -sticky w
+    ${NS}::checkbutton $page.ldiff -text [mc "Limit diffs to listed paths"] \
+       -variable limitdiffs
+    grid x $page.ldiff -sticky w
+    ${NS}::checkbutton $page.lattr -text [mc "Support per-file encodings"] \
+       -variable perfile_attrs
+    grid x $page.lattr -sticky w
+
+    ${NS}::entry $page.extdifft -textvariable extdifftool
+    ${NS}::frame $page.extdifff
+    ${NS}::label $page.extdifff.l -text [mc "External diff tool" ]
+    ${NS}::button $page.extdifff.b -text [mc "Choose..."] -command choose_extdiff
+    pack $page.extdifff.l $page.extdifff.b -side left
+    pack configure $page.extdifff.l -padx 10
+    grid x $page.extdifff $page.extdifft -sticky ew
+
+    ${NS}::label $page.lgen -text [mc "General options"]
+    grid $page.lgen - -sticky w -pady 10
+    ${NS}::checkbutton $page.want_ttk -variable want_ttk \
+       -text [mc "Use themed widgets"]
+    if {$have_ttk} {
+       ${NS}::label $page.ttk_note -text [mc "(change requires restart)"]
+    } else {
+       ${NS}::label $page.ttk_note -text [mc "(currently unavailable)"]
+    }
+    grid x $page.want_ttk $page.ttk_note -sticky w
+    return $page
+}
+
+proc prefspage_colors {notebook} {
+    global NS uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor
+
+    set page [create_prefs_page $notebook.colors]
+
+    ${NS}::label $page.cdisp -text [mc "Colors: press to choose"]
+    grid $page.cdisp - -sticky w -pady 10
+    label $page.ui -padx 40 -relief sunk -background $uicolor
+    ${NS}::button $page.uibut -text [mc "Interface"] \
+       -command [list choosecolor uicolor {} $page.ui [mc "interface"] setui]
+    grid x $page.uibut $page.ui -sticky w
+    label $page.bg -padx 40 -relief sunk -background $bgcolor
+    ${NS}::button $page.bgbut -text [mc "Background"] \
+       -command [list choosecolor bgcolor {} $page.bg [mc "background"] setbg]
+    grid x $page.bgbut $page.bg -sticky w
+    label $page.fg -padx 40 -relief sunk -background $fgcolor
+    ${NS}::button $page.fgbut -text [mc "Foreground"] \
+       -command [list choosecolor fgcolor {} $page.fg [mc "foreground"] setfg]
+    grid x $page.fgbut $page.fg -sticky w
+    label $page.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
+    ${NS}::button $page.diffoldbut -text [mc "Diff: old lines"] \
+       -command [list choosecolor diffcolors 0 $page.diffold [mc "diff old lines"] \
+                     [list $ctext tag conf d0 -foreground]]
+    grid x $page.diffoldbut $page.diffold -sticky w
+    label $page.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
+    ${NS}::button $page.diffnewbut -text [mc "Diff: new lines"] \
+       -command [list choosecolor diffcolors 1 $page.diffnew [mc "diff new lines"] \
+                     [list $ctext tag conf dresult -foreground]]
+    grid x $page.diffnewbut $page.diffnew -sticky w
+    label $page.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
+    ${NS}::button $page.hunksepbut -text [mc "Diff: hunk header"] \
+       -command [list choosecolor diffcolors 2 $page.hunksep \
+                     [mc "diff hunk header"] \
+                     [list $ctext tag conf hunksep -foreground]]
+    grid x $page.hunksepbut $page.hunksep -sticky w
+    label $page.markbgsep -padx 40 -relief sunk -background $markbgcolor
+    ${NS}::button $page.markbgbut -text [mc "Marked line bg"] \
+       -command [list choosecolor markbgcolor {} $page.markbgsep \
+                     [mc "marked line background"] \
+                     [list $ctext tag conf omark -background]]
+    grid x $page.markbgbut $page.markbgsep -sticky w
+    label $page.selbgsep -padx 40 -relief sunk -background $selectbgcolor
+    ${NS}::button $page.selbgbut -text [mc "Select bg"] \
+       -command [list choosecolor selectbgcolor {} $page.selbgsep [mc "background"] setselbg]
+    grid x $page.selbgbut $page.selbgsep -sticky w
+    return $page
+}
+
+proc prefspage_fonts {notebook} {
+    global NS
+    set page [create_prefs_page $notebook.fonts]
+    ${NS}::label $page.cfont -text [mc "Fonts: press to choose"]
+    grid $page.cfont - -sticky w -pady 10
+    mkfontdisp mainfont $page [mc "Main font"]
+    mkfontdisp textfont $page [mc "Diff display font"]
+    mkfontdisp uifont $page [mc "User interface font"]
+    return $page
+}
+
 proc doprefs {} {
     global maxwidth maxgraphpct use_ttk NS
     global oldprefs prefstop showneartags showlocalchanges
@@ -10793,106 +11002,38 @@ proc doprefs {} {
     ttk_toplevel $top
     wm title $top [mc "Gitk preferences"]
     make_transient $top .
-    ${NS}::label $top.ldisp -text [mc "Commit list display options"]
-    grid $top.ldisp - -sticky w -pady 10
-    ${NS}::label $top.spacer -text " "
-    ${NS}::label $top.maxwidthl -text [mc "Maximum graph width (lines)"]
-    spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth
-    grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w
-    ${NS}::label $top.maxpctl -text [mc "Maximum graph width (% of pane)"]
-    spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
-    grid x $top.maxpctl $top.maxpct -sticky w
-    ${NS}::checkbutton $top.showlocal -text [mc "Show local changes"] \
-       -variable showlocalchanges
-    grid x $top.showlocal -sticky w
-    ${NS}::checkbutton $top.autoselect -text [mc "Auto-select SHA1 (length)"] \
-       -variable autoselect
-    spinbox $top.autosellen -from 1 -to 40 -width 4 -textvariable autosellen
-    grid x $top.autoselect $top.autosellen -sticky w
-    ${NS}::checkbutton $top.hideremotes -text [mc "Hide remote refs"] \
-       -variable hideremotes
-    grid x $top.hideremotes -sticky w
-
-    ${NS}::label $top.ddisp -text [mc "Diff display options"]
-    grid $top.ddisp - -sticky w -pady 10
-    ${NS}::label $top.tabstopl -text [mc "Tab spacing"]
-    spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop
-    grid x $top.tabstopl $top.tabstop -sticky w
-    ${NS}::checkbutton $top.ntag -text [mc "Display nearby tags"] \
-       -variable showneartags
-    grid x $top.ntag -sticky w
-    ${NS}::checkbutton $top.ldiff -text [mc "Limit diffs to listed paths"] \
-       -variable limitdiffs
-    grid x $top.ldiff -sticky w
-    ${NS}::checkbutton $top.lattr -text [mc "Support per-file encodings"] \
-       -variable perfile_attrs
-    grid x $top.lattr -sticky w
-
-    ${NS}::entry $top.extdifft -textvariable extdifftool
-    ${NS}::frame $top.extdifff
-    ${NS}::label $top.extdifff.l -text [mc "External diff tool" ]
-    ${NS}::button $top.extdifff.b -text [mc "Choose..."] -command choose_extdiff
-    pack $top.extdifff.l $top.extdifff.b -side left
-    pack configure $top.extdifff.l -padx 10
-    grid x $top.extdifff $top.extdifft -sticky ew
-
-    ${NS}::label $top.lgen -text [mc "General options"]
-    grid $top.lgen - -sticky w -pady 10
-    ${NS}::checkbutton $top.want_ttk -variable want_ttk \
-       -text [mc "Use themed widgets"]
-    if {$have_ttk} {
-       ${NS}::label $top.ttk_note -text [mc "(change requires restart)"]
+
+    if {[set use_notebook [expr {$use_ttk && [info command ::ttk::notebook] ne ""}]]} {
+       set notebook [ttk::notebook $top.notebook]
     } else {
-       ${NS}::label $top.ttk_note -text [mc "(currently unavailable)"]
-    }
-    grid x $top.want_ttk $top.ttk_note -sticky w
-
-    ${NS}::label $top.cdisp -text [mc "Colors: press to choose"]
-    grid $top.cdisp - -sticky w -pady 10
-    label $top.ui -padx 40 -relief sunk -background $uicolor
-    ${NS}::button $top.uibut -text [mc "Interface"] \
-       -command [list choosecolor uicolor {} $top.ui [mc "interface"] setui]
-    grid x $top.uibut $top.ui -sticky w
-    label $top.bg -padx 40 -relief sunk -background $bgcolor
-    ${NS}::button $top.bgbut -text [mc "Background"] \
-       -command [list choosecolor bgcolor {} $top.bg [mc "background"] setbg]
-    grid x $top.bgbut $top.bg -sticky w
-    label $top.fg -padx 40 -relief sunk -background $fgcolor
-    ${NS}::button $top.fgbut -text [mc "Foreground"] \
-       -command [list choosecolor fgcolor {} $top.fg [mc "foreground"] setfg]
-    grid x $top.fgbut $top.fg -sticky w
-    label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0]
-    ${NS}::button $top.diffoldbut -text [mc "Diff: old lines"] \
-       -command [list choosecolor diffcolors 0 $top.diffold [mc "diff old lines"] \
-                     [list $ctext tag conf d0 -foreground]]
-    grid x $top.diffoldbut $top.diffold -sticky w
-    label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1]
-    ${NS}::button $top.diffnewbut -text [mc "Diff: new lines"] \
-       -command [list choosecolor diffcolors 1 $top.diffnew [mc "diff new lines"] \
-                     [list $ctext tag conf dresult -foreground]]
-    grid x $top.diffnewbut $top.diffnew -sticky w
-    label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2]
-    ${NS}::button $top.hunksepbut -text [mc "Diff: hunk header"] \
-       -command [list choosecolor diffcolors 2 $top.hunksep \
-                     [mc "diff hunk header"] \
-                     [list $ctext tag conf hunksep -foreground]]
-    grid x $top.hunksepbut $top.hunksep -sticky w
-    label $top.markbgsep -padx 40 -relief sunk -background $markbgcolor
-    ${NS}::button $top.markbgbut -text [mc "Marked line bg"] \
-       -command [list choosecolor markbgcolor {} $top.markbgsep \
-                     [mc "marked line background"] \
-                     [list $ctext tag conf omark -background]]
-    grid x $top.markbgbut $top.markbgsep -sticky w
-    label $top.selbgsep -padx 40 -relief sunk -background $selectbgcolor
-    ${NS}::button $top.selbgbut -text [mc "Select bg"] \
-       -command [list choosecolor selectbgcolor {} $top.selbgsep [mc "background"] setselbg]
-    grid x $top.selbgbut $top.selbgsep -sticky w
-
-    ${NS}::label $top.cfont -text [mc "Fonts: press to choose"]
-    grid $top.cfont - -sticky w -pady 10
-    mkfontdisp mainfont $top [mc "Main font"]
-    mkfontdisp textfont $top [mc "Diff display font"]
-    mkfontdisp uifont $top [mc "User interface font"]
+       set notebook [${NS}::frame $top.notebook -borderwidth 0 -relief flat]
+    }
+
+    lappend pages [prefspage_general $notebook] [mc "General"]
+    lappend pages [prefspage_colors $notebook] [mc "Colors"]
+    lappend pages [prefspage_fonts $notebook] [mc "Fonts"]
+    set col 0
+    foreach {page title} $pages {
+       if {$use_notebook} {
+           $notebook add $page -text $title
+       } else {
+           set btn [${NS}::button $notebook.b_[string map {. X} $page] \
+                        -text $title -command [list raise $page]]
+           $page configure -text $title
+           grid $btn -row 0 -column [incr col] -sticky w
+           grid $page -row 1 -column 0 -sticky news -columnspan 100
+       }
+    }
+
+    if {!$use_notebook} {
+       grid columnconfigure $notebook 0 -weight 1
+       grid rowconfigure $notebook 1 -weight 1
+       raise [lindex $pages 0]
+    }
+
+    grid $notebook -sticky news -padx 2 -pady 2
+    grid rowconfigure $top 0 -weight 1
+    grid columnconfigure $top 0 -weight 1
 
     ${NS}::frame $top.buts
     ${NS}::button $top.buts.ok -text [mc "OK"] -command prefsok -default active
@@ -10904,7 +11045,7 @@ proc doprefs {} {
     grid columnconfigure $top.buts 1 -weight 1 -uniform a
     grid $top.buts - - -pady 10 -sticky ew
     grid columnconfigure $top 2 -weight 1
-    bind $top <Visibility> "focus $top.buts.ok"
+    bind $top <Visibility> [list focus $top.buts.ok]
 }
 
 proc choose_extdiff {} {
@@ -11422,10 +11563,20 @@ catch {
     }
 }
 
+set log_showroot true
+catch {
+    set log_showroot [exec git config --bool --get log.showroot]
+}
+
 if {[tk windowingsystem] eq "aqua"} {
     set mainfont {{Lucida Grande} 9}
     set textfont {Monaco 9}
     set uifont {{Lucida Grande} 9 bold}
+} elseif {![catch {::tk::pkgconfig get fontsystem} xft] && $xft eq "xft"} {
+    # fontconfig!
+    set mainfont {sans 9}
+    set textfont {monospace 9}
+    set uifont {sans 9 bold}
 } else {
     set mainfont {Helvetica 9}
     set textfont {Courier 9}
@@ -11607,6 +11758,8 @@ if {[package vcompare $git_version "1.6.6.2"] >= 0} {
     set show_notes "--show-notes"
 }
 
+set appname "gitk"
+
 set runq {}
 set history {}
 set historyindex 0
@@ -11676,7 +11829,7 @@ catch {
 }
 # wait for the window to become visible
 tkwait visibility .
-wm title . "[file tail $argv0]: [file tail [pwd]]"
+wm title . "$appname: [reponame]"
 update
 readrefs
 
index a8b5fad26631207fcc17a6339ba735877c0902bd..ca6f038c946c9a075ec866cc4a6de240481537e6 100755 (executable)
@@ -3886,6 +3886,7 @@ sub print_feed_meta {
                                '-type' => "application/$type+xml"
                        );
 
+                       $href_params{'extra_options'} = undef;
                        $href_params{'action'} = $type;
                        $link_attr{'-href'} = href(%href_params);
                        print "<link ".
index 72b51cd1b4c9ad63d9f8622d253aae51f81cb04d..66b9a072a4a382b2b0e58e2b726d5f4b8dc7b67c 100644 (file)
@@ -30,7 +30,7 @@
  *                            If a negative value is specified or a date in the past),
  *                            the cookie will be deleted.
  *                            If set to null or omitted, the cookie will be a session cookie
- *                            and will not be retained when the the browser exits.
+ *                            and will not be retained when the browser exits.
  * @param {String} [options.path] Restrict access of a cookie to particular directory
  *                               (default: path of page that created the cookie).
  * @param {String} [options.domain] Override what web sites are allowed to access cookie
diff --git a/http.c b/http.c
index 8ac8eb6c38e21bdb347f59ec41162270ebe82c04..f3f83d70cd2e13a774d208206af20181dd39d8af 100644 (file)
--- a/http.c
+++ b/http.c
@@ -829,7 +829,7 @@ int http_get_strbuf(const char *url, struct strbuf *result, int options)
 }
 
 /*
- * Downloads an url and stores the result in the given file.
+ * Downloads a URL and stores the result in the given file.
  *
  * If a previous interrupted download is detected (i.e. a previous temporary
  * file is still around) the download is resumed.
diff --git a/http.h b/http.h
index 0b61653894eff606980427ee26770fa088438b94..915c2862a65bdbf42472099f9ed53ca68c2ccfd9 100644 (file)
--- a/http.h
+++ b/http.h
@@ -127,7 +127,7 @@ extern char *get_remote_object_url(const char *url, const char *hex,
 #define HTTP_NOAUTH    5
 
 /*
- * Requests an url and stores the result in a strbuf.
+ * Requests a URL and stores the result in a strbuf.
  *
  * If the result pointer is NULL, a HTTP HEAD request is made instead of GET.
  */
diff --git a/ident.c b/ident.c
index f619619b82379c2d205c7d7ea101049e373ab90a..87c697c2b09692ec8a36d557aa0c73de38223492 100644 (file)
--- a/ident.c
+++ b/ident.c
@@ -220,6 +220,74 @@ static int copy(char *buf, size_t size, int offset, const char *src)
        return offset;
 }
 
+/*
+ * Reverse of fmt_ident(); given an ident line, split the fields
+ * to allow the caller to parse it.
+ * Signal a success by returning 0, but date/tz fields of the result
+ * can still be NULL if the input line only has the name/email part
+ * (e.g. reading from a reflog entry).
+ */
+int split_ident_line(struct ident_split *split, const char *line, int len)
+{
+       const char *cp;
+       size_t span;
+       int status = -1;
+
+       memset(split, 0, sizeof(*split));
+
+       split->name_begin = line;
+       for (cp = line; *cp && cp < line + len; cp++)
+               if (*cp == '<') {
+                       split->mail_begin = cp + 1;
+                       break;
+               }
+       if (!split->mail_begin)
+               return status;
+
+       for (cp = split->mail_begin - 2; line < cp; cp--)
+               if (!isspace(*cp)) {
+                       split->name_end = cp + 1;
+                       break;
+               }
+       if (!split->name_end)
+               return status;
+
+       for (cp = split->mail_begin; cp < line + len; cp++)
+               if (*cp == '>') {
+                       split->mail_end = cp;
+                       break;
+               }
+       if (!split->mail_end)
+               return status;
+
+       for (cp = split->mail_end + 1; cp < line + len && isspace(*cp); cp++)
+               ;
+       if (line + len <= cp)
+               goto person_only;
+       split->date_begin = cp;
+       span = strspn(cp, "0123456789");
+       if (!span)
+               goto person_only;
+       split->date_end = split->date_begin + span;
+       for (cp = split->date_end; cp < line + len && isspace(*cp); cp++)
+               ;
+       if (line + len <= cp || (*cp != '+' && *cp != '-'))
+               goto person_only;
+       split->tz_begin = cp;
+       span = strspn(cp + 1, "0123456789");
+       if (!span)
+               goto person_only;
+       split->tz_end = split->tz_begin + 1 + span;
+       return 0;
+
+person_only:
+       split->date_begin = NULL;
+       split->date_end = NULL;
+       split->tz_begin = NULL;
+       split->tz_end = NULL;
+       return 0;
+}
+
 static const char *env_hint =
 "\n"
 "*** Please tell me who you are.\n"
index 6479a60cd112c5b06b354b1a251c60bb4bce972a..857f03dc6112ed5bce6b77b7da9535330ea29015 100644 (file)
@@ -2068,9 +2068,9 @@ int parse_merge_opt(struct merge_options *o, const char *s)
        else if (!prefixcmp(s, "subtree="))
                o->subtree_shift = s + strlen("subtree=");
        else if (!strcmp(s, "patience"))
-               o->xdl_opts |= XDF_PATIENCE_DIFF;
+               o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF);
        else if (!strcmp(s, "histogram"))
-               o->xdl_opts |= XDF_HISTOGRAM_DIFF;
+               o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF);
        else if (!strcmp(s, "ignore-space-change"))
                o->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
        else if (!strcmp(s, "ignore-all-space"))
index fb0832f97d218ecd1812361721800d6288935c06..74aa77ce4be2bf23387a32e42cbdc72154c529c2 100644 (file)
@@ -267,7 +267,8 @@ static void check_notes_merge_worktree(struct notes_merge_options *o)
                 * Must establish NOTES_MERGE_WORKTREE.
                 * Abort if NOTES_MERGE_WORKTREE already exists
                 */
-               if (file_exists(git_path(NOTES_MERGE_WORKTREE))) {
+               if (file_exists(git_path(NOTES_MERGE_WORKTREE)) &&
+                   !is_empty_dir(git_path(NOTES_MERGE_WORKTREE))) {
                        if (advice_resolve_conflict)
                                die("You have not concluded your previous "
                                    "notes merge (%s exists).\nPlease, use "
@@ -687,51 +688,60 @@ int notes_merge_commit(struct notes_merge_options *o,
 {
        /*
         * Iterate through files in .git/NOTES_MERGE_WORKTREE and add all
-        * found notes to 'partial_tree'. Write the updates notes tree to
+        * found notes to 'partial_tree'. Write the updated notes tree to
         * the DB, and commit the resulting tree object while reusing the
         * commit message and parents from 'partial_commit'.
         * Finally store the new commit object SHA1 into 'result_sha1'.
         */
-       struct dir_struct dir;
-       char *path = xstrdup(git_path(NOTES_MERGE_WORKTREE "/"));
-       int path_len = strlen(path), i;
+       DIR *dir;
+       struct dirent *e;
+       struct strbuf path = STRBUF_INIT;
        char *msg = strstr(partial_commit->buffer, "\n\n");
        struct strbuf sb_msg = STRBUF_INIT;
+       int baselen;
 
+       strbuf_addstr(&path, git_path(NOTES_MERGE_WORKTREE));
        if (o->verbosity >= 3)
-               printf("Committing notes in notes merge worktree at %.*s\n",
-                       path_len - 1, path);
+               printf("Committing notes in notes merge worktree at %s\n",
+                       path.buf);
 
        if (!msg || msg[2] == '\0')
                die("partial notes commit has empty message");
        msg += 2;
 
-       memset(&dir, 0, sizeof(dir));
-       read_directory(&dir, path, path_len, NULL);
-       for (i = 0; i < dir.nr; i++) {
-               struct dir_entry *ent = dir.entries[i];
+       dir = opendir(path.buf);
+       if (!dir)
+               die_errno("could not open %s", path.buf);
+
+       strbuf_addch(&path, '/');
+       baselen = path.len;
+       while ((e = readdir(dir)) != NULL) {
                struct stat st;
-               const char *relpath = ent->name + path_len;
                unsigned char obj_sha1[20], blob_sha1[20];
 
-               if (ent->len - path_len != 40 || get_sha1_hex(relpath, obj_sha1)) {
+               if (is_dot_or_dotdot(e->d_name))
+                       continue;
+
+               if (strlen(e->d_name) != 40 || get_sha1_hex(e->d_name, obj_sha1)) {
                        if (o->verbosity >= 3)
-                               printf("Skipping non-SHA1 entry '%s'\n",
-                                                               ent->name);
+                               printf("Skipping non-SHA1 entry '%s%s'\n",
+                                       path.buf, e->d_name);
                        continue;
                }
 
+               strbuf_addstr(&path, e->d_name);
                /* write file as blob, and add to partial_tree */
-               if (stat(ent->name, &st))
-                       die_errno("Failed to stat '%s'", ent->name);
-               if (index_path(blob_sha1, ent->name, &st, HASH_WRITE_OBJECT))
-                       die("Failed to write blob object from '%s'", ent->name);
+               if (stat(path.buf, &st))
+                       die_errno("Failed to stat '%s'", path.buf);
+               if (index_path(blob_sha1, path.buf, &st, HASH_WRITE_OBJECT))
+                       die("Failed to write blob object from '%s'", path.buf);
                if (add_note(partial_tree, obj_sha1, blob_sha1, NULL))
                        die("Failed to add resolved note '%s' to notes tree",
-                           ent->name);
+                           path.buf);
                if (o->verbosity >= 4)
                        printf("Added resolved note for object %s: %s\n",
                                sha1_to_hex(obj_sha1), sha1_to_hex(blob_sha1));
+               strbuf_setlen(&path, baselen);
        }
 
        strbuf_attach(&sb_msg, msg, strlen(msg), strlen(msg) + 1);
@@ -740,20 +750,25 @@ int notes_merge_commit(struct notes_merge_options *o,
        if (o->verbosity >= 4)
                printf("Finalized notes merge commit: %s\n",
                        sha1_to_hex(result_sha1));
-       free(path);
+       strbuf_release(&path);
+       closedir(dir);
        return 0;
 }
 
 int notes_merge_abort(struct notes_merge_options *o)
 {
-       /* Remove .git/NOTES_MERGE_WORKTREE directory and all files within */
+       /*
+        * Remove all files within .git/NOTES_MERGE_WORKTREE. We do not remove
+        * the .git/NOTES_MERGE_WORKTREE directory itself, since it might be
+        * the current working directory of the user.
+        */
        struct strbuf buf = STRBUF_INIT;
        int ret;
 
        strbuf_addstr(&buf, git_path(NOTES_MERGE_WORKTREE));
        if (o->verbosity >= 3)
-               printf("Removing notes merge worktree at %s\n", buf.buf);
-       ret = remove_dir_recursively(&buf, 0);
+               printf("Removing notes merge worktree at %s/*\n", buf.buf);
+       ret = remove_dir_recursively(&buf, REMOVE_DIR_KEEP_TOPLEVEL);
        strbuf_release(&buf);
        return ret;
 }
index 6b06297a5f06cc35cb266d6dd36c92df75a82de7..0498b18d451b2335d21e2db3edc0ce7838aaa50e 100644 (file)
--- a/object.c
+++ b/object.c
@@ -198,6 +198,17 @@ struct object *parse_object(const unsigned char *sha1)
        if (obj && obj->parsed)
                return obj;
 
+       if ((obj && obj->type == OBJ_BLOB) ||
+           (!obj && has_sha1_file(sha1) &&
+            sha1_object_info(sha1, NULL) == OBJ_BLOB)) {
+               if (check_sha1_signature(repl, NULL, 0, NULL) < 0) {
+                       error("sha1 mismatch %s\n", sha1_to_hex(repl));
+                       return NULL;
+               }
+               parse_blob_buffer(lookup_blob(sha1), NULL, 0);
+               return lookup_object(sha1);
+       }
+
        buffer = read_sha1_file(sha1, &type, &size);
        if (buffer) {
                if (check_sha1_signature(repl, buffer, size, typename(type)) < 0) {
index f7ce511bbbfbff5a479200f2814ad87b96f16791..497f420178a73061901393f8c21a9feb17054b6d 100644 (file)
@@ -691,7 +691,7 @@ The hash is in the format C<refname =\> hash>. For tags, the C<refname> entry
 contains the tag object while a C<refname^{}> entry gives the tagged objects.
 
 C<REPOSITORY> has the same meaning as the appropriate C<git-ls-remote>
-argument; either an URL or a remote name (if called on a repository instance).
+argument; either a URL or a remote name (if called on a repository instance).
 C<GROUPS> is an optional arrayref that can contain 'tags' to return all the
 tags and/or 'heads' to return all the heads. C<REFGLOB> is an optional array
 of strings containing a shell-like glob to further limit the refs returned in
index 188ea2c25497e3b6acdaadf8d442b9b99c715506..c1520e8cdeaf5ab5c52d2ae057582cd8f32b7fe6 100644 (file)
--- a/po/README
+++ b/po/README
@@ -178,7 +178,7 @@ used:
 
 C:
 
- - Include builtin.h at the top, it'll pull in in gettext.h, which
+ - Include builtin.h at the top, it'll pull in gettext.h, which
    defines the gettext interface. Consult with the list if you need to
    use gettext.h directly.
 
index 0184493f21913e30c6fa771bedc79c963164af96..7fcf1ec119e52a131ec873b1c3348fb0472fa1ef 100644 (file)
--- a/po/TEAMS
+++ b/po/TEAMS
@@ -4,7 +4,16 @@ Core Git translation language teams
 Language:      is (Icelandic)
 Leader:                Ævar Arnfjörð Bjarmason <avarab@gmail.com>
 
+Language:      nl (Dutch)
+Repository:    https://github.com/vfr-nl/git-po/
+Leader:                Vincent van Ravesteijn <vfr@lyx.org>
+
+Language:      pt_PT (Portuguese - Portugal)
+Repository:    https://github.com/marcomsousa/git-l10n-pt_PT/
+Leader:                Marco Sousa <marcomsousa AT gmail.com>
+
 Language:      sv (Swedish)
+Repository:    https://github.com/nafmo/git-l10n-sv/
 Leader:                Peter Krefting <peter@softwolves.pp.se>
 
 Language:      zh_CN (Simplified Chinese)
index 8bdaf3cc34a9fb2d494b64cb70218e7fb650738e..566c7fdda64a21178ed364f24199f67eaf3bf8ff 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-03-08 10:19+0800\n"
+"POT-Creation-Date: 2012-03-16 20:18+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -3071,49 +3071,49 @@ msgstr ""
 msgid "Patch format detection failed."
 msgstr ""
 
-#: git-am.sh:409
+#: git-am.sh:411
 msgid "-d option is no longer supported.  Do not use."
 msgstr ""
 
-#: git-am.sh:472
+#: git-am.sh:474
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
 msgstr ""
 
-#: git-am.sh:477
+#: git-am.sh:479
 msgid "Please make up your mind. --skip or --abort?"
 msgstr ""
 
-#: git-am.sh:504
+#: git-am.sh:506
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr ""
 
-#: git-am.sh:570
+#: git-am.sh:572
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
 msgstr ""
 
-#: git-am.sh:746
+#: git-am.sh:748
 msgid "cannot be interactive without stdin connected to a terminal."
 msgstr ""
 
 #. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
 #. in your translation. The program will only accept English
 #. input at this point.
-#: git-am.sh:757
+#: git-am.sh:759
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr ""
 
-#: git-am.sh:793
+#: git-am.sh:795
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr ""
 
-#: git-am.sh:838
+#: git-am.sh:840
 msgid "No changes -- Patch already applied."
 msgstr ""
 
-#: git-am.sh:864
+#: git-am.sh:866
 msgid "applying to an empty history"
 msgstr ""
 
@@ -3350,11 +3350,16 @@ msgstr ""
 msgid "No submodule mapping found in .gitmodules for path '$path'"
 msgstr ""
 
-#: git-submodule.sh:173
+#: git-submodule.sh:149
 #, sh-format
 msgid "Clone of '$url' into submodule path '$path' failed"
 msgstr ""
 
+#: git-submodule.sh:159
+#, sh-format
+msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
+msgstr ""
+
 #: git-submodule.sh:247
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
diff --git a/po/nl.po b/po/nl.po
new file mode 100644 (file)
index 0000000..e1399e2
--- /dev/null
+++ b/po/nl.po
@@ -0,0 +1,3493 @@
+# Dutch translations for Git.
+# Copyright (C) 2012 Vincent van Ravesteijn <vfr@lyx.org>
+# This file is distributed under the same license as the Git package.
+# Vincent van Ravesteijn <vfr@lyx.org>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Git\n"
+"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
+"POT-Creation-Date: 2012-02-28 09:17+0800\n"
+"PO-Revision-Date: 2012-03-07 12:02+0100\n"
+"Last-Translator: Vincent van Ravesteijn <vfr@lyx.org>\n"
+"Language-Team: Dutch\n"
+"Language: nl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ASCII\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: advice.c:34
+#, c-format
+msgid "hint: %.*s\n"
+msgstr ""
+
+#.
+#. * Message used both when 'git commit' fails and when
+#. * other commands doing a merge do.
+#.
+#: advice.c:64
+msgid ""
+"Fix them up in the work tree,\n"
+"and then use 'git add/rm <file>' as\n"
+"appropriate to mark resolution and make a commit,\n"
+"or use 'git commit -a'."
+msgstr ""
+
+#: commit.c:47
+#, c-format
+msgid "could not parse %s"
+msgstr ""
+
+#: commit.c:49
+#, c-format
+msgid "%s %s is not a commit!"
+msgstr ""
+
+#: compat/obstack.c:406 compat/obstack.c:408
+msgid "memory exhausted"
+msgstr ""
+
+#: connected.c:39
+msgid "Could not run 'git rev-list'"
+msgstr ""
+
+#: connected.c:48
+#, c-format
+msgid "failed write to rev-list: %s"
+msgstr ""
+
+#: connected.c:56
+#, c-format
+msgid "failed to close rev-list's stdin: %s"
+msgstr ""
+
+#: diff.c:104
+#, c-format
+msgid "  Failed to parse dirstat cut-off percentage '%.*s'\n"
+msgstr ""
+
+#: diff.c:109
+#, c-format
+msgid "  Unknown dirstat parameter '%.*s'\n"
+msgstr ""
+
+#: diff.c:205
+#, c-format
+msgid ""
+"Found errors in 'diff.dirstat' config variable:\n"
+"%s"
+msgstr ""
+
+#: diff.c:1331
+msgid " 0 files changed\n"
+msgstr ""
+
+#: diff.c:1335
+#, c-format
+msgid " %d file changed"
+msgid_plural " %d files changed"
+msgstr[0] ""
+msgstr[1] ""
+
+#: diff.c:1352
+#, c-format
+msgid ", %d insertion(+)"
+msgid_plural ", %d insertions(+)"
+msgstr[0] ""
+msgstr[1] ""
+
+#: diff.c:1363
+#, c-format
+msgid ", %d deletion(-)"
+msgid_plural ", %d deletions(-)"
+msgstr[0] ""
+msgstr[1] ""
+
+#: diff.c:3364
+#, c-format
+msgid ""
+"Failed to parse --dirstat/-X option parameter:\n"
+"%s"
+msgstr ""
+
+#: gpg-interface.c:59
+msgid "could not run gpg."
+msgstr ""
+
+#: gpg-interface.c:71
+msgid "gpg did not accept the data"
+msgstr ""
+
+#: gpg-interface.c:82
+msgid "gpg failed to sign the data"
+msgstr ""
+
+#: grep.c:1285
+#, c-format
+msgid "'%s': unable to read %s"
+msgstr ""
+
+#: grep.c:1302
+#, c-format
+msgid "'%s': %s"
+msgstr ""
+
+#: grep.c:1313
+#, c-format
+msgid "'%s': short read %s"
+msgstr ""
+
+#: help.c:287
+#, c-format
+msgid ""
+"'%s' appears to be a git command, but we were not\n"
+"able to execute it. Maybe git-%s is broken?"
+msgstr ""
+
+#: remote.c:1607
+#, c-format
+msgid "Your branch is ahead of '%s' by %d commit.\n"
+msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: remote.c:1613
+#, c-format
+msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
+msgid_plural ""
+"Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: remote.c:1621
+#, c-format
+msgid ""
+"Your branch and '%s' have diverged,\n"
+"and have %d and %d different commit each, respectively.\n"
+msgid_plural ""
+"Your branch and '%s' have diverged,\n"
+"and have %d and %d different commits each, respectively.\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: sequencer.c:120 builtin/merge.c:862 builtin/merge.c:983
+#: builtin/merge.c:1093 builtin/merge.c:1103
+#, c-format
+msgid "Could not open '%s' for writing"
+msgstr ""
+
+#: sequencer.c:122 builtin/merge.c:334 builtin/merge.c:865
+#: builtin/merge.c:1095 builtin/merge.c:1108
+#, c-format
+msgid "Could not write to '%s'"
+msgstr ""
+
+#: sequencer.c:142
+msgid ""
+"after resolving the conflicts, mark the corrected paths\n"
+"with 'git add <paths>' or 'git rm <paths>'\n"
+"and commit the result with 'git commit'"
+msgstr ""
+
+#: sequencer.c:154 sequencer.c:680 sequencer.c:763
+#, c-format
+msgid "Could not write to %s"
+msgstr ""
+
+#: sequencer.c:157
+#, c-format
+msgid "Error wrapping up %s"
+msgstr ""
+
+#: sequencer.c:172
+msgid "Your local changes would be overwritten by cherry-pick."
+msgstr ""
+
+#: sequencer.c:174
+msgid "Your local changes would be overwritten by revert."
+msgstr ""
+
+#: sequencer.c:177
+msgid "Commit your changes or stash them to proceed."
+msgstr ""
+
+#. TRANSLATORS: %s will be "revert" or "cherry-pick"
+#: sequencer.c:227
+#, c-format
+msgid "%s: Unable to write new index file"
+msgstr ""
+
+#: sequencer.c:293
+msgid "Your index file is unmerged."
+msgstr ""
+
+#: sequencer.c:296
+msgid "You do not have a valid HEAD"
+msgstr ""
+
+#: sequencer.c:311
+#, c-format
+msgid "Commit %s is a merge but no -m option was given."
+msgstr ""
+
+#: sequencer.c:319
+#, c-format
+msgid "Commit %s does not have parent %d"
+msgstr ""
+
+#: sequencer.c:323
+#, c-format
+msgid "Mainline was specified but commit %s is not a merge."
+msgstr ""
+
+#. TRANSLATORS: The first %s will be "revert" or
+#. "cherry-pick", the second %s a SHA1
+#: sequencer.c:334
+#, c-format
+msgid "%s: cannot parse parent commit %s"
+msgstr ""
+
+#: sequencer.c:338
+#, c-format
+msgid "Cannot get commit message for %s"
+msgstr ""
+
+#: sequencer.c:422
+#, c-format
+msgid "could not revert %s... %s"
+msgstr ""
+
+#: sequencer.c:423
+#, c-format
+msgid "could not apply %s... %s"
+msgstr ""
+
+#: sequencer.c:445 sequencer.c:904 builtin/log.c:286 builtin/log.c:709
+#: builtin/log.c:1325 builtin/log.c:1544 builtin/merge.c:348
+#: builtin/shortlog.c:181
+msgid "revision walk setup failed"
+msgstr ""
+
+#: sequencer.c:448
+msgid "empty commit set passed"
+msgstr ""
+
+#: sequencer.c:456
+#, c-format
+msgid "git %s: failed to read the index"
+msgstr ""
+
+#: sequencer.c:461
+#, c-format
+msgid "git %s: failed to refresh the index"
+msgstr ""
+
+#: sequencer.c:546
+#, c-format
+msgid "Cannot %s during a %s"
+msgstr ""
+
+#: sequencer.c:568
+#, c-format
+msgid "Could not parse line %d."
+msgstr ""
+
+#: sequencer.c:573
+msgid "No commits parsed."
+msgstr ""
+
+#: sequencer.c:586
+#, c-format
+msgid "Could not open %s"
+msgstr ""
+
+#: sequencer.c:590
+#, c-format
+msgid "Could not read %s."
+msgstr ""
+
+#: sequencer.c:597
+#, c-format
+msgid "Unusable instruction sheet: %s"
+msgstr ""
+
+#: sequencer.c:625
+#, c-format
+msgid "Invalid key: %s"
+msgstr ""
+
+#: sequencer.c:628
+#, c-format
+msgid "Invalid value for %s: %s"
+msgstr ""
+
+#: sequencer.c:640
+#, c-format
+msgid "Malformed options sheet: %s"
+msgstr ""
+
+#: sequencer.c:661
+msgid "a cherry-pick or revert is already in progress"
+msgstr ""
+
+#: sequencer.c:662
+msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
+msgstr ""
+
+#: sequencer.c:666
+#, c-format
+msgid "Could not create sequencer directory %s"
+msgstr ""
+
+#: sequencer.c:682 sequencer.c:767
+#, c-format
+msgid "Error wrapping up %s."
+msgstr ""
+
+#: sequencer.c:701 sequencer.c:835
+msgid "no cherry-pick or revert in progress"
+msgstr ""
+
+#: sequencer.c:703
+msgid "cannot resolve HEAD"
+msgstr ""
+
+#: sequencer.c:705
+msgid "cannot abort from a branch yet to be born"
+msgstr ""
+
+#: sequencer.c:727
+#, c-format
+msgid "cannot open %s: %s"
+msgstr ""
+
+#: sequencer.c:730
+#, c-format
+msgid "cannot read %s: %s"
+msgstr ""
+
+#: sequencer.c:731
+msgid "unexpected end of file"
+msgstr ""
+
+#: sequencer.c:737
+#, c-format
+msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
+msgstr ""
+
+#: sequencer.c:760
+#, c-format
+msgid "Could not format %s."
+msgstr ""
+
+#: sequencer.c:922
+msgid "Can't revert as initial commit"
+msgstr ""
+
+#: sequencer.c:923
+msgid "Can't cherry-pick into empty head"
+msgstr ""
+
+#: wt-status.c:134
+msgid "Unmerged paths:"
+msgstr ""
+
+#: wt-status.c:140 wt-status.c:157
+#, c-format
+msgid "  (use \"git reset %s <file>...\" to unstage)"
+msgstr ""
+
+#: wt-status.c:142 wt-status.c:159
+msgid "  (use \"git rm --cached <file>...\" to unstage)"
+msgstr ""
+
+#: wt-status.c:143
+msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
+msgstr ""
+
+#: wt-status.c:151
+msgid "Changes to be committed:"
+msgstr ""
+
+#: wt-status.c:169
+msgid "Changes not staged for commit:"
+msgstr ""
+
+#: wt-status.c:173
+msgid "  (use \"git add <file>...\" to update what will be committed)"
+msgstr ""
+
+#: wt-status.c:175
+msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
+msgstr ""
+
+#: wt-status.c:176
+msgid ""
+"  (use \"git checkout -- <file>...\" to discard changes in working directory)"
+msgstr ""
+
+#: wt-status.c:178
+msgid "  (commit or discard the untracked or modified content in submodules)"
+msgstr ""
+
+#: wt-status.c:187
+#, c-format
+msgid "%s files:"
+msgstr ""
+
+#: wt-status.c:190
+#, c-format
+msgid "  (use \"git %s <file>...\" to include in what will be committed)"
+msgstr ""
+
+#: wt-status.c:207
+msgid "bug"
+msgstr ""
+
+#: wt-status.c:212
+msgid "both deleted:"
+msgstr ""
+
+#: wt-status.c:213
+msgid "added by us:"
+msgstr ""
+
+#: wt-status.c:214
+msgid "deleted by them:"
+msgstr ""
+
+#: wt-status.c:215
+msgid "added by them:"
+msgstr ""
+
+#: wt-status.c:216
+msgid "deleted by us:"
+msgstr ""
+
+#: wt-status.c:217
+msgid "both added:"
+msgstr ""
+
+#: wt-status.c:218
+msgid "both modified:"
+msgstr ""
+
+#: wt-status.c:248
+msgid "new commits, "
+msgstr ""
+
+#: wt-status.c:250
+msgid "modified content, "
+msgstr ""
+
+#: wt-status.c:252
+msgid "untracked content, "
+msgstr ""
+
+#: wt-status.c:266
+#, c-format
+msgid "new file:   %s"
+msgstr ""
+
+#: wt-status.c:269
+#, c-format
+msgid "copied:     %s -> %s"
+msgstr ""
+
+#: wt-status.c:272
+#, c-format
+msgid "deleted:    %s"
+msgstr ""
+
+#: wt-status.c:275
+#, c-format
+msgid "modified:   %s"
+msgstr ""
+
+#: wt-status.c:278
+#, c-format
+msgid "renamed:    %s -> %s"
+msgstr ""
+
+#: wt-status.c:281
+#, c-format
+msgid "typechange: %s"
+msgstr ""
+
+#: wt-status.c:284
+#, c-format
+msgid "unknown:    %s"
+msgstr ""
+
+#: wt-status.c:287
+#, c-format
+msgid "unmerged:   %s"
+msgstr ""
+
+#: wt-status.c:290
+#, c-format
+msgid "bug: unhandled diff status %c"
+msgstr ""
+
+#: wt-status.c:713
+msgid "On branch "
+msgstr ""
+
+#: wt-status.c:720
+msgid "Not currently on any branch."
+msgstr ""
+
+#: wt-status.c:731
+msgid "Initial commit"
+msgstr ""
+
+#: wt-status.c:745
+msgid "Untracked"
+msgstr ""
+
+#: wt-status.c:747
+msgid "Ignored"
+msgstr ""
+
+#: wt-status.c:749
+#, c-format
+msgid "Untracked files not listed%s"
+msgstr ""
+
+#: wt-status.c:751
+msgid " (use -u option to show untracked files)"
+msgstr ""
+
+#: wt-status.c:757
+msgid "No changes"
+msgstr ""
+
+#: wt-status.c:761
+#, c-format
+msgid "no changes added to commit%s\n"
+msgstr ""
+
+#: wt-status.c:763
+msgid " (use \"git add\" and/or \"git commit -a\")"
+msgstr ""
+
+#: wt-status.c:765
+#, c-format
+msgid "nothing added to commit but untracked files present%s\n"
+msgstr ""
+
+#: wt-status.c:767
+msgid " (use \"git add\" to track)"
+msgstr ""
+
+#: wt-status.c:769 wt-status.c:772 wt-status.c:775
+#, c-format
+msgid "nothing to commit%s\n"
+msgstr ""
+
+#: wt-status.c:770
+msgid " (create/copy files and use \"git add\" to track)"
+msgstr ""
+
+#: wt-status.c:773
+msgid " (use -u to show untracked files)"
+msgstr ""
+
+#: wt-status.c:776
+msgid " (working directory clean)"
+msgstr ""
+
+#: wt-status.c:884
+msgid "HEAD (no branch)"
+msgstr ""
+
+#: wt-status.c:890
+msgid "Initial commit on "
+msgstr ""
+
+#: wt-status.c:905
+msgid "behind "
+msgstr ""
+
+#: wt-status.c:908 wt-status.c:911
+msgid "ahead "
+msgstr ""
+
+#: wt-status.c:913
+msgid ", behind "
+msgstr ""
+
+#: builtin/add.c:62
+#, c-format
+msgid "unexpected diff status %c"
+msgstr ""
+
+#: builtin/add.c:67 builtin/commit.c:298
+msgid "updating files failed"
+msgstr ""
+
+#: builtin/add.c:77
+#, c-format
+msgid "remove '%s'\n"
+msgstr ""
+
+#: builtin/add.c:176
+#, c-format
+msgid "Path '%s' is in submodule '%.*s'"
+msgstr ""
+
+#: builtin/add.c:192
+msgid "Unstaged changes after refreshing the index:"
+msgstr ""
+
+#: builtin/add.c:195 builtin/add.c:456 builtin/rm.c:186
+#, c-format
+msgid "pathspec '%s' did not match any files"
+msgstr ""
+
+#: builtin/add.c:209
+#, c-format
+msgid "'%s' is beyond a symbolic link"
+msgstr ""
+
+#: builtin/add.c:276
+msgid "Could not read the index"
+msgstr ""
+
+#: builtin/add.c:286
+#, c-format
+msgid "Could not open '%s' for writing."
+msgstr ""
+
+#: builtin/add.c:290
+msgid "Could not write patch"
+msgstr ""
+
+#: builtin/add.c:295
+#, c-format
+msgid "Could not stat '%s'"
+msgstr ""
+
+#: builtin/add.c:297
+msgid "Empty patch. Aborted."
+msgstr ""
+
+#: builtin/add.c:303
+#, c-format
+msgid "Could not apply '%s'"
+msgstr ""
+
+#: builtin/add.c:312
+msgid "The following paths are ignored by one of your .gitignore files:\n"
+msgstr ""
+
+#: builtin/add.c:352
+#, c-format
+msgid "Use -f if you really want to add them.\n"
+msgstr ""
+
+#: builtin/add.c:353
+msgid "no files added"
+msgstr ""
+
+#: builtin/add.c:359
+msgid "adding files failed"
+msgstr ""
+
+#: builtin/add.c:391
+msgid "-A and -u are mutually incompatible"
+msgstr ""
+
+#: builtin/add.c:393
+msgid "Option --ignore-missing can only be used together with --dry-run"
+msgstr ""
+
+#: builtin/add.c:413
+#, c-format
+msgid "Nothing specified, nothing added.\n"
+msgstr ""
+
+#: builtin/add.c:414
+#, c-format
+msgid "Maybe you wanted to say 'git add .'?\n"
+msgstr ""
+
+#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:358 builtin/mv.c:82
+#: builtin/rm.c:162
+msgid "index file corrupt"
+msgstr ""
+
+#: builtin/add.c:476 builtin/mv.c:229 builtin/rm.c:260
+msgid "Unable to write new index file"
+msgstr ""
+
+#: builtin/archive.c:17
+#, c-format
+msgid "could not create archive file '%s'"
+msgstr ""
+
+#: builtin/archive.c:20
+msgid "could not redirect output"
+msgstr ""
+
+#: builtin/archive.c:37
+msgid "git archive: Remote with no URL"
+msgstr ""
+
+#: builtin/archive.c:58
+msgid "git archive: expected ACK/NAK, got EOF"
+msgstr ""
+
+#: builtin/archive.c:63
+#, c-format
+msgid "git archive: NACK %s"
+msgstr ""
+
+#: builtin/archive.c:65
+#, c-format
+msgid "remote error: %s"
+msgstr ""
+
+#: builtin/archive.c:66
+msgid "git archive: protocol error"
+msgstr ""
+
+#: builtin/archive.c:71
+msgid "git archive: expected a flush"
+msgstr ""
+
+#: builtin/branch.c:137
+#, c-format
+msgid ""
+"deleting branch '%s' that has been merged to\n"
+"         '%s', but not yet merged to HEAD."
+msgstr ""
+
+#: builtin/branch.c:141
+#, c-format
+msgid ""
+"not deleting branch '%s' that is not yet merged to\n"
+"         '%s', even though it is merged to HEAD."
+msgstr ""
+
+#. TRANSLATORS: This is "remote " in "remote branch '%s' not found"
+#: builtin/branch.c:163
+msgid "remote "
+msgstr ""
+
+#: builtin/branch.c:171
+msgid "cannot use -a with -d"
+msgstr ""
+
+#: builtin/branch.c:177
+msgid "Couldn't look up commit object for HEAD"
+msgstr ""
+
+#: builtin/branch.c:182
+#, c-format
+msgid "Cannot delete the branch '%s' which you are currently on."
+msgstr ""
+
+#: builtin/branch.c:192
+#, c-format
+msgid "%sbranch '%s' not found."
+msgstr ""
+
+#: builtin/branch.c:200
+#, c-format
+msgid "Couldn't look up commit object for '%s'"
+msgstr ""
+
+#: builtin/branch.c:206
+#, c-format
+msgid ""
+"The branch '%s' is not fully merged.\n"
+"If you are sure you want to delete it, run 'git branch -D %s'."
+msgstr ""
+
+#: builtin/branch.c:214
+#, c-format
+msgid "Error deleting %sbranch '%s'"
+msgstr ""
+
+#: builtin/branch.c:219
+#, c-format
+msgid "Deleted %sbranch %s (was %s).\n"
+msgstr ""
+
+#: builtin/branch.c:224
+msgid "Update of config-file failed"
+msgstr ""
+
+#: builtin/branch.c:322
+#, c-format
+msgid "branch '%s' does not point at a commit"
+msgstr ""
+
+#: builtin/branch.c:394
+#, c-format
+msgid "behind %d] "
+msgstr ""
+
+#: builtin/branch.c:396
+#, c-format
+msgid "ahead %d] "
+msgstr ""
+
+#: builtin/branch.c:398
+#, c-format
+msgid "ahead %d, behind %d] "
+msgstr ""
+
+#: builtin/branch.c:501
+msgid "(no branch)"
+msgstr ""
+
+#: builtin/branch.c:562
+msgid "some refs could not be read"
+msgstr ""
+
+#: builtin/branch.c:575
+msgid "cannot rename the current branch while not on any."
+msgstr ""
+
+#: builtin/branch.c:585
+#, c-format
+msgid "Invalid branch name: '%s'"
+msgstr ""
+
+#: builtin/branch.c:600
+msgid "Branch rename failed"
+msgstr ""
+
+#: builtin/branch.c:604
+#, c-format
+msgid "Renamed a misnamed branch '%s' away"
+msgstr ""
+
+#: builtin/branch.c:608
+#, c-format
+msgid "Branch renamed to %s, but HEAD is not updated!"
+msgstr ""
+
+#: builtin/branch.c:615
+msgid "Branch is renamed, but update of config-file failed"
+msgstr ""
+
+#: builtin/branch.c:630
+#, c-format
+msgid "malformed object name %s"
+msgstr ""
+
+#: builtin/branch.c:654
+#, c-format
+msgid "could not write branch description template: %s\n"
+msgstr ""
+
+#: builtin/branch.c:742
+msgid "Failed to resolve HEAD as a valid ref."
+msgstr ""
+
+#: builtin/branch.c:747 builtin/clone.c:558
+msgid "HEAD not found below refs/heads!"
+msgstr ""
+
+#: builtin/branch.c:805
+msgid "-a and -r options to 'git branch' do not make sense with a branch name"
+msgstr ""
+
+#: builtin/bundle.c:47
+#, c-format
+msgid "%s is okay\n"
+msgstr ""
+
+#: builtin/bundle.c:56
+msgid "Need a repository to create a bundle."
+msgstr ""
+
+#: builtin/bundle.c:60
+msgid "Need a repository to unbundle."
+msgstr ""
+
+#: builtin/checkout.c:113 builtin/checkout.c:146
+#, c-format
+msgid "path '%s' does not have our version"
+msgstr ""
+
+#: builtin/checkout.c:115 builtin/checkout.c:148
+#, c-format
+msgid "path '%s' does not have their version"
+msgstr ""
+
+#: builtin/checkout.c:131
+#, c-format
+msgid "path '%s' does not have all necessary versions"
+msgstr ""
+
+#: builtin/checkout.c:175
+#, c-format
+msgid "path '%s' does not have necessary versions"
+msgstr ""
+
+#: builtin/checkout.c:192
+#, c-format
+msgid "path '%s': cannot merge"
+msgstr ""
+
+#: builtin/checkout.c:209
+#, c-format
+msgid "Unable to add merge result for '%s'"
+msgstr ""
+
+#: builtin/checkout.c:212 builtin/reset.c:158
+#, c-format
+msgid "make_cache_entry failed for path '%s'"
+msgstr ""
+
+#: builtin/checkout.c:234 builtin/checkout.c:392
+msgid "corrupt index file"
+msgstr ""
+
+#: builtin/checkout.c:264 builtin/checkout.c:271
+#, c-format
+msgid "path '%s' is unmerged"
+msgstr ""
+
+#: builtin/checkout.c:302 builtin/checkout.c:498 builtin/clone.c:583
+#: builtin/merge.c:809
+msgid "unable to write new index file"
+msgstr ""
+
+#: builtin/checkout.c:319 builtin/diff.c:298 builtin/merge.c:406
+msgid "diff_setup_done failed"
+msgstr ""
+
+#: builtin/checkout.c:414
+msgid "you need to resolve your current index first"
+msgstr ""
+
+#: builtin/checkout.c:533
+#, c-format
+msgid "Can not do reflog for '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:565
+msgid "HEAD is now at"
+msgstr ""
+
+#: builtin/checkout.c:572
+#, c-format
+msgid "Reset branch '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:575
+#, c-format
+msgid "Already on '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:579
+#, c-format
+msgid "Switched to and reset branch '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:581
+#, c-format
+msgid "Switched to a new branch '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:583
+#, c-format
+msgid "Switched to branch '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:639
+#, c-format
+msgid " ... and %d more.\n"
+msgstr ""
+
+#. The singular version
+#: builtin/checkout.c:645
+#, c-format
+msgid ""
+"Warning: you are leaving %d commit behind, not connected to\n"
+"any of your branches:\n"
+"\n"
+"%s\n"
+msgid_plural ""
+"Warning: you are leaving %d commits behind, not connected to\n"
+"any of your branches:\n"
+"\n"
+"%s\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: builtin/checkout.c:663
+#, c-format
+msgid ""
+"If you want to keep them by creating a new branch, this may be a good time\n"
+"to do so with:\n"
+"\n"
+" git branch new_branch_name %s\n"
+"\n"
+msgstr ""
+
+#: builtin/checkout.c:692
+msgid "internal error in revision walk"
+msgstr ""
+
+#: builtin/checkout.c:696
+msgid "Previous HEAD position was"
+msgstr ""
+
+#: builtin/checkout.c:722
+msgid "You are on a branch yet to be born"
+msgstr ""
+
+#. case (1)
+#: builtin/checkout.c:853
+#, c-format
+msgid "invalid reference: %s"
+msgstr ""
+
+#. case (1): want a tree
+#: builtin/checkout.c:892
+#, c-format
+msgid "reference is not a tree: %s"
+msgstr ""
+
+#: builtin/checkout.c:972
+msgid "-B cannot be used with -b"
+msgstr ""
+
+#: builtin/checkout.c:981
+msgid "--patch is incompatible with all other options"
+msgstr ""
+
+#: builtin/checkout.c:984
+msgid "--detach cannot be used with -b/-B/--orphan"
+msgstr ""
+
+#: builtin/checkout.c:986
+msgid "--detach cannot be used with -t"
+msgstr ""
+
+#: builtin/checkout.c:992
+msgid "--track needs a branch name"
+msgstr ""
+
+#: builtin/checkout.c:999
+msgid "Missing branch name; try -b"
+msgstr ""
+
+#: builtin/checkout.c:1005
+msgid "--orphan and -b|-B are mutually exclusive"
+msgstr ""
+
+#: builtin/checkout.c:1007
+msgid "--orphan cannot be used with -t"
+msgstr ""
+
+#: builtin/checkout.c:1017
+msgid "git checkout: -f and -m are incompatible"
+msgstr ""
+
+#: builtin/checkout.c:1051
+msgid "invalid path specification"
+msgstr ""
+
+#: builtin/checkout.c:1059
+#, c-format
+msgid ""
+"git checkout: updating paths is incompatible with switching branches.\n"
+"Did you intend to checkout '%s' which can not be resolved as commit?"
+msgstr ""
+
+#: builtin/checkout.c:1061
+msgid "git checkout: updating paths is incompatible with switching branches."
+msgstr ""
+
+#: builtin/checkout.c:1066
+msgid "git checkout: --detach does not take a path argument"
+msgstr ""
+
+#: builtin/checkout.c:1069
+msgid ""
+"git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
+"checking out of the index."
+msgstr ""
+
+#: builtin/checkout.c:1088
+msgid "Cannot switch branch to a non-commit."
+msgstr ""
+
+#: builtin/checkout.c:1091
+msgid "--ours/--theirs is incompatible with switching branches."
+msgstr ""
+
+#: builtin/clean.c:78
+msgid "-x and -X cannot be used together"
+msgstr ""
+
+#: builtin/clean.c:82
+msgid ""
+"clean.requireForce set to true and neither -n nor -f given; refusing to clean"
+msgstr ""
+
+#: builtin/clean.c:85
+msgid ""
+"clean.requireForce defaults to true and neither -n nor -f given; refusing to "
+"clean"
+msgstr ""
+
+#: builtin/clean.c:155 builtin/clean.c:176
+#, c-format
+msgid "Would remove %s\n"
+msgstr ""
+
+#: builtin/clean.c:159 builtin/clean.c:179
+#, c-format
+msgid "Removing %s\n"
+msgstr ""
+
+#: builtin/clean.c:162 builtin/clean.c:182
+#, c-format
+msgid "failed to remove %s"
+msgstr ""
+
+#: builtin/clean.c:166
+#, c-format
+msgid "Would not remove %s\n"
+msgstr ""
+
+#: builtin/clean.c:168
+#, c-format
+msgid "Not removing %s\n"
+msgstr ""
+
+#: builtin/clone.c:243
+#, c-format
+msgid "reference repository '%s' is not a local directory."
+msgstr ""
+
+#: builtin/clone.c:302
+#, c-format
+msgid "failed to open '%s'"
+msgstr ""
+
+#: builtin/clone.c:306
+#, c-format
+msgid "failed to create directory '%s'"
+msgstr ""
+
+#: builtin/clone.c:308 builtin/diff.c:75
+#, c-format
+msgid "failed to stat '%s'"
+msgstr ""
+
+#: builtin/clone.c:310
+#, c-format
+msgid "%s exists and is not a directory"
+msgstr ""
+
+#: builtin/clone.c:324
+#, c-format
+msgid "failed to stat %s\n"
+msgstr ""
+
+#: builtin/clone.c:341
+#, c-format
+msgid "failed to unlink '%s'"
+msgstr ""
+
+#: builtin/clone.c:346
+#, c-format
+msgid "failed to create link '%s'"
+msgstr ""
+
+#: builtin/clone.c:350
+#, c-format
+msgid "failed to copy file to '%s'"
+msgstr ""
+
+#: builtin/clone.c:373
+#, c-format
+msgid "done.\n"
+msgstr ""
+
+#: builtin/clone.c:440
+#, c-format
+msgid "Could not find remote branch %s to clone."
+msgstr ""
+
+#: builtin/clone.c:549
+msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
+msgstr ""
+
+#: builtin/clone.c:639
+msgid "Too many arguments."
+msgstr ""
+
+#: builtin/clone.c:643
+msgid "You must specify a repository to clone."
+msgstr ""
+
+#: builtin/clone.c:654
+#, c-format
+msgid "--bare and --origin %s options are incompatible."
+msgstr ""
+
+#: builtin/clone.c:668
+#, c-format
+msgid "repository '%s' does not exist"
+msgstr ""
+
+#: builtin/clone.c:673
+msgid "--depth is ignored in local clones; use file:// instead."
+msgstr ""
+
+#: builtin/clone.c:683
+#, c-format
+msgid "destination path '%s' already exists and is not an empty directory."
+msgstr ""
+
+#: builtin/clone.c:693
+#, c-format
+msgid "working tree '%s' already exists."
+msgstr ""
+
+#: builtin/clone.c:706 builtin/clone.c:720
+#, c-format
+msgid "could not create leading directories of '%s'"
+msgstr ""
+
+#: builtin/clone.c:709
+#, c-format
+msgid "could not create work tree dir '%s'."
+msgstr ""
+
+#: builtin/clone.c:728
+#, c-format
+msgid "Cloning into bare repository '%s'...\n"
+msgstr ""
+
+#: builtin/clone.c:730
+#, c-format
+msgid "Cloning into '%s'...\n"
+msgstr ""
+
+#: builtin/clone.c:786
+#, c-format
+msgid "Don't know how to clone %s"
+msgstr ""
+
+#: builtin/clone.c:835
+#, c-format
+msgid "Remote branch %s not found in upstream %s"
+msgstr ""
+
+#: builtin/clone.c:842
+msgid "You appear to have cloned an empty repository."
+msgstr ""
+
+#: builtin/commit.c:42
+msgid ""
+"Your name and email address were configured automatically based\n"
+"on your username and hostname. Please check that they are accurate.\n"
+"You can suppress this message by setting them explicitly:\n"
+"\n"
+"    git config --global user.name \"Your Name\"\n"
+"    git config --global user.email you@example.com\n"
+"\n"
+"After doing this, you may fix the identity used for this commit with:\n"
+"\n"
+"    git commit --amend --reset-author\n"
+msgstr ""
+
+#: builtin/commit.c:54
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/commit.c:59
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/commit.c:205 builtin/reset.c:33
+msgid "merge"
+msgstr ""
+
+#: builtin/commit.c:208
+msgid "cherry-pick"
+msgstr ""
+
+#: builtin/commit.c:325
+msgid "failed to unpack HEAD tree object"
+msgstr ""
+
+#: builtin/commit.c:367
+msgid "unable to create temporary index"
+msgstr ""
+
+#: builtin/commit.c:373
+msgid "interactive add failed"
+msgstr ""
+
+#: builtin/commit.c:406 builtin/commit.c:427 builtin/commit.c:473
+msgid "unable to write new_index file"
+msgstr ""
+
+#: builtin/commit.c:457
+#, c-format
+msgid "cannot do a partial commit during a %s."
+msgstr ""
+
+#: builtin/commit.c:466
+msgid "cannot read the index"
+msgstr ""
+
+#: builtin/commit.c:486
+msgid "unable to write temporary index file"
+msgstr ""
+
+#: builtin/commit.c:550 builtin/commit.c:556
+#, c-format
+msgid "invalid commit: %s"
+msgstr ""
+
+#: builtin/commit.c:579
+msgid "malformed --author parameter"
+msgstr ""
+
+#: builtin/commit.c:635
+#, c-format
+msgid "Malformed ident string: '%s'"
+msgstr ""
+
+#: builtin/commit.c:670 builtin/commit.c:703 builtin/commit.c:1000
+#, c-format
+msgid "could not lookup commit %s"
+msgstr ""
+
+#: builtin/commit.c:682 builtin/shortlog.c:296
+#, c-format
+msgid "(reading log message from standard input)\n"
+msgstr ""
+
+#: builtin/commit.c:684
+msgid "could not read log from standard input"
+msgstr ""
+
+#: builtin/commit.c:688
+#, c-format
+msgid "could not read log file '%s'"
+msgstr ""
+
+#: builtin/commit.c:694
+msgid "commit has empty message"
+msgstr ""
+
+#: builtin/commit.c:710
+msgid "could not read MERGE_MSG"
+msgstr ""
+
+#: builtin/commit.c:714
+msgid "could not read SQUASH_MSG"
+msgstr ""
+
+#: builtin/commit.c:718
+#, c-format
+msgid "could not read '%s'"
+msgstr ""
+
+#: builtin/commit.c:746
+#, c-format
+msgid "could not open '%s'"
+msgstr ""
+
+#: builtin/commit.c:770
+msgid "could not write commit template"
+msgstr ""
+
+#: builtin/commit.c:783
+#, c-format
+msgid ""
+"\n"
+"It looks like you may be committing a %s.\n"
+"If this is not correct, please remove the file\n"
+"\t%s\n"
+"and try again.\n"
+msgstr ""
+
+#: builtin/commit.c:796
+msgid "Please enter the commit message for your changes."
+msgstr ""
+
+#: builtin/commit.c:799
+msgid ""
+" Lines starting\n"
+"with '#' will be ignored, and an empty message aborts the commit.\n"
+msgstr ""
+
+#: builtin/commit.c:804
+msgid ""
+" Lines starting\n"
+"with '#' will be kept; you may remove them yourself if you want to.\n"
+"An empty message aborts the commit.\n"
+msgstr ""
+
+#: builtin/commit.c:816
+#, c-format
+msgid "%sAuthor:    %s"
+msgstr ""
+
+#: builtin/commit.c:823
+#, c-format
+msgid "%sCommitter: %s"
+msgstr ""
+
+#: builtin/commit.c:843
+msgid "Cannot read index"
+msgstr ""
+
+#: builtin/commit.c:880
+msgid "Error building trees"
+msgstr ""
+
+#: builtin/commit.c:895 builtin/tag.c:357
+#, c-format
+msgid "Please supply the message using either -m or -F option.\n"
+msgstr ""
+
+#: builtin/commit.c:975
+#, c-format
+msgid "No existing author found with '%s'"
+msgstr ""
+
+#: builtin/commit.c:990 builtin/commit.c:1182
+#, c-format
+msgid "Invalid untracked files mode '%s'"
+msgstr ""
+
+#: builtin/commit.c:1030
+msgid "Using both --reset-author and --author does not make sense"
+msgstr ""
+
+#: builtin/commit.c:1041
+msgid "You have nothing to amend."
+msgstr ""
+
+#: builtin/commit.c:1043
+#, c-format
+msgid "You are in the middle of a %s -- cannot amend."
+msgstr ""
+
+#: builtin/commit.c:1045
+msgid "Options --squash and --fixup cannot be used together"
+msgstr ""
+
+#: builtin/commit.c:1055
+msgid "Only one of -c/-C/-F/--fixup can be used."
+msgstr ""
+
+#: builtin/commit.c:1057
+msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
+msgstr ""
+
+#: builtin/commit.c:1063
+msgid "--reset-author can be used only with -C, -c or --amend."
+msgstr ""
+
+#: builtin/commit.c:1080
+msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
+msgstr ""
+
+#: builtin/commit.c:1082
+msgid "No paths with --include/--only does not make sense."
+msgstr ""
+
+#: builtin/commit.c:1084
+msgid "Clever... amending the last one with dirty index."
+msgstr ""
+
+#: builtin/commit.c:1086
+msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
+msgstr ""
+
+#: builtin/commit.c:1096 builtin/tag.c:556
+#, c-format
+msgid "Invalid cleanup mode %s"
+msgstr ""
+
+#: builtin/commit.c:1101
+msgid "Paths with -a does not make sense."
+msgstr ""
+
+#: builtin/commit.c:1280
+msgid "couldn't look up newly created commit"
+msgstr ""
+
+#: builtin/commit.c:1282
+msgid "could not parse newly created commit"
+msgstr ""
+
+#: builtin/commit.c:1323
+msgid "detached HEAD"
+msgstr ""
+
+#: builtin/commit.c:1325
+msgid " (root-commit)"
+msgstr ""
+
+#: builtin/commit.c:1415
+msgid "could not parse HEAD commit"
+msgstr ""
+
+#: builtin/commit.c:1452 builtin/merge.c:507
+#, c-format
+msgid "could not open '%s' for reading"
+msgstr ""
+
+#: builtin/commit.c:1459
+#, c-format
+msgid "Corrupt MERGE_HEAD file (%s)"
+msgstr ""
+
+#: builtin/commit.c:1466
+msgid "could not read MERGE_MODE"
+msgstr ""
+
+#: builtin/commit.c:1485
+#, c-format
+msgid "could not read commit message: %s"
+msgstr ""
+
+#: builtin/commit.c:1499
+#, c-format
+msgid "Aborting commit due to empty commit message.\n"
+msgstr ""
+
+#: builtin/commit.c:1514 builtin/merge.c:933 builtin/merge.c:966
+msgid "failed to write commit object"
+msgstr ""
+
+#: builtin/commit.c:1535
+msgid "cannot lock HEAD ref"
+msgstr ""
+
+#: builtin/commit.c:1539
+msgid "cannot update HEAD ref"
+msgstr ""
+
+#: builtin/commit.c:1550
+msgid ""
+"Repository has been updated, but unable to write\n"
+"new_index file. Check that disk is not full or quota is\n"
+"not exceeded, and then \"git reset HEAD\" to recover."
+msgstr ""
+
+#: builtin/describe.c:234
+#, c-format
+msgid "annotated tag %s not available"
+msgstr ""
+
+#: builtin/describe.c:238
+#, c-format
+msgid "annotated tag %s has no embedded name"
+msgstr ""
+
+#: builtin/describe.c:240
+#, c-format
+msgid "tag '%s' is really '%s' here"
+msgstr ""
+
+#: builtin/describe.c:267
+#, c-format
+msgid "Not a valid object name %s"
+msgstr ""
+
+#: builtin/describe.c:270
+#, c-format
+msgid "%s is not a valid '%s' object"
+msgstr ""
+
+#: builtin/describe.c:287
+#, c-format
+msgid "no tag exactly matches '%s'"
+msgstr ""
+
+#: builtin/describe.c:289
+#, c-format
+msgid "searching to describe %s\n"
+msgstr ""
+
+#: builtin/describe.c:329
+#, c-format
+msgid "finished search at %s\n"
+msgstr ""
+
+#: builtin/describe.c:353
+#, c-format
+msgid ""
+"No annotated tags can describe '%s'.\n"
+"However, there were unannotated tags: try --tags."
+msgstr ""
+
+#: builtin/describe.c:357
+#, c-format
+msgid ""
+"No tags can describe '%s'.\n"
+"Try --always, or create some tags."
+msgstr ""
+
+#: builtin/describe.c:378
+#, c-format
+msgid "traversed %lu commits\n"
+msgstr ""
+
+#: builtin/describe.c:381
+#, c-format
+msgid ""
+"more than %i tags found; listed %i most recent\n"
+"gave up search at %s\n"
+msgstr ""
+
+#: builtin/describe.c:436
+msgid "--long is incompatible with --abbrev=0"
+msgstr ""
+
+#: builtin/describe.c:462
+msgid "No names found, cannot describe anything."
+msgstr ""
+
+#: builtin/describe.c:482
+msgid "--dirty is incompatible with committishes"
+msgstr ""
+
+#: builtin/diff.c:77
+#, c-format
+msgid "'%s': not a regular file or symlink"
+msgstr ""
+
+#: builtin/diff.c:220
+#, c-format
+msgid "invalid option: %s"
+msgstr ""
+
+#: builtin/diff.c:293
+msgid "Not a git repository"
+msgstr ""
+
+#: builtin/diff.c:343
+#, c-format
+msgid "invalid object '%s' given."
+msgstr ""
+
+#: builtin/diff.c:348
+#, c-format
+msgid "more than %d trees given: '%s'"
+msgstr ""
+
+#: builtin/diff.c:358
+#, c-format
+msgid "more than two blobs given: '%s'"
+msgstr ""
+
+#: builtin/diff.c:366
+#, c-format
+msgid "unhandled object '%s' given."
+msgstr ""
+
+#: builtin/fetch.c:200
+msgid "Couldn't find remote ref HEAD"
+msgstr ""
+
+#: builtin/fetch.c:252
+#, c-format
+msgid "object %s not found"
+msgstr ""
+
+#: builtin/fetch.c:258
+msgid "[up to date]"
+msgstr ""
+
+#: builtin/fetch.c:272
+#, c-format
+msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
+msgstr ""
+
+#: builtin/fetch.c:273 builtin/fetch.c:351
+msgid "[rejected]"
+msgstr ""
+
+#: builtin/fetch.c:284
+msgid "[tag update]"
+msgstr ""
+
+#: builtin/fetch.c:286 builtin/fetch.c:313 builtin/fetch.c:331
+msgid "  (unable to update local ref)"
+msgstr ""
+
+#: builtin/fetch.c:298
+msgid "[new tag]"
+msgstr ""
+
+#: builtin/fetch.c:302
+msgid "[new branch]"
+msgstr ""
+
+#: builtin/fetch.c:347
+msgid "unable to update local ref"
+msgstr ""
+
+#: builtin/fetch.c:347
+msgid "forced update"
+msgstr ""
+
+#: builtin/fetch.c:353
+msgid "(non-fast-forward)"
+msgstr ""
+
+#: builtin/fetch.c:384 builtin/fetch.c:676
+#, c-format
+msgid "cannot open %s: %s\n"
+msgstr ""
+
+#: builtin/fetch.c:393
+#, c-format
+msgid "%s did not send all necessary objects\n"
+msgstr ""
+
+#: builtin/fetch.c:479
+#, c-format
+msgid "From %.*s\n"
+msgstr ""
+
+#: builtin/fetch.c:490
+#, c-format
+msgid ""
+"some local refs could not be updated; try running\n"
+" 'git remote prune %s' to remove any old, conflicting branches"
+msgstr ""
+
+#: builtin/fetch.c:540
+#, c-format
+msgid "   (%s will become dangling)\n"
+msgstr ""
+
+#: builtin/fetch.c:541
+#, c-format
+msgid "   (%s has become dangling)\n"
+msgstr ""
+
+#: builtin/fetch.c:548
+msgid "[deleted]"
+msgstr ""
+
+#: builtin/fetch.c:549
+msgid "(none)"
+msgstr ""
+
+#: builtin/fetch.c:666
+#, c-format
+msgid "Refusing to fetch into current branch %s of non-bare repository"
+msgstr ""
+
+#: builtin/fetch.c:700
+#, c-format
+msgid "Don't know how to fetch from %s"
+msgstr ""
+
+#: builtin/fetch.c:777
+#, c-format
+msgid "Option \"%s\" value \"%s\" is not valid for %s"
+msgstr ""
+
+#: builtin/fetch.c:780
+#, c-format
+msgid "Option \"%s\" is ignored for %s\n"
+msgstr ""
+
+#: builtin/fetch.c:879
+#, c-format
+msgid "Fetching %s\n"
+msgstr ""
+
+#: builtin/fetch.c:881
+#, c-format
+msgid "Could not fetch %s"
+msgstr ""
+
+#: builtin/fetch.c:898
+msgid ""
+"No remote repository specified.  Please, specify either a URL or a\n"
+"remote name from which new revisions should be fetched."
+msgstr ""
+
+#: builtin/fetch.c:918
+msgid "You need to specify a tag name."
+msgstr ""
+
+#: builtin/fetch.c:970
+msgid "fetch --all does not take a repository argument"
+msgstr ""
+
+#: builtin/fetch.c:972
+msgid "fetch --all does not make sense with refspecs"
+msgstr ""
+
+#: builtin/fetch.c:983
+#, c-format
+msgid "No such remote or remote group: %s"
+msgstr ""
+
+#: builtin/fetch.c:991
+msgid "Fetching a group and specifying refspecs does not make sense"
+msgstr ""
+
+#: builtin/gc.c:63
+#, c-format
+msgid "Invalid %s: '%s'"
+msgstr ""
+
+#: builtin/gc.c:78
+msgid "Too many options specified"
+msgstr ""
+
+#: builtin/gc.c:103
+#, c-format
+msgid "insanely long object directory %.*s"
+msgstr ""
+
+#: builtin/gc.c:223
+#, c-format
+msgid "Auto packing the repository for optimum performance.\n"
+msgstr ""
+
+#: builtin/gc.c:226
+#, c-format
+msgid ""
+"Auto packing the repository for optimum performance. You may also\n"
+"run \"git gc\" manually. See \"git help gc\" for more information.\n"
+msgstr ""
+
+#: builtin/gc.c:256
+msgid ""
+"There are too many unreachable loose objects; run 'git prune' to remove them."
+msgstr ""
+
+#: builtin/grep.c:216
+#, c-format
+msgid "grep: failed to create thread: %s"
+msgstr ""
+
+#: builtin/grep.c:402
+#, c-format
+msgid "Failed to chdir: %s"
+msgstr ""
+
+#: builtin/grep.c:478 builtin/grep.c:512
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr ""
+
+#: builtin/grep.c:526
+#, c-format
+msgid "unable to grep from object of type %s"
+msgstr ""
+
+#: builtin/grep.c:584
+#, c-format
+msgid "switch `%c' expects a numerical value"
+msgstr ""
+
+#: builtin/grep.c:601
+#, c-format
+msgid "cannot open '%s'"
+msgstr ""
+
+#: builtin/grep.c:889
+msgid "no pattern given."
+msgstr ""
+
+#: builtin/grep.c:903
+#, c-format
+msgid "bad object %s"
+msgstr ""
+
+#: builtin/grep.c:944
+msgid "--open-files-in-pager only works on the worktree"
+msgstr ""
+
+#: builtin/grep.c:967
+msgid "--cached or --untracked cannot be used with --no-index."
+msgstr ""
+
+#: builtin/grep.c:972
+msgid "--no-index or --untracked cannot be used with revs."
+msgstr ""
+
+#: builtin/grep.c:975
+msgid "--[no-]exclude-standard cannot be used for tracked contents."
+msgstr ""
+
+#: builtin/grep.c:983
+msgid "both --cached and trees are given."
+msgstr ""
+
+#: builtin/init-db.c:35
+#, c-format
+msgid "Could not make %s writable by group"
+msgstr ""
+
+#: builtin/init-db.c:62
+#, c-format
+msgid "insanely long template name %s"
+msgstr ""
+
+#: builtin/init-db.c:67
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: builtin/init-db.c:73
+#, c-format
+msgid "cannot stat template '%s'"
+msgstr ""
+
+#: builtin/init-db.c:80
+#, c-format
+msgid "cannot opendir '%s'"
+msgstr ""
+
+#: builtin/init-db.c:97
+#, c-format
+msgid "cannot readlink '%s'"
+msgstr ""
+
+#: builtin/init-db.c:99
+#, c-format
+msgid "insanely long symlink %s"
+msgstr ""
+
+#: builtin/init-db.c:102
+#, c-format
+msgid "cannot symlink '%s' '%s'"
+msgstr ""
+
+#: builtin/init-db.c:106
+#, c-format
+msgid "cannot copy '%s' to '%s'"
+msgstr ""
+
+#: builtin/init-db.c:110
+#, c-format
+msgid "ignoring template %s"
+msgstr ""
+
+#: builtin/init-db.c:133
+#, c-format
+msgid "insanely long template path %s"
+msgstr ""
+
+#: builtin/init-db.c:141
+#, c-format
+msgid "templates not found %s"
+msgstr ""
+
+#: builtin/init-db.c:154
+#, c-format
+msgid "not copying templates of a wrong format version %d from '%s'"
+msgstr ""
+
+#: builtin/init-db.c:192
+#, c-format
+msgid "insane git directory %s"
+msgstr ""
+
+#: builtin/init-db.c:322 builtin/init-db.c:325
+#, c-format
+msgid "%s already exists"
+msgstr ""
+
+#: builtin/init-db.c:354
+#, c-format
+msgid "unable to handle file type %d"
+msgstr ""
+
+#: builtin/init-db.c:357
+#, c-format
+msgid "unable to move %s to %s"
+msgstr ""
+
+#: builtin/init-db.c:362
+#, c-format
+msgid "Could not create git link %s"
+msgstr ""
+
+#.
+#. * TRANSLATORS: The first '%s' is either "Reinitialized
+#. * existing" or "Initialized empty", the second " shared" or
+#. * "", and the last '%s%s' is the verbatim directory name.
+#.
+#: builtin/init-db.c:419
+#, c-format
+msgid "%s%s Git repository in %s%s\n"
+msgstr ""
+
+#: builtin/init-db.c:420
+msgid "Reinitialized existing"
+msgstr ""
+
+#: builtin/init-db.c:420
+msgid "Initialized empty"
+msgstr ""
+
+#: builtin/init-db.c:421
+msgid " shared"
+msgstr ""
+
+#: builtin/init-db.c:440
+msgid "cannot tell cwd"
+msgstr ""
+
+#: builtin/init-db.c:521 builtin/init-db.c:528
+#, c-format
+msgid "cannot mkdir %s"
+msgstr ""
+
+#: builtin/init-db.c:532
+#, c-format
+msgid "cannot chdir to %s"
+msgstr ""
+
+#: builtin/init-db.c:554
+#, c-format
+msgid ""
+"%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
+"dir=<directory>)"
+msgstr ""
+
+#: builtin/init-db.c:578
+msgid "Cannot access current working directory"
+msgstr ""
+
+#: builtin/init-db.c:585
+#, c-format
+msgid "Cannot access work tree '%s'"
+msgstr ""
+
+#: builtin/log.c:185
+#, c-format
+msgid "Final output: %d %s\n"
+msgstr ""
+
+#: builtin/log.c:393 builtin/log.c:479
+#, c-format
+msgid "Could not read object %s"
+msgstr ""
+
+#: builtin/log.c:503
+#, c-format
+msgid "Unknown type: %d"
+msgstr ""
+
+#: builtin/log.c:592
+msgid "format.headers without value"
+msgstr ""
+
+#: builtin/log.c:665
+msgid "name of output directory is too long"
+msgstr ""
+
+#: builtin/log.c:676
+#, c-format
+msgid "Cannot open patch file %s"
+msgstr ""
+
+#: builtin/log.c:690
+msgid "Need exactly one range."
+msgstr ""
+
+#: builtin/log.c:698
+msgid "Not a range."
+msgstr ""
+
+#: builtin/log.c:735
+msgid "Could not extract email from committer identity."
+msgstr ""
+
+#: builtin/log.c:781
+msgid "Cover letter needs email format"
+msgstr ""
+
+#: builtin/log.c:875
+#, c-format
+msgid "insane in-reply-to: %s"
+msgstr ""
+
+#: builtin/log.c:948
+msgid "Two output directories?"
+msgstr ""
+
+#: builtin/log.c:1169
+#, c-format
+msgid "bogus committer info %s"
+msgstr ""
+
+#: builtin/log.c:1214
+msgid "-n and -k are mutually exclusive."
+msgstr ""
+
+#: builtin/log.c:1216
+msgid "--subject-prefix and -k are mutually exclusive."
+msgstr ""
+
+#: builtin/log.c:1221 builtin/shortlog.c:284
+#, c-format
+msgid "unrecognized argument: %s"
+msgstr ""
+
+#: builtin/log.c:1224
+msgid "--name-only does not make sense"
+msgstr ""
+
+#: builtin/log.c:1226
+msgid "--name-status does not make sense"
+msgstr ""
+
+#: builtin/log.c:1228
+msgid "--check does not make sense"
+msgstr ""
+
+#: builtin/log.c:1251
+msgid "standard output, or directory, which one?"
+msgstr ""
+
+#: builtin/log.c:1253
+#, c-format
+msgid "Could not create directory '%s'"
+msgstr ""
+
+#: builtin/log.c:1406
+msgid "Failed to create output files"
+msgstr ""
+
+#: builtin/log.c:1510
+#, c-format
+msgid ""
+"Could not find a tracked remote branch, please specify <upstream> manually.\n"
+msgstr ""
+
+#: builtin/log.c:1526 builtin/log.c:1528 builtin/log.c:1540
+#, c-format
+msgid "Unknown commit %s"
+msgstr ""
+
+#: builtin/merge.c:91
+msgid "switch `m' requires a value"
+msgstr ""
+
+#: builtin/merge.c:128
+#, c-format
+msgid "Could not find merge strategy '%s'.\n"
+msgstr ""
+
+#: builtin/merge.c:129
+#, c-format
+msgid "Available strategies are:"
+msgstr ""
+
+#: builtin/merge.c:134
+#, c-format
+msgid "Available custom strategies are:"
+msgstr ""
+
+#: builtin/merge.c:241
+msgid "could not run stash."
+msgstr ""
+
+#: builtin/merge.c:246
+msgid "stash failed"
+msgstr ""
+
+#: builtin/merge.c:251
+#, c-format
+msgid "not a valid object: %s"
+msgstr ""
+
+#: builtin/merge.c:270 builtin/merge.c:287
+msgid "read-tree failed"
+msgstr ""
+
+#: builtin/merge.c:317
+msgid " (nothing to squash)"
+msgstr ""
+
+#: builtin/merge.c:330
+#, c-format
+msgid "Squash commit -- not updating HEAD\n"
+msgstr ""
+
+#: builtin/merge.c:362
+msgid "Writing SQUASH_MSG"
+msgstr ""
+
+#: builtin/merge.c:364
+msgid "Finishing SQUASH_MSG"
+msgstr ""
+
+#: builtin/merge.c:386
+#, c-format
+msgid "No merge message -- not updating HEAD\n"
+msgstr ""
+
+#: builtin/merge.c:435
+#, c-format
+msgid "'%s' does not point to a commit"
+msgstr ""
+
+#: builtin/merge.c:534
+#, c-format
+msgid "Bad branch.%s.mergeoptions string: %s"
+msgstr ""
+
+#: builtin/merge.c:627
+msgid "git write-tree failed to write a tree"
+msgstr ""
+
+#: builtin/merge.c:677
+msgid "failed to read the cache"
+msgstr ""
+
+#: builtin/merge.c:694
+msgid "Unable to write index."
+msgstr ""
+
+#: builtin/merge.c:707
+msgid "Not handling anything other than two heads merge."
+msgstr ""
+
+#: builtin/merge.c:721
+#, c-format
+msgid "Unknown option for merge-recursive: -X%s"
+msgstr ""
+
+#: builtin/merge.c:735
+#, c-format
+msgid "unable to write %s"
+msgstr ""
+
+#: builtin/merge.c:874
+#, c-format
+msgid "Could not read from '%s'"
+msgstr ""
+
+#: builtin/merge.c:883
+#, c-format
+msgid "Not committing merge; use 'git commit' to complete the merge.\n"
+msgstr ""
+
+#: builtin/merge.c:889
+msgid ""
+"Please enter a commit message to explain why this merge is necessary,\n"
+"especially if it merges an updated upstream into a topic branch.\n"
+"\n"
+"Lines starting with '#' will be ignored, and an empty message aborts\n"
+"the commit.\n"
+msgstr ""
+
+#: builtin/merge.c:913
+msgid "Empty commit message."
+msgstr ""
+
+#: builtin/merge.c:925
+#, c-format
+msgid "Wonderful.\n"
+msgstr ""
+
+#: builtin/merge.c:998
+#, c-format
+msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
+msgstr ""
+
+#: builtin/merge.c:1014
+#, c-format
+msgid "'%s' is not a commit"
+msgstr ""
+
+#: builtin/merge.c:1055
+msgid "No current branch."
+msgstr ""
+
+#: builtin/merge.c:1057
+msgid "No remote for the current branch."
+msgstr ""
+
+#: builtin/merge.c:1059
+msgid "No default upstream defined for the current branch."
+msgstr ""
+
+#: builtin/merge.c:1064
+#, c-format
+msgid "No remote tracking branch for %s from %s"
+msgstr ""
+
+#: builtin/merge.c:1186
+msgid "There is no merge to abort (MERGE_HEAD missing)."
+msgstr ""
+
+#: builtin/merge.c:1202 git-pull.sh:31
+msgid ""
+"You have not concluded your merge (MERGE_HEAD exists).\n"
+"Please, commit your changes before you can merge."
+msgstr ""
+
+#: builtin/merge.c:1205 git-pull.sh:34
+msgid "You have not concluded your merge (MERGE_HEAD exists)."
+msgstr ""
+
+#: builtin/merge.c:1209
+msgid ""
+"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
+"Please, commit your changes before you can merge."
+msgstr ""
+
+#: builtin/merge.c:1212
+msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
+msgstr ""
+
+#: builtin/merge.c:1221
+msgid "You cannot combine --squash with --no-ff."
+msgstr ""
+
+#: builtin/merge.c:1226
+msgid "You cannot combine --no-ff with --ff-only."
+msgstr ""
+
+#: builtin/merge.c:1233
+msgid "No commit specified and merge.defaultToUpstream not set."
+msgstr ""
+
+#: builtin/merge.c:1264
+msgid "Can merge only exactly one commit into empty head"
+msgstr ""
+
+#: builtin/merge.c:1267
+msgid "Squash commit into empty head not supported yet"
+msgstr ""
+
+#: builtin/merge.c:1269
+msgid "Non-fast-forward commit does not make sense into an empty head"
+msgstr ""
+
+#: builtin/merge.c:1273 builtin/merge.c:1317
+#, c-format
+msgid "%s - not something we can merge"
+msgstr ""
+
+#: builtin/merge.c:1383
+#, c-format
+msgid "Updating %s..%s\n"
+msgstr ""
+
+#: builtin/merge.c:1421
+#, c-format
+msgid "Trying really trivial in-index merge...\n"
+msgstr ""
+
+#: builtin/merge.c:1428
+#, c-format
+msgid "Nope.\n"
+msgstr ""
+
+#: builtin/merge.c:1460
+msgid "Not possible to fast-forward, aborting."
+msgstr ""
+
+#: builtin/merge.c:1483 builtin/merge.c:1560
+#, c-format
+msgid "Rewinding the tree to pristine...\n"
+msgstr ""
+
+#: builtin/merge.c:1487
+#, c-format
+msgid "Trying merge strategy %s...\n"
+msgstr ""
+
+#: builtin/merge.c:1551
+#, c-format
+msgid "No merge strategy handled the merge.\n"
+msgstr ""
+
+#: builtin/merge.c:1553
+#, c-format
+msgid "Merge with strategy %s failed.\n"
+msgstr ""
+
+#: builtin/merge.c:1562
+#, c-format
+msgid "Using the %s to prepare resolving by hand.\n"
+msgstr ""
+
+#: builtin/merge.c:1573
+#, c-format
+msgid "Automatic merge went well; stopped before committing as requested\n"
+msgstr ""
+
+#: builtin/mv.c:108
+#, c-format
+msgid "Checking rename of '%s' to '%s'\n"
+msgstr ""
+
+#: builtin/mv.c:112
+msgid "bad source"
+msgstr ""
+
+#: builtin/mv.c:115
+msgid "can not move directory into itself"
+msgstr ""
+
+#: builtin/mv.c:118
+msgid "cannot move directory over file"
+msgstr ""
+
+#: builtin/mv.c:128
+#, c-format
+msgid "Huh? %.*s is in index?"
+msgstr ""
+
+#: builtin/mv.c:140
+msgid "source directory is empty"
+msgstr ""
+
+#: builtin/mv.c:171
+msgid "not under version control"
+msgstr ""
+
+#: builtin/mv.c:173
+msgid "destination exists"
+msgstr ""
+
+#: builtin/mv.c:181
+#, c-format
+msgid "overwriting '%s'"
+msgstr ""
+
+#: builtin/mv.c:184
+msgid "Cannot overwrite"
+msgstr ""
+
+#: builtin/mv.c:187
+msgid "multiple sources for the same target"
+msgstr ""
+
+#: builtin/mv.c:202
+#, c-format
+msgid "%s, source=%s, destination=%s"
+msgstr ""
+
+#: builtin/mv.c:212
+#, c-format
+msgid "Renaming %s to %s\n"
+msgstr ""
+
+#: builtin/mv.c:215
+#, c-format
+msgid "renaming '%s' failed"
+msgstr ""
+
+#: builtin/notes.c:139
+#, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr ""
+
+#: builtin/notes.c:145
+msgid "can't fdopen 'show' output fd"
+msgstr ""
+
+#: builtin/notes.c:155
+#, c-format
+msgid "failed to close pipe to 'show' for object '%s'"
+msgstr ""
+
+#: builtin/notes.c:158
+#, c-format
+msgid "failed to finish 'show' for object '%s'"
+msgstr ""
+
+#: builtin/notes.c:175 builtin/tag.c:343
+#, c-format
+msgid "could not create file '%s'"
+msgstr ""
+
+#: builtin/notes.c:189
+msgid "Please supply the note contents using either -m or -F option"
+msgstr ""
+
+#: builtin/notes.c:210 builtin/notes.c:973
+#, c-format
+msgid "Removing note for object %s\n"
+msgstr ""
+
+#: builtin/notes.c:215
+msgid "unable to write note object"
+msgstr ""
+
+#: builtin/notes.c:217
+#, c-format
+msgid "The note contents has been left in %s"
+msgstr ""
+
+#: builtin/notes.c:251 builtin/tag.c:521
+#, c-format
+msgid "cannot read '%s'"
+msgstr ""
+
+#: builtin/notes.c:253 builtin/tag.c:524
+#, c-format
+msgid "could not open or read '%s'"
+msgstr ""
+
+#: builtin/notes.c:272 builtin/notes.c:445 builtin/notes.c:447
+#: builtin/notes.c:507 builtin/notes.c:561 builtin/notes.c:644
+#: builtin/notes.c:649 builtin/notes.c:724 builtin/notes.c:766
+#: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:537
+#, c-format
+msgid "Failed to resolve '%s' as a valid ref."
+msgstr ""
+
+#: builtin/notes.c:275
+#, c-format
+msgid "Failed to read object '%s'."
+msgstr ""
+
+#: builtin/notes.c:299
+msgid "Cannot commit uninitialized/unreferenced notes tree"
+msgstr ""
+
+#: builtin/notes.c:340
+#, c-format
+msgid "Bad notes.rewriteMode value: '%s'"
+msgstr ""
+
+#: builtin/notes.c:350
+#, c-format
+msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
+msgstr ""
+
+#. TRANSLATORS: The first %s is the name of the
+#. environment variable, the second %s is its value
+#: builtin/notes.c:377
+#, c-format
+msgid "Bad %s value: '%s'"
+msgstr ""
+
+#: builtin/notes.c:441
+#, c-format
+msgid "Malformed input line: '%s'."
+msgstr ""
+
+#: builtin/notes.c:456
+#, c-format
+msgid "Failed to copy notes from '%s' to '%s'"
+msgstr ""
+
+#: builtin/notes.c:500 builtin/notes.c:554 builtin/notes.c:627
+#: builtin/notes.c:639 builtin/notes.c:712 builtin/notes.c:759
+#: builtin/notes.c:1033
+msgid "too many parameters"
+msgstr ""
+
+#: builtin/notes.c:513 builtin/notes.c:772
+#, c-format
+msgid "No note found for object %s."
+msgstr ""
+
+#: builtin/notes.c:580
+#, c-format
+msgid ""
+"Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite "
+"existing notes"
+msgstr ""
+
+#: builtin/notes.c:585 builtin/notes.c:662
+#, c-format
+msgid "Overwriting existing notes for object %s\n"
+msgstr ""
+
+#: builtin/notes.c:635
+msgid "too few parameters"
+msgstr ""
+
+#: builtin/notes.c:656
+#, c-format
+msgid ""
+"Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite "
+"existing notes"
+msgstr ""
+
+#: builtin/notes.c:668
+#, c-format
+msgid "Missing notes on source object %s. Cannot copy."
+msgstr ""
+
+#: builtin/notes.c:717
+#, c-format
+msgid ""
+"The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n"
+"Please use 'git notes add -f -m/-F/-c/-C' instead.\n"
+msgstr ""
+
+#: builtin/notes.c:971
+#, c-format
+msgid "Object %s has no note\n"
+msgstr ""
+
+#: builtin/notes.c:1103
+#, c-format
+msgid "Unknown subcommand: %s"
+msgstr ""
+
+#: builtin/pack-objects.c:2310
+#, c-format
+msgid "unsupported index version %s"
+msgstr ""
+
+#: builtin/pack-objects.c:2314
+#, c-format
+msgid "bad index version '%s'"
+msgstr ""
+
+#: builtin/pack-objects.c:2322
+#, c-format
+msgid "option %s does not accept negative form"
+msgstr ""
+
+#: builtin/pack-objects.c:2326
+#, c-format
+msgid "unable to parse value '%s' for option %s"
+msgstr ""
+
+#: builtin/push.c:44
+msgid "tag shorthand without <tag>"
+msgstr ""
+
+#: builtin/push.c:63
+msgid "--delete only accepts plain target ref names"
+msgstr ""
+
+#: builtin/push.c:73
+#, c-format
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/push.c:80
+#, c-format
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/push.c:88
+#, c-format
+msgid "The current branch %s has multiple upstream branches, refusing to push."
+msgstr ""
+
+#: builtin/push.c:111
+msgid ""
+"You didn't specify any refspecs to push, and push.default is \"nothing\"."
+msgstr ""
+
+#: builtin/push.c:131
+#, c-format
+msgid "Pushing to %s\n"
+msgstr ""
+
+#: builtin/push.c:135
+#, c-format
+msgid "failed to push some refs to '%s'"
+msgstr ""
+
+#: builtin/push.c:143
+#, c-format
+msgid ""
+"To prevent you from losing history, non-fast-forward updates were rejected\n"
+"Merge the remote changes (e.g. 'git pull') before pushing again.  See the\n"
+"'Note about fast-forwards' section of 'git push --help' for details.\n"
+msgstr ""
+
+#: builtin/push.c:160
+#, c-format
+msgid "bad repository '%s'"
+msgstr ""
+
+#: builtin/push.c:161
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/push.c:176
+msgid "--all and --tags are incompatible"
+msgstr ""
+
+#: builtin/push.c:177
+msgid "--all can't be combined with refspecs"
+msgstr ""
+
+#: builtin/push.c:182
+msgid "--mirror and --tags are incompatible"
+msgstr ""
+
+#: builtin/push.c:183
+msgid "--mirror can't be combined with refspecs"
+msgstr ""
+
+#: builtin/push.c:188
+msgid "--all and --mirror are incompatible"
+msgstr ""
+
+#: builtin/push.c:274
+msgid "--delete is incompatible with --all, --mirror and --tags"
+msgstr ""
+
+#: builtin/push.c:276
+msgid "--delete doesn't make sense without any refs"
+msgstr ""
+
+#: builtin/reset.c:33
+msgid "mixed"
+msgstr ""
+
+#: builtin/reset.c:33
+msgid "soft"
+msgstr ""
+
+#: builtin/reset.c:33
+msgid "hard"
+msgstr ""
+
+#: builtin/reset.c:33
+msgid "keep"
+msgstr ""
+
+#: builtin/reset.c:77
+msgid "You do not have a valid HEAD."
+msgstr ""
+
+#: builtin/reset.c:79
+msgid "Failed to find tree of HEAD."
+msgstr ""
+
+#: builtin/reset.c:85
+#, c-format
+msgid "Failed to find tree of %s."
+msgstr ""
+
+#: builtin/reset.c:96
+msgid "Could not write new index file."
+msgstr ""
+
+#: builtin/reset.c:106
+#, c-format
+msgid "HEAD is now at %s"
+msgstr ""
+
+#: builtin/reset.c:130
+msgid "Could not read index"
+msgstr ""
+
+#: builtin/reset.c:133
+msgid "Unstaged changes after reset:"
+msgstr ""
+
+#: builtin/reset.c:223
+#, c-format
+msgid "Cannot do a %s reset in the middle of a merge."
+msgstr ""
+
+#: builtin/reset.c:297
+#, c-format
+msgid "Could not parse object '%s'."
+msgstr ""
+
+#: builtin/reset.c:302
+msgid "--patch is incompatible with --{hard,mixed,soft}"
+msgstr ""
+
+#: builtin/reset.c:311
+msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
+msgstr ""
+
+#: builtin/reset.c:313
+#, c-format
+msgid "Cannot do %s reset with paths."
+msgstr ""
+
+#: builtin/reset.c:325
+#, c-format
+msgid "%s reset is not allowed in a bare repository"
+msgstr ""
+
+#: builtin/reset.c:341
+#, c-format
+msgid "Could not reset index file to revision '%s'."
+msgstr ""
+
+#: builtin/revert.c:70 builtin/revert.c:91
+#, c-format
+msgid "%s: %s cannot be used with %s"
+msgstr ""
+
+#: builtin/revert.c:126
+msgid "program error"
+msgstr ""
+
+#: builtin/revert.c:209
+msgid "revert failed"
+msgstr ""
+
+#: builtin/revert.c:224
+msgid "cherry-pick failed"
+msgstr ""
+
+#: builtin/rm.c:109
+#, c-format
+msgid ""
+"'%s' has staged content different from both the file and the HEAD\n"
+"(use -f to force removal)"
+msgstr ""
+
+#: builtin/rm.c:115
+#, c-format
+msgid ""
+"'%s' has changes staged in the index\n"
+"(use --cached to keep the file, or -f to force removal)"
+msgstr ""
+
+#: builtin/rm.c:119
+#, c-format
+msgid ""
+"'%s' has local modifications\n"
+"(use --cached to keep the file, or -f to force removal)"
+msgstr ""
+
+#: builtin/rm.c:194
+#, c-format
+msgid "not removing '%s' recursively without -r"
+msgstr ""
+
+#: builtin/rm.c:230
+#, c-format
+msgid "git rm: unable to remove %s"
+msgstr ""
+
+#: builtin/shortlog.c:157
+#, c-format
+msgid "Missing author: %s"
+msgstr ""
+
+#: builtin/tag.c:58
+#, c-format
+msgid "malformed object at '%s'"
+msgstr ""
+
+#: builtin/tag.c:205
+#, c-format
+msgid "tag name too long: %.*s..."
+msgstr ""
+
+#: builtin/tag.c:210
+#, c-format
+msgid "tag '%s' not found."
+msgstr ""
+
+#: builtin/tag.c:225
+#, c-format
+msgid "Deleted tag '%s' (was %s)\n"
+msgstr ""
+
+#: builtin/tag.c:237
+#, c-format
+msgid "could not verify the tag '%s'"
+msgstr ""
+
+#: builtin/tag.c:247
+msgid ""
+"\n"
+"#\n"
+"# Write a tag message\n"
+"# Lines starting with '#' will be ignored.\n"
+"#\n"
+msgstr ""
+
+#: builtin/tag.c:254
+msgid ""
+"\n"
+"#\n"
+"# Write a tag message\n"
+"# Lines starting with '#' will be kept; you may remove them yourself if you "
+"want to.\n"
+"#\n"
+msgstr ""
+
+#: builtin/tag.c:294
+msgid "unable to sign the tag"
+msgstr ""
+
+#: builtin/tag.c:296
+msgid "unable to write tag file"
+msgstr ""
+
+#: builtin/tag.c:321
+msgid "bad object type."
+msgstr ""
+
+#: builtin/tag.c:334
+msgid "tag header too big."
+msgstr ""
+
+#: builtin/tag.c:366
+msgid "no tag message?"
+msgstr ""
+
+#: builtin/tag.c:372
+#, c-format
+msgid "The tag message has been left in %s\n"
+msgstr ""
+
+#: builtin/tag.c:421
+msgid "switch 'points-at' requires an object"
+msgstr ""
+
+#: builtin/tag.c:423
+#, c-format
+msgid "malformed object name '%s'"
+msgstr ""
+
+#: builtin/tag.c:502
+msgid "-n option is only allowed with -l."
+msgstr ""
+
+#: builtin/tag.c:504
+msgid "--contains option is only allowed with -l."
+msgstr ""
+
+#: builtin/tag.c:506
+msgid "--points-at option is only allowed with -l."
+msgstr ""
+
+#: builtin/tag.c:514
+msgid "only one -F or -m option is allowed."
+msgstr ""
+
+#: builtin/tag.c:534
+msgid "too many params"
+msgstr ""
+
+#: builtin/tag.c:540
+#, c-format
+msgid "'%s' is not a valid tag name."
+msgstr ""
+
+#: builtin/tag.c:545
+#, c-format
+msgid "tag '%s' already exists"
+msgstr ""
+
+#: builtin/tag.c:563
+#, c-format
+msgid "%s: cannot lock the ref"
+msgstr ""
+
+#: builtin/tag.c:565
+#, c-format
+msgid "%s: cannot update the ref"
+msgstr ""
+
+#: builtin/tag.c:567
+#, c-format
+msgid "Updated tag '%s' (was %s)\n"
+msgstr ""
+
+#: git-am.sh:49
+msgid "You need to set your committer info first"
+msgstr ""
+
+#: git-am.sh:135
+msgid "Repository lacks necessary blobs to fall back on 3-way merge."
+msgstr ""
+
+#: git-am.sh:144
+msgid ""
+"Did you hand edit your patch?\n"
+"It does not apply to blobs recorded in its index."
+msgstr ""
+
+#: git-am.sh:153
+msgid "Falling back to patching base and 3-way merge..."
+msgstr ""
+
+#: git-am.sh:265
+msgid "Only one StGIT patch series can be applied at once"
+msgstr ""
+
+#: git-am.sh:352
+#, sh-format
+msgid "Patch format $patch_format is not supported."
+msgstr ""
+
+#: git-am.sh:354
+msgid "Patch format detection failed."
+msgstr ""
+
+#: git-am.sh:406
+msgid "-d option is no longer supported.  Do not use."
+msgstr ""
+
+#: git-am.sh:469
+#, sh-format
+msgid "previous rebase directory $dotest still exists but mbox given."
+msgstr ""
+
+#: git-am.sh:474
+msgid "Please make up your mind. --skip or --abort?"
+msgstr ""
+
+#: git-am.sh:501
+msgid "Resolve operation not in progress, we are not resuming."
+msgstr ""
+
+#: git-am.sh:567
+#, sh-format
+msgid "Dirty index: cannot apply patches (dirty: $files)"
+msgstr ""
+
+#: git-am.sh:743
+msgid "cannot be interactive without stdin connected to a terminal."
+msgstr ""
+
+#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
+#. in your translation. The program will only accept English
+#. input at this point.
+#: git-am.sh:754
+msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
+msgstr ""
+
+#: git-am.sh:790
+#, sh-format
+msgid "Applying: $FIRSTLINE"
+msgstr ""
+
+#: git-am.sh:835
+msgid "No changes -- Patch already applied."
+msgstr ""
+
+#: git-am.sh:861
+msgid "applying to an empty history"
+msgstr ""
+
+#. TRANSLATORS: Make sure to include [Y] and [n] in your
+#. translation. The program will only accept English input
+#. at this point.
+#: git-bisect.sh:54
+msgid "Do you want me to do it for you [Y/n]? "
+msgstr ""
+
+#: git-bisect.sh:95
+#, sh-format
+msgid "unrecognised option: '$arg'"
+msgstr ""
+
+#: git-bisect.sh:99
+#, sh-format
+msgid "'$arg' does not appear to be a valid revision"
+msgstr ""
+
+#: git-bisect.sh:117
+msgid "Bad HEAD - I need a HEAD"
+msgstr ""
+
+#: git-bisect.sh:130
+#, sh-format
+msgid ""
+"Checking out '$start_head' failed. Try 'git bisect reset <validbranch>'."
+msgstr ""
+
+#: git-bisect.sh:140
+msgid "won't bisect on seeked tree"
+msgstr ""
+
+#: git-bisect.sh:144
+msgid "Bad HEAD - strange symbolic ref"
+msgstr ""
+
+#: git-bisect.sh:189
+#, sh-format
+msgid "Bad bisect_write argument: $state"
+msgstr ""
+
+#: git-bisect.sh:218
+#, sh-format
+msgid "Bad rev input: $arg"
+msgstr ""
+
+#: git-bisect.sh:232
+msgid "Please call 'bisect_state' with at least one argument."
+msgstr ""
+
+#: git-bisect.sh:244
+#, sh-format
+msgid "Bad rev input: $rev"
+msgstr ""
+
+#: git-bisect.sh:250
+msgid "'git bisect bad' can take only one argument."
+msgstr ""
+
+#. TRANSLATORS: Make sure to include [Y] and [n] in your
+#. translation. The program will only accept English input
+#. at this point.
+#: git-bisect.sh:279
+msgid "Are you sure [Y/n]? "
+msgstr ""
+
+#: git-bisect.sh:354
+#, sh-format
+msgid "'$invalid' is not a valid commit"
+msgstr ""
+
+#: git-bisect.sh:363
+#, sh-format
+msgid ""
+"Could not check out original HEAD '$branch'.\n"
+"Try 'git bisect reset <commit>'."
+msgstr ""
+
+#: git-bisect.sh:390
+msgid "No logfile given"
+msgstr ""
+
+#: git-bisect.sh:391
+#, sh-format
+msgid "cannot read $file for replaying"
+msgstr ""
+
+#: git-bisect.sh:408
+msgid "?? what are you talking about?"
+msgstr ""
+
+#: git-bisect.sh:474
+msgid "We are not bisecting."
+msgstr ""
+
+#: git-pull.sh:21
+msgid ""
+"Pull is not possible because you have unmerged files.\n"
+"Please, fix them up in the work tree, and then use 'git add/rm <file>'\n"
+"as appropriate to mark resolution, or use 'git commit -a'."
+msgstr ""
+
+#: git-pull.sh:25
+msgid "Pull is not possible because you have unmerged files."
+msgstr ""
+
+#: git-pull.sh:197
+msgid "updating an unborn branch with changes added to the index"
+msgstr ""
+
+#: git-pull.sh:253
+msgid "Cannot merge multiple branches into empty head"
+msgstr ""
+
+#: git-pull.sh:257
+msgid "Cannot rebase onto multiple branches"
+msgstr ""
+
+#: git-stash.sh:51
+msgid "git stash clear with parameters is unimplemented"
+msgstr ""
+
+#: git-stash.sh:74
+msgid "You do not have the initial commit yet"
+msgstr ""
+
+#: git-stash.sh:89
+msgid "Cannot save the current index state"
+msgstr ""
+
+#: git-stash.sh:123 git-stash.sh:136
+msgid "Cannot save the current worktree state"
+msgstr ""
+
+#: git-stash.sh:140
+msgid "No changes selected"
+msgstr ""
+
+#: git-stash.sh:143
+msgid "Cannot remove temporary index (can't happen)"
+msgstr ""
+
+#: git-stash.sh:156
+msgid "Cannot record working tree state"
+msgstr ""
+
+#: git-stash.sh:223
+msgid "No local changes to save"
+msgstr ""
+
+#: git-stash.sh:227
+msgid "Cannot initialize stash"
+msgstr ""
+
+#: git-stash.sh:235
+msgid "Cannot save the current status"
+msgstr ""
+
+#: git-stash.sh:253
+msgid "Cannot remove worktree changes"
+msgstr ""
+
+#: git-stash.sh:352
+msgid "No stash found."
+msgstr ""
+
+#: git-stash.sh:359
+#, sh-format
+msgid "Too many revisions specified: $REV"
+msgstr ""
+
+#: git-stash.sh:365
+#, sh-format
+msgid "$reference is not valid reference"
+msgstr ""
+
+#: git-stash.sh:393
+#, sh-format
+msgid "'$args' is not a stash-like commit"
+msgstr ""
+
+#: git-stash.sh:404
+#, sh-format
+msgid "'$args' is not a stash reference"
+msgstr ""
+
+#: git-stash.sh:412
+msgid "unable to refresh index"
+msgstr ""
+
+#: git-stash.sh:416
+msgid "Cannot apply a stash in the middle of a merge"
+msgstr ""
+
+#: git-stash.sh:424
+msgid "Conflicts in index. Try without --index."
+msgstr ""
+
+#: git-stash.sh:426
+msgid "Could not save index tree"
+msgstr ""
+
+#: git-stash.sh:460
+msgid "Cannot unstage modified files"
+msgstr ""
+
+#: git-stash.sh:491
+#, sh-format
+msgid "Dropped ${REV} ($s)"
+msgstr ""
+
+#: git-stash.sh:492
+#, sh-format
+msgid "${REV}: Could not drop stash entry"
+msgstr ""
+
+#: git-stash.sh:499
+msgid "No branch name specified"
+msgstr ""
+
+#: git-stash.sh:570
+msgid "(To restore them type \"git stash apply\")"
+msgstr ""
+
+#: git-submodule.sh:56
+#, sh-format
+msgid "cannot strip one component off url '$remoteurl'"
+msgstr ""
+
+#: git-submodule.sh:108
+#, sh-format
+msgid "No submodule mapping found in .gitmodules for path '$path'"
+msgstr ""
+
+#: git-submodule.sh:173
+#, sh-format
+msgid "Clone of '$url' into submodule path '$path' failed"
+msgstr ""
+
+#: git-submodule.sh:247
+#, sh-format
+msgid "repo URL: '$repo' must be absolute or begin with ./|../"
+msgstr ""
+
+#: git-submodule.sh:264
+#, sh-format
+msgid "'$path' already exists in the index"
+msgstr ""
+
+#: git-submodule.sh:281
+#, sh-format
+msgid "'$path' already exists and is not a valid git repo"
+msgstr ""
+
+#: git-submodule.sh:295
+#, sh-format
+msgid "Unable to checkout submodule '$path'"
+msgstr ""
+
+#: git-submodule.sh:300
+#, sh-format
+msgid "Failed to add submodule '$path'"
+msgstr ""
+
+#: git-submodule.sh:305
+#, sh-format
+msgid "Failed to register submodule '$path'"
+msgstr ""
+
+#: git-submodule.sh:347
+#, sh-format
+msgid "Entering '$prefix$path'"
+msgstr ""
+
+#: git-submodule.sh:359
+#, sh-format
+msgid "Stopping at '$path'; script returned non-zero status."
+msgstr ""
+
+#: git-submodule.sh:401
+#, sh-format
+msgid "No url found for submodule path '$path' in .gitmodules"
+msgstr ""
+
+#: git-submodule.sh:410
+#, sh-format
+msgid "Failed to register url for submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:418
+#, sh-format
+msgid "Failed to register update mode for submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:420
+#, sh-format
+msgid "Submodule '$name' ($url) registered for path '$path'"
+msgstr ""
+
+#: git-submodule.sh:519
+#, sh-format
+msgid ""
+"Submodule path '$path' not initialized\n"
+"Maybe you want to use 'update --init'?"
+msgstr ""
+
+#: git-submodule.sh:532
+#, sh-format
+msgid "Unable to find current revision in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:551
+#, sh-format
+msgid "Unable to fetch in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:565
+#, sh-format
+msgid "Unable to rebase '$sha1' in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:566
+#, sh-format
+msgid "Submodule path '$path': rebased into '$sha1'"
+msgstr ""
+
+#: git-submodule.sh:571
+#, sh-format
+msgid "Unable to merge '$sha1' in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:572
+#, sh-format
+msgid "Submodule path '$path': merged in '$sha1'"
+msgstr ""
+
+#: git-submodule.sh:577
+#, sh-format
+msgid "Unable to checkout '$sha1' in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:578
+#, sh-format
+msgid "Submodule path '$path': checked out '$sha1'"
+msgstr ""
+
+#: git-submodule.sh:600 git-submodule.sh:923
+#, sh-format
+msgid "Failed to recurse into submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:708
+msgid "--"
+msgstr ""
+
+#: git-submodule.sh:766
+#, sh-format
+msgid "  Warn: $name doesn't contain commit $sha1_src"
+msgstr ""
+
+#: git-submodule.sh:769
+#, sh-format
+msgid "  Warn: $name doesn't contain commit $sha1_dst"
+msgstr ""
+
+#: git-submodule.sh:772
+#, sh-format
+msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
+msgstr ""
+
+#: git-submodule.sh:797
+msgid "blob"
+msgstr ""
+
+#: git-submodule.sh:798
+msgid "submodule"
+msgstr ""
+
+#: git-submodule.sh:969
+#, sh-format
+msgid "Synchronizing submodule url for '$name'"
+msgstr ""
diff --git a/po/pt_PT.po b/po/pt_PT.po
new file mode 100644 (file)
index 0000000..a0e9b0c
--- /dev/null
@@ -0,0 +1,3583 @@
+# Portuguese translations for Git package.
+# Copyright (C) 2012 Marco Sousa <marcomsousa AT gmail.com>
+# This file is distributed under the same license as the Git package.
+# Contributers:
+#   - Marco Sousa <marcomsousa AT gmail.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Git\n"
+"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
+"POT-Creation-Date: 2012-03-16 20:18+0800\n"
+"PO-Revision-Date: 2012-04-01 11:26+0100\n"
+"Last-Translator: Marco Sousa <marcomsousa AT gmail.com>\n"
+"Language-Team: Portuguese\n"
+"Language: pt\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: advice.c:34
+#, c-format
+msgid "hint: %.*s\n"
+msgstr "dica: %.*s\n"
+
+#.
+#. * Message used both when 'git commit' fails and when
+#. * other commands doing a merge do.
+#.
+#: advice.c:64
+msgid ""
+"Fix them up in the work tree,\n"
+"and then use 'git add/rm <file>' as\n"
+"appropriate to mark resolution and make a commit,\n"
+"or use 'git commit -a'."
+msgstr ""
+
+#: commit.c:47
+#, c-format
+msgid "could not parse %s"
+msgstr "não consigo parsear %s"
+
+#: commit.c:49
+#, c-format
+msgid "%s %s is not a commit!"
+msgstr "%s %s não é um commit!"
+
+#: compat/obstack.c:406
+#: compat/obstack.c:408
+msgid "memory exhausted"
+msgstr "memoria exausta"
+
+#: connected.c:39
+msgid "Could not run 'git rev-list'"
+msgstr ""
+
+#: connected.c:48
+#, c-format
+msgid "failed write to rev-list: %s"
+msgstr ""
+
+#: connected.c:56
+#, c-format
+msgid "failed to close rev-list's stdin: %s"
+msgstr ""
+
+#: diff.c:105
+#, c-format
+msgid "  Failed to parse dirstat cut-off percentage '%.*s'\n"
+msgstr ""
+
+#: diff.c:110
+#, c-format
+msgid "  Unknown dirstat parameter '%.*s'\n"
+msgstr ""
+
+#: diff.c:210
+#, c-format
+msgid ""
+"Found errors in 'diff.dirstat' config variable:\n"
+"%s"
+msgstr ""
+
+#: diff.c:1336
+msgid " 0 files changed\n"
+msgstr " 0 ficheros modificados\n"
+
+#: diff.c:1340
+#, c-format
+msgid " %d file changed"
+msgid_plural " %d files changed"
+msgstr[0] " %d ficheiro modificado"
+msgstr[1] " %d ficheiros modificados"
+
+#: diff.c:1357
+#, c-format
+msgid ", %d insertion(+)"
+msgid_plural ", %d insertions(+)"
+msgstr[0] ", %d adição(+)"
+msgstr[1] ", %d adições(+)"
+
+#: diff.c:1368
+#, c-format
+msgid ", %d deletion(-)"
+msgid_plural ", %d deletions(-)"
+msgstr[0] ", %d eliminado(-)"
+msgstr[1] ", %d eliminados(-)"
+
+#: diff.c:3424
+#, c-format
+msgid ""
+"Failed to parse --dirstat/-X option parameter:\n"
+"%s"
+msgstr ""
+
+#: gpg-interface.c:59
+msgid "could not run gpg."
+msgstr "não consegue ejecutar gpg."
+
+#: gpg-interface.c:71
+msgid "gpg did not accept the data"
+msgstr ""
+
+#: gpg-interface.c:82
+msgid "gpg failed to sign the data"
+msgstr ""
+
+#: grep.c:1280
+#, c-format
+msgid "'%s': unable to read %s"
+msgstr ""
+
+#: grep.c:1297
+#, c-format
+msgid "'%s': %s"
+msgstr "'%s': %s"
+
+#: grep.c:1308
+#, c-format
+msgid "'%s': short read %s"
+msgstr ""
+
+#: help.c:287
+#, c-format
+msgid ""
+"'%s' appears to be a git command, but we were not\n"
+"able to execute it. Maybe git-%s is broken?"
+msgstr ""
+
+#: remote.c:1607
+#, c-format
+msgid "Your branch is ahead of '%s' by %d commit.\n"
+msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: remote.c:1613
+#, c-format
+msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
+msgid_plural "Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: remote.c:1621
+#, c-format
+msgid ""
+"Your branch and '%s' have diverged,\n"
+"and have %d and %d different commit each, respectively.\n"
+msgid_plural ""
+"Your branch and '%s' have diverged,\n"
+"and have %d and %d different commits each, respectively.\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: sequencer.c:120
+#: builtin/merge.c:864
+#: builtin/merge.c:985
+#: builtin/merge.c:1095
+#: builtin/merge.c:1105
+#, c-format
+msgid "Could not open '%s' for writing"
+msgstr ""
+
+#: sequencer.c:122
+#: builtin/merge.c:334
+#: builtin/merge.c:867
+#: builtin/merge.c:1097
+#: builtin/merge.c:1110
+#, c-format
+msgid "Could not write to '%s'"
+msgstr ""
+
+#: sequencer.c:143
+msgid ""
+"after resolving the conflicts, mark the corrected paths\n"
+"with 'git add <paths>' or 'git rm <paths>'"
+msgstr ""
+
+#: sequencer.c:146
+msgid ""
+"after resolving the conflicts, mark the corrected paths\n"
+"with 'git add <paths>' or 'git rm <paths>'\n"
+"and commit the result with 'git commit'"
+msgstr ""
+
+#: sequencer.c:159
+#: sequencer.c:685
+#: sequencer.c:768
+#, c-format
+msgid "Could not write to %s"
+msgstr ""
+
+#: sequencer.c:162
+#, c-format
+msgid "Error wrapping up %s"
+msgstr ""
+
+#: sequencer.c:177
+msgid "Your local changes would be overwritten by cherry-pick."
+msgstr ""
+
+#: sequencer.c:179
+msgid "Your local changes would be overwritten by revert."
+msgstr ""
+
+#: sequencer.c:182
+msgid "Commit your changes or stash them to proceed."
+msgstr ""
+
+#. TRANSLATORS: %s will be "revert" or "cherry-pick"
+#: sequencer.c:232
+#, c-format
+msgid "%s: Unable to write new index file"
+msgstr ""
+
+#: sequencer.c:298
+msgid "Your index file is unmerged."
+msgstr ""
+
+#: sequencer.c:301
+msgid "You do not have a valid HEAD"
+msgstr ""
+
+#: sequencer.c:316
+#, c-format
+msgid "Commit %s is a merge but no -m option was given."
+msgstr ""
+
+#: sequencer.c:324
+#, c-format
+msgid "Commit %s does not have parent %d"
+msgstr ""
+
+#: sequencer.c:328
+#, c-format
+msgid "Mainline was specified but commit %s is not a merge."
+msgstr ""
+
+#. TRANSLATORS: The first %s will be "revert" or
+#. "cherry-pick", the second %s a SHA1
+#: sequencer.c:339
+#, c-format
+msgid "%s: cannot parse parent commit %s"
+msgstr ""
+
+#: sequencer.c:343
+#, c-format
+msgid "Cannot get commit message for %s"
+msgstr ""
+
+#: sequencer.c:427
+#, c-format
+msgid "could not revert %s... %s"
+msgstr ""
+
+#: sequencer.c:428
+#, c-format
+msgid "could not apply %s... %s"
+msgstr ""
+
+#: sequencer.c:450
+#: sequencer.c:909
+#: builtin/log.c:288
+#: builtin/log.c:713
+#: builtin/log.c:1329
+#: builtin/log.c:1548
+#: builtin/merge.c:348
+#: builtin/shortlog.c:181
+msgid "revision walk setup failed"
+msgstr ""
+
+#: sequencer.c:453
+msgid "empty commit set passed"
+msgstr ""
+
+#: sequencer.c:461
+#, c-format
+msgid "git %s: failed to read the index"
+msgstr ""
+
+#: sequencer.c:466
+#, c-format
+msgid "git %s: failed to refresh the index"
+msgstr ""
+
+#: sequencer.c:551
+#, c-format
+msgid "Cannot %s during a %s"
+msgstr ""
+
+#: sequencer.c:573
+#, c-format
+msgid "Could not parse line %d."
+msgstr ""
+
+#: sequencer.c:578
+msgid "No commits parsed."
+msgstr "Nenhum commit parseado."
+
+#: sequencer.c:591
+#, c-format
+msgid "Could not open %s"
+msgstr ""
+
+#: sequencer.c:595
+#, c-format
+msgid "Could not read %s."
+msgstr ""
+
+#: sequencer.c:602
+#, c-format
+msgid "Unusable instruction sheet: %s"
+msgstr ""
+
+#: sequencer.c:630
+#, c-format
+msgid "Invalid key: %s"
+msgstr ""
+
+#: sequencer.c:633
+#, c-format
+msgid "Invalid value for %s: %s"
+msgstr "Valor inválido para %s: %s"
+
+#: sequencer.c:645
+#, c-format
+msgid "Malformed options sheet: %s"
+msgstr ""
+
+#: sequencer.c:666
+msgid "a cherry-pick or revert is already in progress"
+msgstr ""
+
+#: sequencer.c:667
+msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
+msgstr ""
+
+#: sequencer.c:671
+#, c-format
+msgid "Could not create sequencer directory %s"
+msgstr ""
+
+#: sequencer.c:687
+#: sequencer.c:772
+#, c-format
+msgid "Error wrapping up %s."
+msgstr ""
+
+#: sequencer.c:706
+#: sequencer.c:840
+msgid "no cherry-pick or revert in progress"
+msgstr ""
+
+#: sequencer.c:708
+msgid "cannot resolve HEAD"
+msgstr ""
+
+#: sequencer.c:710
+msgid "cannot abort from a branch yet to be born"
+msgstr ""
+
+#: sequencer.c:732
+#, c-format
+msgid "cannot open %s: %s"
+msgstr ""
+
+#: sequencer.c:735
+#, c-format
+msgid "cannot read %s: %s"
+msgstr ""
+
+#: sequencer.c:736
+msgid "unexpected end of file"
+msgstr ""
+
+#: sequencer.c:742
+#, c-format
+msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
+msgstr ""
+
+#: sequencer.c:765
+#, c-format
+msgid "Could not format %s."
+msgstr ""
+
+#: sequencer.c:927
+msgid "Can't revert as initial commit"
+msgstr ""
+
+#: sequencer.c:928
+msgid "Can't cherry-pick into empty head"
+msgstr ""
+
+#: wt-status.c:134
+msgid "Unmerged paths:"
+msgstr ""
+
+#: wt-status.c:140
+#: wt-status.c:157
+#, c-format
+msgid "  (use \"git reset %s <file>...\" to unstage)"
+msgstr ""
+
+#: wt-status.c:142
+#: wt-status.c:159
+msgid "  (use \"git rm --cached <file>...\" to unstage)"
+msgstr ""
+
+#: wt-status.c:143
+msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
+msgstr "  (usa \"git add/rm <ficheiro>...\" para marcar como resolvido)"
+
+#: wt-status.c:151
+msgid "Changes to be committed:"
+msgstr "Mudanças a serem commitadas"
+
+#: wt-status.c:169
+msgid "Changes not staged for commit:"
+msgstr ""
+
+#: wt-status.c:173
+msgid "  (use \"git add <file>...\" to update what will be committed)"
+msgstr "  (usa \"git add <ficheiro>...\" para actualizar o que vai ser commitado)"
+
+#: wt-status.c:175
+msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
+msgstr "  (usa \"git add/rm <ficheiro>...\" para actualizar o que vai ser commitado)"
+
+#: wt-status.c:176
+msgid "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
+msgstr ""
+
+#: wt-status.c:178
+msgid "  (commit or discard the untracked or modified content in submodules)"
+msgstr ""
+
+#: wt-status.c:187
+#, c-format
+msgid "%s files:"
+msgstr "%s ficheros:"
+
+#: wt-status.c:190
+#, c-format
+msgid "  (use \"git %s <file>...\" to include in what will be committed)"
+msgstr ""
+
+#: wt-status.c:207
+msgid "bug"
+msgstr "erro"
+
+#: wt-status.c:212
+msgid "both deleted:"
+msgstr ""
+
+#: wt-status.c:213
+msgid "added by us:"
+msgstr ""
+
+#: wt-status.c:214
+msgid "deleted by them:"
+msgstr ""
+
+#: wt-status.c:215
+msgid "added by them:"
+msgstr ""
+
+#: wt-status.c:216
+msgid "deleted by us:"
+msgstr ""
+
+#: wt-status.c:217
+msgid "both added:"
+msgstr ""
+
+#: wt-status.c:218
+msgid "both modified:"
+msgstr ""
+
+#: wt-status.c:248
+msgid "new commits, "
+msgstr "novos commits, "
+
+#: wt-status.c:250
+msgid "modified content, "
+msgstr ""
+
+#: wt-status.c:252
+msgid "untracked content, "
+msgstr ""
+
+#: wt-status.c:266
+#, c-format
+msgid "new file:   %s"
+msgstr "novo ficheiro:   %s"
+
+#: wt-status.c:269
+#, c-format
+msgid "copied:     %s -> %s"
+msgstr "copiado:     %s -> %s"
+
+#: wt-status.c:272
+#, c-format
+msgid "deleted:    %s"
+msgstr "eliminado:    %s"
+
+#: wt-status.c:275
+#, c-format
+msgid "modified:   %s"
+msgstr "modificado:   %s"
+
+#: wt-status.c:278
+#, c-format
+msgid "renamed:    %s -> %s"
+msgstr "mudado de nome:    %s -> %s"
+
+#: wt-status.c:281
+#, c-format
+msgid "typechange: %s"
+msgstr ""
+
+#: wt-status.c:284
+#, c-format
+msgid "unknown:    %s"
+msgstr "desconhecido:    %s"
+
+#: wt-status.c:287
+#, c-format
+msgid "unmerged:   %s"
+msgstr ""
+
+#: wt-status.c:290
+#, c-format
+msgid "bug: unhandled diff status %c"
+msgstr ""
+
+#: wt-status.c:713
+msgid "On branch "
+msgstr "Na rama"
+
+#: wt-status.c:720
+msgid "Not currently on any branch."
+msgstr ""
+
+#: wt-status.c:731
+msgid "Initial commit"
+msgstr "Commit inicial"
+
+#: wt-status.c:745
+msgid "Untracked"
+msgstr ""
+
+#: wt-status.c:747
+msgid "Ignored"
+msgstr "Ignorado"
+
+#: wt-status.c:749
+#, c-format
+msgid "Untracked files not listed%s"
+msgstr ""
+
+#: wt-status.c:751
+msgid " (use -u option to show untracked files)"
+msgstr ""
+
+#: wt-status.c:757
+msgid "No changes"
+msgstr "Sem mudanças"
+
+#: wt-status.c:761
+#, c-format
+msgid "no changes added to commit%s\n"
+msgstr ""
+
+#: wt-status.c:763
+msgid " (use \"git add\" and/or \"git commit -a\")"
+msgstr " (usa \"git add\" e/ou \"git commit -a\")"
+
+#: wt-status.c:765
+#, c-format
+msgid "nothing added to commit but untracked files present%s\n"
+msgstr ""
+
+#: wt-status.c:767
+msgid " (use \"git add\" to track)"
+msgstr " (usa \"git add\" para seguir)"
+
+#: wt-status.c:769
+#: wt-status.c:772
+#: wt-status.c:775
+#, c-format
+msgid "nothing to commit%s\n"
+msgstr "nada para fazer commit%s\n"
+
+#: wt-status.c:770
+msgid " (create/copy files and use \"git add\" to track)"
+msgstr ""
+
+#: wt-status.c:773
+msgid " (use -u to show untracked files)"
+msgstr ""
+
+#: wt-status.c:776
+msgid " (working directory clean)"
+msgstr " (directório de trabalho vacio)"
+
+#: wt-status.c:884
+msgid "HEAD (no branch)"
+msgstr "HEAD (Não é rama)"
+
+#: wt-status.c:890
+msgid "Initial commit on "
+msgstr "Commit inicial em "
+
+#: wt-status.c:905
+msgid "behind "
+msgstr "atrás "
+
+#: wt-status.c:908
+#: wt-status.c:911
+msgid "ahead "
+msgstr "a frente "
+
+#: wt-status.c:913
+msgid ", behind "
+msgstr ", atrás "
+
+#: builtin/add.c:62
+#, c-format
+msgid "unexpected diff status %c"
+msgstr ""
+
+#: builtin/add.c:67
+#: builtin/commit.c:298
+msgid "updating files failed"
+msgstr ""
+
+#: builtin/add.c:77
+#, c-format
+msgid "remove '%s'\n"
+msgstr "eliminar '%s'\n"
+
+#: builtin/add.c:176
+#, c-format
+msgid "Path '%s' is in submodule '%.*s'"
+msgstr ""
+
+#: builtin/add.c:192
+msgid "Unstaged changes after refreshing the index:"
+msgstr ""
+
+#: builtin/add.c:195
+#: builtin/add.c:456
+#: builtin/rm.c:186
+#, c-format
+msgid "pathspec '%s' did not match any files"
+msgstr ""
+
+#: builtin/add.c:209
+#, c-format
+msgid "'%s' is beyond a symbolic link"
+msgstr ""
+
+#: builtin/add.c:276
+msgid "Could not read the index"
+msgstr ""
+
+#: builtin/add.c:286
+#, c-format
+msgid "Could not open '%s' for writing."
+msgstr ""
+
+#: builtin/add.c:290
+msgid "Could not write patch"
+msgstr ""
+
+#: builtin/add.c:295
+#, c-format
+msgid "Could not stat '%s'"
+msgstr ""
+
+#: builtin/add.c:297
+msgid "Empty patch. Aborted."
+msgstr ""
+
+#: builtin/add.c:303
+#, c-format
+msgid "Could not apply '%s'"
+msgstr ""
+
+#: builtin/add.c:312
+msgid "The following paths are ignored by one of your .gitignore files:\n"
+msgstr ""
+
+#: builtin/add.c:352
+#, c-format
+msgid "Use -f if you really want to add them.\n"
+msgstr ""
+
+#: builtin/add.c:353
+msgid "no files added"
+msgstr "nenhum ficheiros adicionado"
+
+#: builtin/add.c:359
+msgid "adding files failed"
+msgstr ""
+
+#: builtin/add.c:391
+msgid "-A and -u are mutually incompatible"
+msgstr ""
+
+#: builtin/add.c:393
+msgid "Option --ignore-missing can only be used together with --dry-run"
+msgstr ""
+
+#: builtin/add.c:413
+#, c-format
+msgid "Nothing specified, nothing added.\n"
+msgstr ""
+
+#: builtin/add.c:414
+#, c-format
+msgid "Maybe you wanted to say 'git add .'?\n"
+msgstr ""
+
+#: builtin/add.c:420
+#: builtin/clean.c:95
+#: builtin/commit.c:358
+#: builtin/mv.c:82
+#: builtin/rm.c:162
+msgid "index file corrupt"
+msgstr ""
+
+#: builtin/add.c:476
+#: builtin/mv.c:229
+#: builtin/rm.c:260
+msgid "Unable to write new index file"
+msgstr ""
+
+#: builtin/archive.c:17
+#, c-format
+msgid "could not create archive file '%s'"
+msgstr ""
+
+#: builtin/archive.c:20
+msgid "could not redirect output"
+msgstr ""
+
+#: builtin/archive.c:37
+msgid "git archive: Remote with no URL"
+msgstr ""
+
+#: builtin/archive.c:58
+msgid "git archive: expected ACK/NAK, got EOF"
+msgstr ""
+
+#: builtin/archive.c:63
+#, c-format
+msgid "git archive: NACK %s"
+msgstr ""
+
+#: builtin/archive.c:65
+#, c-format
+msgid "remote error: %s"
+msgstr ""
+
+#: builtin/archive.c:66
+msgid "git archive: protocol error"
+msgstr ""
+
+#: builtin/archive.c:71
+msgid "git archive: expected a flush"
+msgstr ""
+
+#: builtin/branch.c:137
+#, c-format
+msgid ""
+"deleting branch '%s' that has been merged to\n"
+"         '%s', but not yet merged to HEAD."
+msgstr ""
+
+#: builtin/branch.c:141
+#, c-format
+msgid ""
+"not deleting branch '%s' that is not yet merged to\n"
+"         '%s', even though it is merged to HEAD."
+msgstr ""
+
+#. TRANSLATORS: This is "remote " in "remote branch '%s' not found"
+#: builtin/branch.c:163
+msgid "remote "
+msgstr "remota"
+
+#: builtin/branch.c:171
+msgid "cannot use -a with -d"
+msgstr ""
+
+#: builtin/branch.c:177
+msgid "Couldn't look up commit object for HEAD"
+msgstr ""
+
+#: builtin/branch.c:182
+#, c-format
+msgid "Cannot delete the branch '%s' which you are currently on."
+msgstr ""
+
+#: builtin/branch.c:192
+#, c-format
+msgid "%sbranch '%s' not found."
+msgstr ""
+
+#: builtin/branch.c:200
+#, c-format
+msgid "Couldn't look up commit object for '%s'"
+msgstr ""
+
+#: builtin/branch.c:206
+#, c-format
+msgid ""
+"The branch '%s' is not fully merged.\n"
+"If you are sure you want to delete it, run 'git branch -D %s'."
+msgstr ""
+
+#: builtin/branch.c:214
+#, c-format
+msgid "Error deleting %sbranch '%s'"
+msgstr ""
+
+#: builtin/branch.c:219
+#, c-format
+msgid "Deleted %sbranch %s (was %s).\n"
+msgstr ""
+
+#: builtin/branch.c:224
+msgid "Update of config-file failed"
+msgstr ""
+
+#: builtin/branch.c:322
+#, c-format
+msgid "branch '%s' does not point at a commit"
+msgstr ""
+
+#: builtin/branch.c:394
+#, c-format
+msgid "behind %d] "
+msgstr ""
+
+#: builtin/branch.c:396
+#, c-format
+msgid "ahead %d] "
+msgstr ""
+
+#: builtin/branch.c:398
+#, c-format
+msgid "ahead %d, behind %d] "
+msgstr ""
+
+#: builtin/branch.c:501
+msgid "(no branch)"
+msgstr "(não é rama)"
+
+#: builtin/branch.c:566
+msgid "some refs could not be read"
+msgstr ""
+
+#: builtin/branch.c:579
+msgid "cannot rename the current branch while not on any."
+msgstr ""
+
+#: builtin/branch.c:589
+#, c-format
+msgid "Invalid branch name: '%s'"
+msgstr ""
+
+#: builtin/branch.c:604
+msgid "Branch rename failed"
+msgstr ""
+
+#: builtin/branch.c:608
+#, c-format
+msgid "Renamed a misnamed branch '%s' away"
+msgstr ""
+
+#: builtin/branch.c:612
+#, c-format
+msgid "Branch renamed to %s, but HEAD is not updated!"
+msgstr ""
+
+#: builtin/branch.c:619
+msgid "Branch is renamed, but update of config-file failed"
+msgstr ""
+
+#: builtin/branch.c:634
+#, c-format
+msgid "malformed object name %s"
+msgstr ""
+
+#: builtin/branch.c:658
+#, c-format
+msgid "could not write branch description template: %s\n"
+msgstr ""
+
+#: builtin/branch.c:746
+msgid "Failed to resolve HEAD as a valid ref."
+msgstr ""
+
+#: builtin/branch.c:751
+#: builtin/clone.c:558
+msgid "HEAD not found below refs/heads!"
+msgstr ""
+
+#: builtin/branch.c:809
+msgid "-a and -r options to 'git branch' do not make sense with a branch name"
+msgstr ""
+
+#: builtin/bundle.c:47
+#, c-format
+msgid "%s is okay\n"
+msgstr "%s está bem\n"
+
+#: builtin/bundle.c:56
+msgid "Need a repository to create a bundle."
+msgstr ""
+
+#: builtin/bundle.c:60
+msgid "Need a repository to unbundle."
+msgstr ""
+
+#: builtin/checkout.c:113
+#: builtin/checkout.c:146
+#, c-format
+msgid "path '%s' does not have our version"
+msgstr ""
+
+#: builtin/checkout.c:115
+#: builtin/checkout.c:148
+#, c-format
+msgid "path '%s' does not have their version"
+msgstr ""
+
+#: builtin/checkout.c:131
+#, c-format
+msgid "path '%s' does not have all necessary versions"
+msgstr ""
+
+#: builtin/checkout.c:175
+#, c-format
+msgid "path '%s' does not have necessary versions"
+msgstr ""
+
+#: builtin/checkout.c:192
+#, c-format
+msgid "path '%s': cannot merge"
+msgstr ""
+
+#: builtin/checkout.c:209
+#, c-format
+msgid "Unable to add merge result for '%s'"
+msgstr ""
+
+#: builtin/checkout.c:212
+#: builtin/reset.c:158
+#, c-format
+msgid "make_cache_entry failed for path '%s'"
+msgstr ""
+
+#: builtin/checkout.c:234
+#: builtin/checkout.c:392
+msgid "corrupt index file"
+msgstr ""
+
+#: builtin/checkout.c:264
+#: builtin/checkout.c:271
+#, c-format
+msgid "path '%s' is unmerged"
+msgstr ""
+
+#: builtin/checkout.c:302
+#: builtin/checkout.c:498
+#: builtin/clone.c:583
+#: builtin/merge.c:811
+msgid "unable to write new index file"
+msgstr ""
+
+#: builtin/checkout.c:319
+#: builtin/diff.c:302
+#: builtin/merge.c:408
+msgid "diff_setup_done failed"
+msgstr ""
+
+#: builtin/checkout.c:414
+msgid "you need to resolve your current index first"
+msgstr ""
+
+#: builtin/checkout.c:533
+#, c-format
+msgid "Can not do reflog for '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:565
+msgid "HEAD is now at"
+msgstr "HEAD é agora em "
+
+#: builtin/checkout.c:572
+#, c-format
+msgid "Reset branch '%s'\n"
+msgstr "Reset rama '%s'\n"
+
+#: builtin/checkout.c:575
+#, c-format
+msgid "Already on '%s'\n"
+msgstr "Já em '%s'\n"
+
+#: builtin/checkout.c:579
+#, c-format
+msgid "Switched to and reset branch '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:581
+#, c-format
+msgid "Switched to a new branch '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:583
+#, c-format
+msgid "Switched to branch '%s'\n"
+msgstr ""
+
+#: builtin/checkout.c:639
+#, c-format
+msgid " ... and %d more.\n"
+msgstr ""
+
+#. The singular version
+#: builtin/checkout.c:645
+#, c-format
+msgid ""
+"Warning: you are leaving %d commit behind, not connected to\n"
+"any of your branches:\n"
+"\n"
+"%s\n"
+msgid_plural ""
+"Warning: you are leaving %d commits behind, not connected to\n"
+"any of your branches:\n"
+"\n"
+"%s\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: builtin/checkout.c:663
+#, c-format
+msgid ""
+"If you want to keep them by creating a new branch, this may be a good time\n"
+"to do so with:\n"
+"\n"
+" git branch new_branch_name %s\n"
+"\n"
+msgstr ""
+
+#: builtin/checkout.c:692
+msgid "internal error in revision walk"
+msgstr ""
+
+#: builtin/checkout.c:696
+msgid "Previous HEAD position was"
+msgstr ""
+
+#: builtin/checkout.c:722
+msgid "You are on a branch yet to be born"
+msgstr ""
+
+#. case (1)
+#: builtin/checkout.c:853
+#, c-format
+msgid "invalid reference: %s"
+msgstr ""
+
+#. case (1): want a tree
+#: builtin/checkout.c:892
+#, c-format
+msgid "reference is not a tree: %s"
+msgstr ""
+
+#: builtin/checkout.c:972
+msgid "-B cannot be used with -b"
+msgstr ""
+
+#: builtin/checkout.c:981
+msgid "--patch is incompatible with all other options"
+msgstr ""
+
+#: builtin/checkout.c:984
+msgid "--detach cannot be used with -b/-B/--orphan"
+msgstr ""
+
+#: builtin/checkout.c:986
+msgid "--detach cannot be used with -t"
+msgstr ""
+
+#: builtin/checkout.c:992
+msgid "--track needs a branch name"
+msgstr ""
+
+#: builtin/checkout.c:999
+msgid "Missing branch name; try -b"
+msgstr ""
+
+#: builtin/checkout.c:1005
+msgid "--orphan and -b|-B are mutually exclusive"
+msgstr ""
+
+#: builtin/checkout.c:1007
+msgid "--orphan cannot be used with -t"
+msgstr ""
+
+#: builtin/checkout.c:1017
+msgid "git checkout: -f and -m are incompatible"
+msgstr ""
+
+#: builtin/checkout.c:1051
+msgid "invalid path specification"
+msgstr ""
+
+#: builtin/checkout.c:1059
+#, c-format
+msgid ""
+"git checkout: updating paths is incompatible with switching branches.\n"
+"Did you intend to checkout '%s' which can not be resolved as commit?"
+msgstr ""
+
+#: builtin/checkout.c:1061
+msgid "git checkout: updating paths is incompatible with switching branches."
+msgstr ""
+
+#: builtin/checkout.c:1066
+msgid "git checkout: --detach does not take a path argument"
+msgstr ""
+
+#: builtin/checkout.c:1069
+msgid ""
+"git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
+"checking out of the index."
+msgstr ""
+
+#: builtin/checkout.c:1088
+msgid "Cannot switch branch to a non-commit."
+msgstr ""
+
+#: builtin/checkout.c:1091
+msgid "--ours/--theirs is incompatible with switching branches."
+msgstr ""
+
+#: builtin/clean.c:78
+msgid "-x and -X cannot be used together"
+msgstr ""
+
+#: builtin/clean.c:82
+msgid "clean.requireForce set to true and neither -n nor -f given; refusing to clean"
+msgstr ""
+
+#: builtin/clean.c:85
+msgid "clean.requireForce defaults to true and neither -n nor -f given; refusing to clean"
+msgstr ""
+
+#: builtin/clean.c:155
+#: builtin/clean.c:176
+#, c-format
+msgid "Would remove %s\n"
+msgstr ""
+
+#: builtin/clean.c:159
+#: builtin/clean.c:179
+#, c-format
+msgid "Removing %s\n"
+msgstr ""
+
+#: builtin/clean.c:162
+#: builtin/clean.c:182
+#, c-format
+msgid "failed to remove %s"
+msgstr ""
+
+#: builtin/clean.c:166
+#, c-format
+msgid "Would not remove %s\n"
+msgstr ""
+
+#: builtin/clean.c:168
+#, c-format
+msgid "Not removing %s\n"
+msgstr ""
+
+#: builtin/clone.c:243
+#, c-format
+msgid "reference repository '%s' is not a local directory."
+msgstr ""
+
+#: builtin/clone.c:302
+#, c-format
+msgid "failed to open '%s'"
+msgstr ""
+
+#: builtin/clone.c:306
+#, c-format
+msgid "failed to create directory '%s'"
+msgstr ""
+
+#: builtin/clone.c:308
+#: builtin/diff.c:75
+#, c-format
+msgid "failed to stat '%s'"
+msgstr ""
+
+#: builtin/clone.c:310
+#, c-format
+msgid "%s exists and is not a directory"
+msgstr ""
+
+#: builtin/clone.c:324
+#, c-format
+msgid "failed to stat %s\n"
+msgstr ""
+
+#: builtin/clone.c:341
+#, c-format
+msgid "failed to unlink '%s'"
+msgstr ""
+
+#: builtin/clone.c:346
+#, c-format
+msgid "failed to create link '%s'"
+msgstr ""
+
+#: builtin/clone.c:350
+#, c-format
+msgid "failed to copy file to '%s'"
+msgstr ""
+
+#: builtin/clone.c:373
+#, c-format
+msgid "done.\n"
+msgstr "terminado.\n"
+
+#: builtin/clone.c:440
+#, c-format
+msgid "Could not find remote branch %s to clone."
+msgstr ""
+
+#: builtin/clone.c:549
+msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
+msgstr ""
+
+#: builtin/clone.c:639
+msgid "Too many arguments."
+msgstr ""
+
+#: builtin/clone.c:643
+msgid "You must specify a repository to clone."
+msgstr ""
+
+#: builtin/clone.c:654
+#, c-format
+msgid "--bare and --origin %s options are incompatible."
+msgstr ""
+
+#: builtin/clone.c:668
+#, c-format
+msgid "repository '%s' does not exist"
+msgstr ""
+
+#: builtin/clone.c:673
+msgid "--depth is ignored in local clones; use file:// instead."
+msgstr ""
+
+#: builtin/clone.c:683
+#, c-format
+msgid "destination path '%s' already exists and is not an empty directory."
+msgstr ""
+
+#: builtin/clone.c:693
+#, c-format
+msgid "working tree '%s' already exists."
+msgstr ""
+
+#: builtin/clone.c:706
+#: builtin/clone.c:720
+#, c-format
+msgid "could not create leading directories of '%s'"
+msgstr ""
+
+#: builtin/clone.c:709
+#, c-format
+msgid "could not create work tree dir '%s'."
+msgstr ""
+
+#: builtin/clone.c:728
+#, c-format
+msgid "Cloning into bare repository '%s'...\n"
+msgstr ""
+
+#: builtin/clone.c:730
+#, c-format
+msgid "Cloning into '%s'...\n"
+msgstr ""
+
+#: builtin/clone.c:786
+#, c-format
+msgid "Don't know how to clone %s"
+msgstr ""
+
+#: builtin/clone.c:835
+#, c-format
+msgid "Remote branch %s not found in upstream %s"
+msgstr ""
+
+#: builtin/clone.c:842
+msgid "You appear to have cloned an empty repository."
+msgstr ""
+
+#: builtin/commit.c:42
+msgid ""
+"Your name and email address were configured automatically based\n"
+"on your username and hostname. Please check that they are accurate.\n"
+"You can suppress this message by setting them explicitly:\n"
+"\n"
+"    git config --global user.name \"Your Name\"\n"
+"    git config --global user.email you@example.com\n"
+"\n"
+"After doing this, you may fix the identity used for this commit with:\n"
+"\n"
+"    git commit --amend --reset-author\n"
+msgstr ""
+
+#: builtin/commit.c:54
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/commit.c:59
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/commit.c:205
+#: builtin/reset.c:33
+msgid "merge"
+msgstr "juntar"
+
+#: builtin/commit.c:208
+msgid "cherry-pick"
+msgstr "cherry-pick"
+
+#: builtin/commit.c:325
+msgid "failed to unpack HEAD tree object"
+msgstr ""
+
+#: builtin/commit.c:367
+msgid "unable to create temporary index"
+msgstr ""
+
+#: builtin/commit.c:373
+msgid "interactive add failed"
+msgstr ""
+
+#: builtin/commit.c:406
+#: builtin/commit.c:427
+#: builtin/commit.c:473
+msgid "unable to write new_index file"
+msgstr ""
+
+#: builtin/commit.c:457
+#, c-format
+msgid "cannot do a partial commit during a %s."
+msgstr ""
+
+#: builtin/commit.c:466
+msgid "cannot read the index"
+msgstr ""
+
+#: builtin/commit.c:486
+msgid "unable to write temporary index file"
+msgstr ""
+
+#: builtin/commit.c:550
+#: builtin/commit.c:556
+#, c-format
+msgid "invalid commit: %s"
+msgstr "commit inválido: %s"
+
+#: builtin/commit.c:579
+msgid "malformed --author parameter"
+msgstr ""
+
+#: builtin/commit.c:635
+#, c-format
+msgid "Malformed ident string: '%s'"
+msgstr ""
+
+#: builtin/commit.c:670
+#: builtin/commit.c:703
+#: builtin/commit.c:1000
+#, c-format
+msgid "could not lookup commit %s"
+msgstr ""
+
+#: builtin/commit.c:682
+#: builtin/shortlog.c:296
+#, c-format
+msgid "(reading log message from standard input)\n"
+msgstr ""
+
+#: builtin/commit.c:684
+msgid "could not read log from standard input"
+msgstr ""
+
+#: builtin/commit.c:688
+#, c-format
+msgid "could not read log file '%s'"
+msgstr ""
+
+#: builtin/commit.c:694
+msgid "commit has empty message"
+msgstr ""
+
+#: builtin/commit.c:710
+msgid "could not read MERGE_MSG"
+msgstr ""
+
+#: builtin/commit.c:714
+msgid "could not read SQUASH_MSG"
+msgstr ""
+
+#: builtin/commit.c:718
+#, c-format
+msgid "could not read '%s'"
+msgstr ""
+
+#: builtin/commit.c:746
+#, c-format
+msgid "could not open '%s'"
+msgstr ""
+
+#: builtin/commit.c:770
+msgid "could not write commit template"
+msgstr ""
+
+#: builtin/commit.c:783
+#, c-format
+msgid ""
+"\n"
+"It looks like you may be committing a %s.\n"
+"If this is not correct, please remove the file\n"
+"\t%s\n"
+"and try again.\n"
+msgstr ""
+
+#: builtin/commit.c:796
+msgid "Please enter the commit message for your changes."
+msgstr ""
+
+#: builtin/commit.c:799
+msgid ""
+" Lines starting\n"
+"with '#' will be ignored, and an empty message aborts the commit.\n"
+msgstr ""
+
+#: builtin/commit.c:804
+msgid ""
+" Lines starting\n"
+"with '#' will be kept; you may remove them yourself if you want to.\n"
+"An empty message aborts the commit.\n"
+msgstr ""
+
+#: builtin/commit.c:816
+#, c-format
+msgid "%sAuthor:    %s"
+msgstr "%sAutor:    %s"
+
+#: builtin/commit.c:823
+#, c-format
+msgid "%sCommitter: %s"
+msgstr "%sCommitador: %s"
+
+#: builtin/commit.c:843
+msgid "Cannot read index"
+msgstr ""
+
+#: builtin/commit.c:880
+msgid "Error building trees"
+msgstr ""
+
+#: builtin/commit.c:895
+#: builtin/tag.c:357
+#, c-format
+msgid "Please supply the message using either -m or -F option.\n"
+msgstr ""
+
+#: builtin/commit.c:975
+#, c-format
+msgid "No existing author found with '%s'"
+msgstr ""
+
+#: builtin/commit.c:990
+#: builtin/commit.c:1182
+#, c-format
+msgid "Invalid untracked files mode '%s'"
+msgstr ""
+
+#: builtin/commit.c:1030
+msgid "Using both --reset-author and --author does not make sense"
+msgstr ""
+
+#: builtin/commit.c:1041
+msgid "You have nothing to amend."
+msgstr ""
+
+#: builtin/commit.c:1043
+#, c-format
+msgid "You are in the middle of a %s -- cannot amend."
+msgstr ""
+
+#: builtin/commit.c:1045
+msgid "Options --squash and --fixup cannot be used together"
+msgstr ""
+
+#: builtin/commit.c:1055
+msgid "Only one of -c/-C/-F/--fixup can be used."
+msgstr ""
+
+#: builtin/commit.c:1057
+msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
+msgstr ""
+
+#: builtin/commit.c:1063
+msgid "--reset-author can be used only with -C, -c or --amend."
+msgstr ""
+
+#: builtin/commit.c:1080
+msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
+msgstr ""
+
+#: builtin/commit.c:1082
+msgid "No paths with --include/--only does not make sense."
+msgstr ""
+
+#: builtin/commit.c:1084
+msgid "Clever... amending the last one with dirty index."
+msgstr ""
+
+#: builtin/commit.c:1086
+msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
+msgstr ""
+
+#: builtin/commit.c:1096
+#: builtin/tag.c:556
+#, c-format
+msgid "Invalid cleanup mode %s"
+msgstr ""
+
+#: builtin/commit.c:1101
+msgid "Paths with -a does not make sense."
+msgstr ""
+
+#: builtin/commit.c:1280
+msgid "couldn't look up newly created commit"
+msgstr ""
+
+#: builtin/commit.c:1282
+msgid "could not parse newly created commit"
+msgstr ""
+
+#: builtin/commit.c:1323
+msgid "detached HEAD"
+msgstr ""
+
+#: builtin/commit.c:1325
+msgid " (root-commit)"
+msgstr " (root-commit)"
+
+#: builtin/commit.c:1415
+msgid "could not parse HEAD commit"
+msgstr ""
+
+#: builtin/commit.c:1452
+#: builtin/merge.c:509
+#, c-format
+msgid "could not open '%s' for reading"
+msgstr ""
+
+#: builtin/commit.c:1459
+#, c-format
+msgid "Corrupt MERGE_HEAD file (%s)"
+msgstr ""
+
+#: builtin/commit.c:1466
+msgid "could not read MERGE_MODE"
+msgstr ""
+
+#: builtin/commit.c:1485
+#, c-format
+msgid "could not read commit message: %s"
+msgstr ""
+
+#: builtin/commit.c:1499
+#, c-format
+msgid "Aborting commit due to empty commit message.\n"
+msgstr ""
+
+#: builtin/commit.c:1514
+#: builtin/merge.c:935
+#: builtin/merge.c:968
+msgid "failed to write commit object"
+msgstr ""
+
+#: builtin/commit.c:1535
+msgid "cannot lock HEAD ref"
+msgstr ""
+
+#: builtin/commit.c:1539
+msgid "cannot update HEAD ref"
+msgstr ""
+
+#: builtin/commit.c:1550
+msgid ""
+"Repository has been updated, but unable to write\n"
+"new_index file. Check that disk is not full or quota is\n"
+"not exceeded, and then \"git reset HEAD\" to recover."
+msgstr ""
+
+#: builtin/describe.c:234
+#, c-format
+msgid "annotated tag %s not available"
+msgstr ""
+
+#: builtin/describe.c:238
+#, c-format
+msgid "annotated tag %s has no embedded name"
+msgstr ""
+
+#: builtin/describe.c:240
+#, c-format
+msgid "tag '%s' is really '%s' here"
+msgstr ""
+
+#: builtin/describe.c:267
+#, c-format
+msgid "Not a valid object name %s"
+msgstr ""
+
+#: builtin/describe.c:270
+#, c-format
+msgid "%s is not a valid '%s' object"
+msgstr ""
+
+#: builtin/describe.c:287
+#, c-format
+msgid "no tag exactly matches '%s'"
+msgstr ""
+
+#: builtin/describe.c:289
+#, c-format
+msgid "searching to describe %s\n"
+msgstr ""
+
+#: builtin/describe.c:329
+#, c-format
+msgid "finished search at %s\n"
+msgstr ""
+
+#: builtin/describe.c:353
+#, c-format
+msgid ""
+"No annotated tags can describe '%s'.\n"
+"However, there were unannotated tags: try --tags."
+msgstr ""
+
+#: builtin/describe.c:357
+#, c-format
+msgid ""
+"No tags can describe '%s'.\n"
+"Try --always, or create some tags."
+msgstr ""
+
+#: builtin/describe.c:378
+#, c-format
+msgid "traversed %lu commits\n"
+msgstr ""
+
+#: builtin/describe.c:381
+#, c-format
+msgid ""
+"more than %i tags found; listed %i most recent\n"
+"gave up search at %s\n"
+msgstr ""
+
+#: builtin/describe.c:436
+msgid "--long is incompatible with --abbrev=0"
+msgstr ""
+
+#: builtin/describe.c:462
+msgid "No names found, cannot describe anything."
+msgstr ""
+
+#: builtin/describe.c:482
+msgid "--dirty is incompatible with committishes"
+msgstr ""
+
+#: builtin/diff.c:77
+#, c-format
+msgid "'%s': not a regular file or symlink"
+msgstr ""
+
+#: builtin/diff.c:220
+#, c-format
+msgid "invalid option: %s"
+msgstr ""
+
+#: builtin/diff.c:297
+msgid "Not a git repository"
+msgstr "Não é um repositorio git"
+
+#: builtin/diff.c:347
+#, c-format
+msgid "invalid object '%s' given."
+msgstr ""
+
+#: builtin/diff.c:352
+#, c-format
+msgid "more than %d trees given: '%s'"
+msgstr ""
+
+#: builtin/diff.c:362
+#, c-format
+msgid "more than two blobs given: '%s'"
+msgstr ""
+
+#: builtin/diff.c:370
+#, c-format
+msgid "unhandled object '%s' given."
+msgstr ""
+
+#: builtin/fetch.c:200
+msgid "Couldn't find remote ref HEAD"
+msgstr ""
+
+#: builtin/fetch.c:252
+#, c-format
+msgid "object %s not found"
+msgstr ""
+
+#: builtin/fetch.c:258
+msgid "[up to date]"
+msgstr "[Actualizada]"
+
+#: builtin/fetch.c:272
+#, c-format
+msgid "! %-*s %-*s -> %s  (can't fetch in current branch)"
+msgstr ""
+
+#: builtin/fetch.c:273
+#: builtin/fetch.c:351
+msgid "[rejected]"
+msgstr "[rejeitado]"
+
+#: builtin/fetch.c:284
+msgid "[tag update]"
+msgstr "[etiqueta actualizada]"
+
+#: builtin/fetch.c:286
+#: builtin/fetch.c:313
+#: builtin/fetch.c:331
+msgid "  (unable to update local ref)"
+msgstr ""
+
+#: builtin/fetch.c:298
+msgid "[new tag]"
+msgstr "[nova etiqueta]"
+
+#: builtin/fetch.c:302
+msgid "[new branch]"
+msgstr "[nova rama]"
+
+#: builtin/fetch.c:347
+msgid "unable to update local ref"
+msgstr ""
+
+#: builtin/fetch.c:347
+msgid "forced update"
+msgstr "actualização forçada"
+
+#: builtin/fetch.c:353
+msgid "(non-fast-forward)"
+msgstr ""
+
+#: builtin/fetch.c:384
+#: builtin/fetch.c:676
+#, c-format
+msgid "cannot open %s: %s\n"
+msgstr ""
+
+#: builtin/fetch.c:393
+#, c-format
+msgid "%s did not send all necessary objects\n"
+msgstr ""
+
+#: builtin/fetch.c:479
+#, c-format
+msgid "From %.*s\n"
+msgstr "Para %.*s\n"
+
+#: builtin/fetch.c:490
+#, c-format
+msgid ""
+"some local refs could not be updated; try running\n"
+" 'git remote prune %s' to remove any old, conflicting branches"
+msgstr ""
+
+#: builtin/fetch.c:540
+#, c-format
+msgid "   (%s will become dangling)\n"
+msgstr ""
+
+#: builtin/fetch.c:541
+#, c-format
+msgid "   (%s has become dangling)\n"
+msgstr ""
+
+#: builtin/fetch.c:548
+msgid "[deleted]"
+msgstr "[eliminado]"
+
+#: builtin/fetch.c:549
+msgid "(none)"
+msgstr "(nenhum)"
+
+#: builtin/fetch.c:666
+#, c-format
+msgid "Refusing to fetch into current branch %s of non-bare repository"
+msgstr ""
+
+#: builtin/fetch.c:700
+#, c-format
+msgid "Don't know how to fetch from %s"
+msgstr ""
+
+#: builtin/fetch.c:777
+#, c-format
+msgid "Option \"%s\" value \"%s\" is not valid for %s"
+msgstr ""
+
+#: builtin/fetch.c:780
+#, c-format
+msgid "Option \"%s\" is ignored for %s\n"
+msgstr ""
+
+#: builtin/fetch.c:879
+#, c-format
+msgid "Fetching %s\n"
+msgstr ""
+
+#: builtin/fetch.c:881
+#, c-format
+msgid "Could not fetch %s"
+msgstr ""
+
+#: builtin/fetch.c:898
+msgid ""
+"No remote repository specified.  Please, specify either a URL or a\n"
+"remote name from which new revisions should be fetched."
+msgstr ""
+
+#: builtin/fetch.c:918
+msgid "You need to specify a tag name."
+msgstr ""
+
+#: builtin/fetch.c:970
+msgid "fetch --all does not take a repository argument"
+msgstr ""
+
+#: builtin/fetch.c:972
+msgid "fetch --all does not make sense with refspecs"
+msgstr ""
+
+#: builtin/fetch.c:983
+#, c-format
+msgid "No such remote or remote group: %s"
+msgstr ""
+
+#: builtin/fetch.c:991
+msgid "Fetching a group and specifying refspecs does not make sense"
+msgstr ""
+
+#: builtin/gc.c:63
+#, c-format
+msgid "Invalid %s: '%s'"
+msgstr ""
+
+#: builtin/gc.c:78
+msgid "Too many options specified"
+msgstr ""
+
+#: builtin/gc.c:103
+#, c-format
+msgid "insanely long object directory %.*s"
+msgstr ""
+
+#: builtin/gc.c:223
+#, c-format
+msgid "Auto packing the repository for optimum performance.\n"
+msgstr ""
+
+#: builtin/gc.c:226
+#, c-format
+msgid ""
+"Auto packing the repository for optimum performance. You may also\n"
+"run \"git gc\" manually. See \"git help gc\" for more information.\n"
+msgstr ""
+
+#: builtin/gc.c:256
+msgid "There are too many unreachable loose objects; run 'git prune' to remove them."
+msgstr ""
+
+#: builtin/grep.c:216
+#, c-format
+msgid "grep: failed to create thread: %s"
+msgstr ""
+
+#: builtin/grep.c:402
+#, c-format
+msgid "Failed to chdir: %s"
+msgstr ""
+
+#: builtin/grep.c:478
+#: builtin/grep.c:512
+#, c-format
+msgid "unable to read tree (%s)"
+msgstr ""
+
+#: builtin/grep.c:526
+#, c-format
+msgid "unable to grep from object of type %s"
+msgstr ""
+
+#: builtin/grep.c:584
+#, c-format
+msgid "switch `%c' expects a numerical value"
+msgstr ""
+
+#: builtin/grep.c:601
+#, c-format
+msgid "cannot open '%s'"
+msgstr ""
+
+#: builtin/grep.c:888
+msgid "no pattern given."
+msgstr ""
+
+#: builtin/grep.c:902
+#, c-format
+msgid "bad object %s"
+msgstr ""
+
+#: builtin/grep.c:943
+msgid "--open-files-in-pager only works on the worktree"
+msgstr ""
+
+#: builtin/grep.c:966
+msgid "--cached or --untracked cannot be used with --no-index."
+msgstr ""
+
+#: builtin/grep.c:971
+msgid "--no-index or --untracked cannot be used with revs."
+msgstr ""
+
+#: builtin/grep.c:974
+msgid "--[no-]exclude-standard cannot be used for tracked contents."
+msgstr ""
+
+#: builtin/grep.c:982
+msgid "both --cached and trees are given."
+msgstr ""
+
+#: builtin/init-db.c:35
+#, c-format
+msgid "Could not make %s writable by group"
+msgstr ""
+
+#: builtin/init-db.c:62
+#, c-format
+msgid "insanely long template name %s"
+msgstr ""
+
+#: builtin/init-db.c:67
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: builtin/init-db.c:73
+#, c-format
+msgid "cannot stat template '%s'"
+msgstr ""
+
+#: builtin/init-db.c:80
+#, c-format
+msgid "cannot opendir '%s'"
+msgstr ""
+
+#: builtin/init-db.c:97
+#, c-format
+msgid "cannot readlink '%s'"
+msgstr ""
+
+#: builtin/init-db.c:99
+#, c-format
+msgid "insanely long symlink %s"
+msgstr ""
+
+#: builtin/init-db.c:102
+#, c-format
+msgid "cannot symlink '%s' '%s'"
+msgstr ""
+
+#: builtin/init-db.c:106
+#, c-format
+msgid "cannot copy '%s' to '%s'"
+msgstr ""
+
+#: builtin/init-db.c:110
+#, c-format
+msgid "ignoring template %s"
+msgstr ""
+
+#: builtin/init-db.c:133
+#, c-format
+msgid "insanely long template path %s"
+msgstr ""
+
+#: builtin/init-db.c:141
+#, c-format
+msgid "templates not found %s"
+msgstr ""
+
+#: builtin/init-db.c:154
+#, c-format
+msgid "not copying templates of a wrong format version %d from '%s'"
+msgstr ""
+
+#: builtin/init-db.c:192
+#, c-format
+msgid "insane git directory %s"
+msgstr ""
+
+#: builtin/init-db.c:322
+#: builtin/init-db.c:325
+#, c-format
+msgid "%s already exists"
+msgstr "%s já existe"
+
+#: builtin/init-db.c:354
+#, c-format
+msgid "unable to handle file type %d"
+msgstr ""
+
+#: builtin/init-db.c:357
+#, c-format
+msgid "unable to move %s to %s"
+msgstr ""
+
+#: builtin/init-db.c:362
+#, c-format
+msgid "Could not create git link %s"
+msgstr ""
+
+#.
+#. * TRANSLATORS: The first '%s' is either "Reinitialized
+#. * existing" or "Initialized empty", the second " shared" or
+#. * "", and the last '%s%s' is the verbatim directory name.
+#.
+#: builtin/init-db.c:419
+#, c-format
+msgid "%s%s Git repository in %s%s\n"
+msgstr ""
+
+#: builtin/init-db.c:420
+msgid "Reinitialized existing"
+msgstr ""
+
+#: builtin/init-db.c:420
+msgid "Initialized empty"
+msgstr "Inicializada vazio"
+
+#: builtin/init-db.c:421
+msgid " shared"
+msgstr " partilhado"
+
+#: builtin/init-db.c:440
+msgid "cannot tell cwd"
+msgstr ""
+
+#: builtin/init-db.c:521
+#: builtin/init-db.c:528
+#, c-format
+msgid "cannot mkdir %s"
+msgstr ""
+
+#: builtin/init-db.c:532
+#, c-format
+msgid "cannot chdir to %s"
+msgstr ""
+
+#: builtin/init-db.c:554
+#, c-format
+msgid "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-dir=<directory>)"
+msgstr ""
+
+#: builtin/init-db.c:578
+msgid "Cannot access current working directory"
+msgstr ""
+
+#: builtin/init-db.c:585
+#, c-format
+msgid "Cannot access work tree '%s'"
+msgstr ""
+
+#: builtin/log.c:187
+#, c-format
+msgid "Final output: %d %s\n"
+msgstr ""
+
+#: builtin/log.c:395
+#: builtin/log.c:483
+#, c-format
+msgid "Could not read object %s"
+msgstr ""
+
+#: builtin/log.c:507
+#, c-format
+msgid "Unknown type: %d"
+msgstr ""
+
+#: builtin/log.c:596
+msgid "format.headers without value"
+msgstr ""
+
+#: builtin/log.c:669
+msgid "name of output directory is too long"
+msgstr ""
+
+#: builtin/log.c:680
+#, c-format
+msgid "Cannot open patch file %s"
+msgstr ""
+
+#: builtin/log.c:694
+msgid "Need exactly one range."
+msgstr ""
+
+#: builtin/log.c:702
+msgid "Not a range."
+msgstr ""
+
+#: builtin/log.c:739
+msgid "Could not extract email from committer identity."
+msgstr ""
+
+#: builtin/log.c:785
+msgid "Cover letter needs email format"
+msgstr ""
+
+#: builtin/log.c:879
+#, c-format
+msgid "insane in-reply-to: %s"
+msgstr ""
+
+#: builtin/log.c:952
+msgid "Two output directories?"
+msgstr ""
+
+#: builtin/log.c:1173
+#, c-format
+msgid "bogus committer info %s"
+msgstr ""
+
+#: builtin/log.c:1218
+msgid "-n and -k are mutually exclusive."
+msgstr ""
+
+#: builtin/log.c:1220
+msgid "--subject-prefix and -k are mutually exclusive."
+msgstr ""
+
+#: builtin/log.c:1225
+#: builtin/shortlog.c:284
+#, c-format
+msgid "unrecognized argument: %s"
+msgstr ""
+
+#: builtin/log.c:1228
+msgid "--name-only does not make sense"
+msgstr ""
+
+#: builtin/log.c:1230
+msgid "--name-status does not make sense"
+msgstr ""
+
+#: builtin/log.c:1232
+msgid "--check does not make sense"
+msgstr ""
+
+#: builtin/log.c:1255
+msgid "standard output, or directory, which one?"
+msgstr ""
+
+#: builtin/log.c:1257
+#, c-format
+msgid "Could not create directory '%s'"
+msgstr ""
+
+#: builtin/log.c:1410
+msgid "Failed to create output files"
+msgstr ""
+
+#: builtin/log.c:1514
+#, c-format
+msgid "Could not find a tracked remote branch, please specify <upstream> manually.\n"
+msgstr ""
+
+#: builtin/log.c:1530
+#: builtin/log.c:1532
+#: builtin/log.c:1544
+#, c-format
+msgid "Unknown commit %s"
+msgstr "Commit desconhecido %s"
+
+#: builtin/merge.c:91
+msgid "switch `m' requires a value"
+msgstr ""
+
+#: builtin/merge.c:128
+#, c-format
+msgid "Could not find merge strategy '%s'.\n"
+msgstr ""
+
+#: builtin/merge.c:129
+#, c-format
+msgid "Available strategies are:"
+msgstr ""
+
+#: builtin/merge.c:134
+#, c-format
+msgid "Available custom strategies are:"
+msgstr ""
+
+#: builtin/merge.c:241
+msgid "could not run stash."
+msgstr ""
+
+#: builtin/merge.c:246
+msgid "stash failed"
+msgstr "falhou o stash"
+
+#: builtin/merge.c:251
+#, c-format
+msgid "not a valid object: %s"
+msgstr ""
+
+#: builtin/merge.c:270
+#: builtin/merge.c:287
+msgid "read-tree failed"
+msgstr ""
+
+#: builtin/merge.c:317
+msgid " (nothing to squash)"
+msgstr " (nada para squash)"
+
+#: builtin/merge.c:330
+#, c-format
+msgid "Squash commit -- not updating HEAD\n"
+msgstr ""
+
+#: builtin/merge.c:362
+msgid "Writing SQUASH_MSG"
+msgstr "Escrevendo SQUASH_MSG"
+
+#: builtin/merge.c:364
+msgid "Finishing SQUASH_MSG"
+msgstr "Terminando SQUASH_MSG"
+
+#: builtin/merge.c:386
+#, c-format
+msgid "No merge message -- not updating HEAD\n"
+msgstr ""
+
+#: builtin/merge.c:437
+#, c-format
+msgid "'%s' does not point to a commit"
+msgstr ""
+
+#: builtin/merge.c:536
+#, c-format
+msgid "Bad branch.%s.mergeoptions string: %s"
+msgstr ""
+
+#: builtin/merge.c:629
+msgid "git write-tree failed to write a tree"
+msgstr ""
+
+#: builtin/merge.c:679
+msgid "failed to read the cache"
+msgstr ""
+
+#: builtin/merge.c:696
+msgid "Unable to write index."
+msgstr ""
+
+#: builtin/merge.c:709
+msgid "Not handling anything other than two heads merge."
+msgstr ""
+
+#: builtin/merge.c:723
+#, c-format
+msgid "Unknown option for merge-recursive: -X%s"
+msgstr ""
+
+#: builtin/merge.c:737
+#, c-format
+msgid "unable to write %s"
+msgstr ""
+
+#: builtin/merge.c:876
+#, c-format
+msgid "Could not read from '%s'"
+msgstr ""
+
+#: builtin/merge.c:885
+#, c-format
+msgid "Not committing merge; use 'git commit' to complete the merge.\n"
+msgstr ""
+
+#: builtin/merge.c:891
+msgid ""
+"Please enter a commit message to explain why this merge is necessary,\n"
+"especially if it merges an updated upstream into a topic branch.\n"
+"\n"
+"Lines starting with '#' will be ignored, and an empty message aborts\n"
+"the commit.\n"
+msgstr ""
+
+#: builtin/merge.c:915
+msgid "Empty commit message."
+msgstr ""
+
+#: builtin/merge.c:927
+#, c-format
+msgid "Wonderful.\n"
+msgstr "Fastastico.\n"
+
+#: builtin/merge.c:1000
+#, c-format
+msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
+msgstr ""
+
+#: builtin/merge.c:1016
+#, c-format
+msgid "'%s' is not a commit"
+msgstr "'%s' não é um commit"
+
+#: builtin/merge.c:1057
+msgid "No current branch."
+msgstr "Nenhuma rama actual"
+
+#: builtin/merge.c:1059
+msgid "No remote for the current branch."
+msgstr ""
+
+#: builtin/merge.c:1061
+msgid "No default upstream defined for the current branch."
+msgstr ""
+
+#: builtin/merge.c:1066
+#, c-format
+msgid "No remote tracking branch for %s from %s"
+msgstr ""
+
+#: builtin/merge.c:1188
+msgid "There is no merge to abort (MERGE_HEAD missing)."
+msgstr ""
+
+#: builtin/merge.c:1204
+#: git-pull.sh:31
+msgid ""
+"You have not concluded your merge (MERGE_HEAD exists).\n"
+"Please, commit your changes before you can merge."
+msgstr ""
+
+#: builtin/merge.c:1207
+#: git-pull.sh:34
+msgid "You have not concluded your merge (MERGE_HEAD exists)."
+msgstr ""
+
+#: builtin/merge.c:1211
+msgid ""
+"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
+"Please, commit your changes before you can merge."
+msgstr ""
+
+#: builtin/merge.c:1214
+msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
+msgstr ""
+
+#: builtin/merge.c:1223
+msgid "You cannot combine --squash with --no-ff."
+msgstr ""
+
+#: builtin/merge.c:1228
+msgid "You cannot combine --no-ff with --ff-only."
+msgstr ""
+
+#: builtin/merge.c:1235
+msgid "No commit specified and merge.defaultToUpstream not set."
+msgstr ""
+
+#: builtin/merge.c:1266
+msgid "Can merge only exactly one commit into empty head"
+msgstr ""
+
+#: builtin/merge.c:1269
+msgid "Squash commit into empty head not supported yet"
+msgstr ""
+
+#: builtin/merge.c:1271
+msgid "Non-fast-forward commit does not make sense into an empty head"
+msgstr ""
+
+#: builtin/merge.c:1275
+#: builtin/merge.c:1319
+#, c-format
+msgid "%s - not something we can merge"
+msgstr ""
+
+#: builtin/merge.c:1385
+#, c-format
+msgid "Updating %s..%s\n"
+msgstr "Actualizando %s..%s\n"
+
+#: builtin/merge.c:1423
+#, c-format
+msgid "Trying really trivial in-index merge...\n"
+msgstr ""
+
+#: builtin/merge.c:1430
+#, c-format
+msgid "Nope.\n"
+msgstr "Não.\n"
+
+#: builtin/merge.c:1462
+msgid "Not possible to fast-forward, aborting."
+msgstr ""
+
+#: builtin/merge.c:1485
+#: builtin/merge.c:1562
+#, c-format
+msgid "Rewinding the tree to pristine...\n"
+msgstr ""
+
+#: builtin/merge.c:1489
+#, c-format
+msgid "Trying merge strategy %s...\n"
+msgstr ""
+
+#: builtin/merge.c:1553
+#, c-format
+msgid "No merge strategy handled the merge.\n"
+msgstr ""
+
+#: builtin/merge.c:1555
+#, c-format
+msgid "Merge with strategy %s failed.\n"
+msgstr ""
+
+#: builtin/merge.c:1564
+#, c-format
+msgid "Using the %s to prepare resolving by hand.\n"
+msgstr ""
+
+#: builtin/merge.c:1575
+#, c-format
+msgid "Automatic merge went well; stopped before committing as requested\n"
+msgstr ""
+
+#: builtin/mv.c:108
+#, c-format
+msgid "Checking rename of '%s' to '%s'\n"
+msgstr ""
+
+#: builtin/mv.c:112
+msgid "bad source"
+msgstr "fonte inválida"
+
+#: builtin/mv.c:115
+msgid "can not move directory into itself"
+msgstr ""
+
+#: builtin/mv.c:118
+msgid "cannot move directory over file"
+msgstr ""
+
+#: builtin/mv.c:128
+#, c-format
+msgid "Huh? %.*s is in index?"
+msgstr ""
+
+#: builtin/mv.c:140
+msgid "source directory is empty"
+msgstr ""
+
+#: builtin/mv.c:171
+msgid "not under version control"
+msgstr ""
+
+#: builtin/mv.c:173
+msgid "destination exists"
+msgstr ""
+
+#: builtin/mv.c:181
+#, c-format
+msgid "overwriting '%s'"
+msgstr "subscrevendo '%s'"
+
+#: builtin/mv.c:184
+msgid "Cannot overwrite"
+msgstr "Não consegue subscrever"
+
+#: builtin/mv.c:187
+msgid "multiple sources for the same target"
+msgstr ""
+
+#: builtin/mv.c:202
+#, c-format
+msgid "%s, source=%s, destination=%s"
+msgstr ""
+
+#: builtin/mv.c:212
+#, c-format
+msgid "Renaming %s to %s\n"
+msgstr ""
+
+#: builtin/mv.c:215
+#, c-format
+msgid "renaming '%s' failed"
+msgstr ""
+
+#: builtin/notes.c:139
+#, c-format
+msgid "unable to start 'show' for object '%s'"
+msgstr ""
+
+#: builtin/notes.c:145
+msgid "can't fdopen 'show' output fd"
+msgstr ""
+
+#: builtin/notes.c:155
+#, c-format
+msgid "failed to close pipe to 'show' for object '%s'"
+msgstr ""
+
+#: builtin/notes.c:158
+#, c-format
+msgid "failed to finish 'show' for object '%s'"
+msgstr ""
+
+#: builtin/notes.c:175
+#: builtin/tag.c:343
+#, c-format
+msgid "could not create file '%s'"
+msgstr ""
+
+#: builtin/notes.c:189
+msgid "Please supply the note contents using either -m or -F option"
+msgstr ""
+
+#: builtin/notes.c:210
+#: builtin/notes.c:973
+#, c-format
+msgid "Removing note for object %s\n"
+msgstr ""
+
+#: builtin/notes.c:215
+msgid "unable to write note object"
+msgstr ""
+
+#: builtin/notes.c:217
+#, c-format
+msgid "The note contents has been left in %s"
+msgstr ""
+
+#: builtin/notes.c:251
+#: builtin/tag.c:521
+#, c-format
+msgid "cannot read '%s'"
+msgstr "não consegue ler '%s'"
+
+#: builtin/notes.c:253
+#: builtin/tag.c:524
+#, c-format
+msgid "could not open or read '%s'"
+msgstr ""
+
+#: builtin/notes.c:272
+#: builtin/notes.c:445
+#: builtin/notes.c:447
+#: builtin/notes.c:507
+#: builtin/notes.c:561
+#: builtin/notes.c:644
+#: builtin/notes.c:649
+#: builtin/notes.c:724
+#: builtin/notes.c:766
+#: builtin/notes.c:968
+#: builtin/reset.c:293
+#: builtin/tag.c:537
+#, c-format
+msgid "Failed to resolve '%s' as a valid ref."
+msgstr ""
+
+#: builtin/notes.c:275
+#, c-format
+msgid "Failed to read object '%s'."
+msgstr ""
+
+#: builtin/notes.c:299
+msgid "Cannot commit uninitialized/unreferenced notes tree"
+msgstr ""
+
+#: builtin/notes.c:340
+#, c-format
+msgid "Bad notes.rewriteMode value: '%s'"
+msgstr ""
+
+#: builtin/notes.c:350
+#, c-format
+msgid "Refusing to rewrite notes in %s (outside of refs/notes/)"
+msgstr ""
+
+#. TRANSLATORS: The first %s is the name of the
+#. environment variable, the second %s is its value
+#: builtin/notes.c:377
+#, c-format
+msgid "Bad %s value: '%s'"
+msgstr ""
+
+#: builtin/notes.c:441
+#, c-format
+msgid "Malformed input line: '%s'."
+msgstr ""
+
+#: builtin/notes.c:456
+#, c-format
+msgid "Failed to copy notes from '%s' to '%s'"
+msgstr ""
+
+#: builtin/notes.c:500
+#: builtin/notes.c:554
+#: builtin/notes.c:627
+#: builtin/notes.c:639
+#: builtin/notes.c:712
+#: builtin/notes.c:759
+#: builtin/notes.c:1033
+msgid "too many parameters"
+msgstr ""
+
+#: builtin/notes.c:513
+#: builtin/notes.c:772
+#, c-format
+msgid "No note found for object %s."
+msgstr ""
+
+#: builtin/notes.c:580
+#, c-format
+msgid "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite existing notes"
+msgstr ""
+
+#: builtin/notes.c:585
+#: builtin/notes.c:662
+#, c-format
+msgid "Overwriting existing notes for object %s\n"
+msgstr ""
+
+#: builtin/notes.c:635
+msgid "too few parameters"
+msgstr ""
+
+#: builtin/notes.c:656
+#, c-format
+msgid "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite existing notes"
+msgstr ""
+
+#: builtin/notes.c:668
+#, c-format
+msgid "Missing notes on source object %s. Cannot copy."
+msgstr ""
+
+#: builtin/notes.c:717
+#, c-format
+msgid ""
+"The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n"
+"Please use 'git notes add -f -m/-F/-c/-C' instead.\n"
+msgstr ""
+
+#: builtin/notes.c:971
+#, c-format
+msgid "Object %s has no note\n"
+msgstr ""
+
+#: builtin/notes.c:1103
+#, c-format
+msgid "Unknown subcommand: %s"
+msgstr ""
+
+#: builtin/pack-objects.c:2310
+#, c-format
+msgid "unsupported index version %s"
+msgstr ""
+
+#: builtin/pack-objects.c:2314
+#, c-format
+msgid "bad index version '%s'"
+msgstr ""
+
+#: builtin/pack-objects.c:2322
+#, c-format
+msgid "option %s does not accept negative form"
+msgstr ""
+
+#: builtin/pack-objects.c:2326
+#, c-format
+msgid "unable to parse value '%s' for option %s"
+msgstr ""
+
+#: builtin/push.c:44
+msgid "tag shorthand without <tag>"
+msgstr ""
+
+#: builtin/push.c:63
+msgid "--delete only accepts plain target ref names"
+msgstr ""
+
+#: builtin/push.c:73
+#, c-format
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/push.c:80
+#, c-format
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/push.c:88
+#, c-format
+msgid "The current branch %s has multiple upstream branches, refusing to push."
+msgstr ""
+
+#: builtin/push.c:111
+msgid "You didn't specify any refspecs to push, and push.default is \"nothing\"."
+msgstr ""
+
+#: builtin/push.c:131
+#, c-format
+msgid "Pushing to %s\n"
+msgstr "Pushing para %s\n"
+
+#: builtin/push.c:135
+#, c-format
+msgid "failed to push some refs to '%s'"
+msgstr ""
+
+#: builtin/push.c:143
+#, c-format
+msgid ""
+"To prevent you from losing history, non-fast-forward updates were rejected\n"
+"Merge the remote changes (e.g. 'git pull') before pushing again.  See the\n"
+"'Note about fast-forwards' section of 'git push --help' for details.\n"
+msgstr ""
+
+#: builtin/push.c:160
+#, c-format
+msgid "bad repository '%s'"
+msgstr "repositorio inválido '%s'"
+
+#: builtin/push.c:161
+msgid ""
+"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"
+msgstr ""
+
+#: builtin/push.c:176
+msgid "--all and --tags are incompatible"
+msgstr ""
+
+#: builtin/push.c:177
+msgid "--all can't be combined with refspecs"
+msgstr ""
+
+#: builtin/push.c:182
+msgid "--mirror and --tags are incompatible"
+msgstr ""
+
+#: builtin/push.c:183
+msgid "--mirror can't be combined with refspecs"
+msgstr ""
+
+#: builtin/push.c:188
+msgid "--all and --mirror are incompatible"
+msgstr ""
+
+#: builtin/push.c:274
+msgid "--delete is incompatible with --all, --mirror and --tags"
+msgstr ""
+
+#: builtin/push.c:276
+msgid "--delete doesn't make sense without any refs"
+msgstr ""
+
+#: builtin/reset.c:33
+msgid "mixed"
+msgstr "mistura"
+
+#: builtin/reset.c:33
+msgid "soft"
+msgstr "leve"
+
+#: builtin/reset.c:33
+msgid "hard"
+msgstr "forte"
+
+#: builtin/reset.c:33
+msgid "keep"
+msgstr "manter"
+
+#: builtin/reset.c:77
+msgid "You do not have a valid HEAD."
+msgstr ""
+
+#: builtin/reset.c:79
+msgid "Failed to find tree of HEAD."
+msgstr ""
+
+#: builtin/reset.c:85
+#, c-format
+msgid "Failed to find tree of %s."
+msgstr ""
+
+#: builtin/reset.c:96
+msgid "Could not write new index file."
+msgstr ""
+
+#: builtin/reset.c:106
+#, c-format
+msgid "HEAD is now at %s"
+msgstr "HEAD é agora em %s"
+
+#: builtin/reset.c:130
+msgid "Could not read index"
+msgstr ""
+
+#: builtin/reset.c:133
+msgid "Unstaged changes after reset:"
+msgstr ""
+
+#: builtin/reset.c:223
+#, c-format
+msgid "Cannot do a %s reset in the middle of a merge."
+msgstr ""
+
+#: builtin/reset.c:297
+#, c-format
+msgid "Could not parse object '%s'."
+msgstr ""
+
+#: builtin/reset.c:302
+msgid "--patch is incompatible with --{hard,mixed,soft}"
+msgstr ""
+
+#: builtin/reset.c:311
+msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
+msgstr ""
+
+#: builtin/reset.c:313
+#, c-format
+msgid "Cannot do %s reset with paths."
+msgstr ""
+
+#: builtin/reset.c:325
+#, c-format
+msgid "%s reset is not allowed in a bare repository"
+msgstr ""
+
+#: builtin/reset.c:341
+#, c-format
+msgid "Could not reset index file to revision '%s'."
+msgstr ""
+
+#: builtin/revert.c:70
+#: builtin/revert.c:91
+#, c-format
+msgid "%s: %s cannot be used with %s"
+msgstr ""
+
+#: builtin/revert.c:126
+msgid "program error"
+msgstr "erro do programa"
+
+#: builtin/revert.c:209
+msgid "revert failed"
+msgstr "falhou o revert"
+
+#: builtin/revert.c:224
+msgid "cherry-pick failed"
+msgstr "cherry-pick falhou"
+
+#: builtin/rm.c:109
+#, c-format
+msgid ""
+"'%s' has staged content different from both the file and the HEAD\n"
+"(use -f to force removal)"
+msgstr ""
+
+#: builtin/rm.c:115
+#, c-format
+msgid ""
+"'%s' has changes staged in the index\n"
+"(use --cached to keep the file, or -f to force removal)"
+msgstr ""
+
+#: builtin/rm.c:119
+#, c-format
+msgid ""
+"'%s' has local modifications\n"
+"(use --cached to keep the file, or -f to force removal)"
+msgstr ""
+
+#: builtin/rm.c:194
+#, c-format
+msgid "not removing '%s' recursively without -r"
+msgstr ""
+
+#: builtin/rm.c:230
+#, c-format
+msgid "git rm: unable to remove %s"
+msgstr ""
+
+#: builtin/shortlog.c:157
+#, c-format
+msgid "Missing author: %s"
+msgstr "Autor em falta: %s"
+
+#: builtin/tag.c:58
+#, c-format
+msgid "malformed object at '%s'"
+msgstr ""
+
+#: builtin/tag.c:205
+#, c-format
+msgid "tag name too long: %.*s..."
+msgstr ""
+
+#: builtin/tag.c:210
+#, c-format
+msgid "tag '%s' not found."
+msgstr "etiqueta '%s' não foi encontrada."
+
+#: builtin/tag.c:225
+#, c-format
+msgid "Deleted tag '%s' (was %s)\n"
+msgstr ""
+
+#: builtin/tag.c:237
+#, c-format
+msgid "could not verify the tag '%s'"
+msgstr ""
+
+#: builtin/tag.c:247
+msgid ""
+"\n"
+"#\n"
+"# Write a tag message\n"
+"# Lines starting with '#' will be ignored.\n"
+"#\n"
+msgstr ""
+
+#: builtin/tag.c:254
+msgid ""
+"\n"
+"#\n"
+"# Write a tag message\n"
+"# Lines starting with '#' will be kept; you may remove them yourself if you want to.\n"
+"#\n"
+msgstr ""
+
+#: builtin/tag.c:294
+msgid "unable to sign the tag"
+msgstr ""
+
+#: builtin/tag.c:296
+msgid "unable to write tag file"
+msgstr ""
+
+#: builtin/tag.c:321
+msgid "bad object type."
+msgstr ""
+
+#: builtin/tag.c:334
+msgid "tag header too big."
+msgstr ""
+
+#: builtin/tag.c:366
+msgid "no tag message?"
+msgstr ""
+
+#: builtin/tag.c:372
+#, c-format
+msgid "The tag message has been left in %s\n"
+msgstr ""
+
+#: builtin/tag.c:421
+msgid "switch 'points-at' requires an object"
+msgstr ""
+
+#: builtin/tag.c:423
+#, c-format
+msgid "malformed object name '%s'"
+msgstr ""
+
+#: builtin/tag.c:502
+msgid "-n option is only allowed with -l."
+msgstr ""
+
+#: builtin/tag.c:504
+msgid "--contains option is only allowed with -l."
+msgstr ""
+
+#: builtin/tag.c:506
+msgid "--points-at option is only allowed with -l."
+msgstr ""
+
+#: builtin/tag.c:514
+msgid "only one -F or -m option is allowed."
+msgstr ""
+
+#: builtin/tag.c:534
+msgid "too many params"
+msgstr "demasiado parametros"
+
+#: builtin/tag.c:540
+#, c-format
+msgid "'%s' is not a valid tag name."
+msgstr ""
+
+#: builtin/tag.c:545
+#, c-format
+msgid "tag '%s' already exists"
+msgstr ""
+
+#: builtin/tag.c:563
+#, c-format
+msgid "%s: cannot lock the ref"
+msgstr ""
+
+#: builtin/tag.c:565
+#, c-format
+msgid "%s: cannot update the ref"
+msgstr ""
+
+#: builtin/tag.c:567
+#, c-format
+msgid "Updated tag '%s' (was %s)\n"
+msgstr ""
+
+#: git-am.sh:49
+msgid "You need to set your committer info first"
+msgstr ""
+
+#: git-am.sh:136
+msgid "Repository lacks necessary blobs to fall back on 3-way merge."
+msgstr ""
+
+#: git-am.sh:147
+msgid ""
+"Did you hand edit your patch?\n"
+"It does not apply to blobs recorded in its index."
+msgstr ""
+
+#: git-am.sh:156
+msgid "Falling back to patching base and 3-way merge..."
+msgstr ""
+
+#: git-am.sh:268
+msgid "Only one StGIT patch series can be applied at once"
+msgstr ""
+
+#: git-am.sh:355
+#, sh-format
+msgid "Patch format $patch_format is not supported."
+msgstr ""
+
+#: git-am.sh:357
+msgid "Patch format detection failed."
+msgstr ""
+
+#: git-am.sh:411
+msgid "-d option is no longer supported.  Do not use."
+msgstr ""
+
+#: git-am.sh:474
+#, sh-format
+msgid "previous rebase directory $dotest still exists but mbox given."
+msgstr ""
+
+#: git-am.sh:479
+msgid "Please make up your mind. --skip or --abort?"
+msgstr ""
+
+#: git-am.sh:506
+msgid "Resolve operation not in progress, we are not resuming."
+msgstr ""
+
+#: git-am.sh:572
+#, sh-format
+msgid "Dirty index: cannot apply patches (dirty: $files)"
+msgstr ""
+
+#: git-am.sh:748
+msgid "cannot be interactive without stdin connected to a terminal."
+msgstr ""
+
+#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
+#. in your translation. The program will only accept English
+#. input at this point.
+#: git-am.sh:759
+msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
+msgstr "Aplicar? Sim[y]/[n]ão/[e]ditar/[v]er patch/[a]ceitar todos "
+
+#: git-am.sh:795
+#, sh-format
+msgid "Applying: $FIRSTLINE"
+msgstr "Aplicando: $FIRSTLINE"
+
+#: git-am.sh:840
+msgid "No changes -- Patch already applied."
+msgstr ""
+
+#: git-am.sh:866
+msgid "applying to an empty history"
+msgstr ""
+
+#. TRANSLATORS: Make sure to include [Y] and [n] in your
+#. translation. The program will only accept English input
+#. at this point.
+#: git-bisect.sh:54
+msgid "Do you want me to do it for you [Y/n]? "
+msgstr "Queres que eu faça por sí [Y/n]?"
+
+#: git-bisect.sh:95
+#, sh-format
+msgid "unrecognised option: '$arg'"
+msgstr ""
+
+#: git-bisect.sh:99
+#, sh-format
+msgid "'$arg' does not appear to be a valid revision"
+msgstr ""
+
+#: git-bisect.sh:117
+msgid "Bad HEAD - I need a HEAD"
+msgstr ""
+
+#: git-bisect.sh:130
+#, sh-format
+msgid "Checking out '$start_head' failed. Try 'git bisect reset <validbranch>'."
+msgstr ""
+
+#: git-bisect.sh:140
+msgid "won't bisect on seeked tree"
+msgstr ""
+
+#: git-bisect.sh:144
+msgid "Bad HEAD - strange symbolic ref"
+msgstr ""
+
+#: git-bisect.sh:189
+#, sh-format
+msgid "Bad bisect_write argument: $state"
+msgstr ""
+
+#: git-bisect.sh:218
+#, sh-format
+msgid "Bad rev input: $arg"
+msgstr ""
+
+#: git-bisect.sh:232
+msgid "Please call 'bisect_state' with at least one argument."
+msgstr ""
+
+#: git-bisect.sh:244
+#, sh-format
+msgid "Bad rev input: $rev"
+msgstr ""
+
+#: git-bisect.sh:250
+msgid "'git bisect bad' can take only one argument."
+msgstr ""
+
+#. TRANSLATORS: Make sure to include [Y] and [n] in your
+#. translation. The program will only accept English input
+#. at this point.
+#: git-bisect.sh:279
+msgid "Are you sure [Y/n]? "
+msgstr "Tens a certeza [Y/n]? "
+
+#: git-bisect.sh:354
+#, sh-format
+msgid "'$invalid' is not a valid commit"
+msgstr ""
+
+#: git-bisect.sh:363
+#, sh-format
+msgid ""
+"Could not check out original HEAD '$branch'.\n"
+"Try 'git bisect reset <commit>'."
+msgstr ""
+
+#: git-bisect.sh:390
+msgid "No logfile given"
+msgstr "Nenhum ficheiro de log dado"
+
+#: git-bisect.sh:391
+#, sh-format
+msgid "cannot read $file for replaying"
+msgstr ""
+
+#: git-bisect.sh:408
+msgid "?? what are you talking about?"
+msgstr ""
+
+#: git-bisect.sh:474
+msgid "We are not bisecting."
+msgstr ""
+
+#: git-pull.sh:21
+msgid ""
+"Pull is not possible because you have unmerged files.\n"
+"Please, fix them up in the work tree, and then use 'git add/rm <file>'\n"
+"as appropriate to mark resolution, or use 'git commit -a'."
+msgstr ""
+
+#: git-pull.sh:25
+msgid "Pull is not possible because you have unmerged files."
+msgstr ""
+
+#: git-pull.sh:197
+msgid "updating an unborn branch with changes added to the index"
+msgstr ""
+
+#: git-pull.sh:253
+msgid "Cannot merge multiple branches into empty head"
+msgstr ""
+
+#: git-pull.sh:257
+msgid "Cannot rebase onto multiple branches"
+msgstr ""
+
+#: git-stash.sh:51
+msgid "git stash clear with parameters is unimplemented"
+msgstr ""
+
+#: git-stash.sh:74
+msgid "You do not have the initial commit yet"
+msgstr "Tu ainda não tens o commit inicial"
+
+#: git-stash.sh:89
+msgid "Cannot save the current index state"
+msgstr ""
+
+#: git-stash.sh:123
+#: git-stash.sh:136
+msgid "Cannot save the current worktree state"
+msgstr ""
+
+#: git-stash.sh:140
+msgid "No changes selected"
+msgstr ""
+
+#: git-stash.sh:143
+msgid "Cannot remove temporary index (can't happen)"
+msgstr ""
+
+#: git-stash.sh:156
+msgid "Cannot record working tree state"
+msgstr ""
+
+#: git-stash.sh:223
+msgid "No local changes to save"
+msgstr ""
+
+#: git-stash.sh:227
+msgid "Cannot initialize stash"
+msgstr ""
+
+#: git-stash.sh:235
+msgid "Cannot save the current status"
+msgstr ""
+
+#: git-stash.sh:253
+msgid "Cannot remove worktree changes"
+msgstr ""
+
+#: git-stash.sh:352
+msgid "No stash found."
+msgstr "nenhum stash encontrado."
+
+#: git-stash.sh:359
+#, sh-format
+msgid "Too many revisions specified: $REV"
+msgstr ""
+
+#: git-stash.sh:365
+#, sh-format
+msgid "$reference is not valid reference"
+msgstr ""
+
+#: git-stash.sh:393
+#, sh-format
+msgid "'$args' is not a stash-like commit"
+msgstr ""
+
+#: git-stash.sh:404
+#, sh-format
+msgid "'$args' is not a stash reference"
+msgstr ""
+
+#: git-stash.sh:412
+msgid "unable to refresh index"
+msgstr ""
+
+#: git-stash.sh:416
+msgid "Cannot apply a stash in the middle of a merge"
+msgstr ""
+
+#: git-stash.sh:424
+msgid "Conflicts in index. Try without --index."
+msgstr ""
+
+#: git-stash.sh:426
+msgid "Could not save index tree"
+msgstr "Não foi posivel guardar o index tree"
+
+#: git-stash.sh:460
+msgid "Cannot unstage modified files"
+msgstr ""
+
+#: git-stash.sh:491
+#, sh-format
+msgid "Dropped ${REV} ($s)"
+msgstr ""
+
+#: git-stash.sh:492
+#, sh-format
+msgid "${REV}: Could not drop stash entry"
+msgstr ""
+
+#: git-stash.sh:499
+msgid "No branch name specified"
+msgstr ""
+
+#: git-stash.sh:570
+msgid "(To restore them type \"git stash apply\")"
+msgstr ""
+
+#: git-submodule.sh:56
+#, sh-format
+msgid "cannot strip one component off url '$remoteurl'"
+msgstr ""
+
+#: git-submodule.sh:108
+#, sh-format
+msgid "No submodule mapping found in .gitmodules for path '$path'"
+msgstr ""
+
+#: git-submodule.sh:149
+#, sh-format
+msgid "Clone of '$url' into submodule path '$path' failed"
+msgstr ""
+
+#: git-submodule.sh:159
+#, sh-format
+msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
+msgstr ""
+
+#: git-submodule.sh:247
+#, sh-format
+msgid "repo URL: '$repo' must be absolute or begin with ./|../"
+msgstr ""
+
+#: git-submodule.sh:264
+#, sh-format
+msgid "'$path' already exists in the index"
+msgstr ""
+
+#: git-submodule.sh:281
+#, sh-format
+msgid "'$path' already exists and is not a valid git repo"
+msgstr ""
+
+#: git-submodule.sh:295
+#, sh-format
+msgid "Unable to checkout submodule '$path'"
+msgstr ""
+
+#: git-submodule.sh:300
+#, sh-format
+msgid "Failed to add submodule '$path'"
+msgstr ""
+
+#: git-submodule.sh:305
+#, sh-format
+msgid "Failed to register submodule '$path'"
+msgstr ""
+
+#: git-submodule.sh:347
+#, sh-format
+msgid "Entering '$prefix$path'"
+msgstr ""
+
+#: git-submodule.sh:359
+#, sh-format
+msgid "Stopping at '$path'; script returned non-zero status."
+msgstr ""
+
+#: git-submodule.sh:401
+#, sh-format
+msgid "No url found for submodule path '$path' in .gitmodules"
+msgstr ""
+
+#: git-submodule.sh:410
+#, sh-format
+msgid "Failed to register url for submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:418
+#, sh-format
+msgid "Failed to register update mode for submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:420
+#, sh-format
+msgid "Submodule '$name' ($url) registered for path '$path'"
+msgstr ""
+
+#: git-submodule.sh:519
+#, sh-format
+msgid ""
+"Submodule path '$path' not initialized\n"
+"Maybe you want to use 'update --init'?"
+msgstr ""
+
+#: git-submodule.sh:532
+#, sh-format
+msgid "Unable to find current revision in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:551
+#, sh-format
+msgid "Unable to fetch in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:565
+#, sh-format
+msgid "Unable to rebase '$sha1' in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:566
+#, sh-format
+msgid "Submodule path '$path': rebased into '$sha1'"
+msgstr ""
+
+#: git-submodule.sh:571
+#, sh-format
+msgid "Unable to merge '$sha1' in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:572
+#, sh-format
+msgid "Submodule path '$path': merged in '$sha1'"
+msgstr ""
+
+#: git-submodule.sh:577
+#, sh-format
+msgid "Unable to checkout '$sha1' in submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:578
+#, sh-format
+msgid "Submodule path '$path': checked out '$sha1'"
+msgstr ""
+
+#: git-submodule.sh:600
+#: git-submodule.sh:923
+#, sh-format
+msgid "Failed to recurse into submodule path '$path'"
+msgstr ""
+
+#: git-submodule.sh:708
+msgid "--"
+msgstr "--"
+
+#: git-submodule.sh:766
+#, sh-format
+msgid "  Warn: $name doesn't contain commit $sha1_src"
+msgstr ""
+
+#: git-submodule.sh:769
+#, sh-format
+msgid "  Warn: $name doesn't contain commit $sha1_dst"
+msgstr ""
+
+#: git-submodule.sh:772
+#, sh-format
+msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
+msgstr ""
+
+#: git-submodule.sh:797
+msgid "blob"
+msgstr "blob"
+
+#: git-submodule.sh:798
+msgid "submodule"
+msgstr "submódulos"
+
+#: git-submodule.sh:969
+#, sh-format
+msgid "Synchronizing submodule url for '$name'"
+msgstr ""
+
index 0d778dc6e548fe93ab03bca537c8cdf86c803f67..e537c671728b6d449fa8c22d3ab25ceb5273a4e0 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git 1.7.3\n"
+"Project-Id-Version: git 1.7.10\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-03-08 10:19+0800\n"
-"PO-Revision-Date: 2012-03-08 10:53+0100\n"
+"POT-Creation-Date: 2012-03-16 20:18+0800\n"
+"PO-Revision-Date: 2012-03-26 07:00+0100\n"
 "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -463,11 +463,11 @@ msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (checka in eller förkasta ospårat eller ändrat innehåll i undermoduler)"
 
-# %s är ett verb ("Untracked"/"Ignored").
+# %s är ett verb ("Untracked"/"Ignored"); lägg till ett -e.
 #: wt-status.c:187
 #, c-format
 msgid "%s files:"
-msgstr "%s filer:"
+msgstr "%se filer:"
 
 #: wt-status.c:190
 #, c-format
@@ -1886,7 +1886,7 @@ msgid ""
 "some local refs could not be updated; try running\n"
 " 'git remote prune %s' to remove any old, conflicting branches"
 msgstr ""
-"några lokala referenser kunde inte uppdateras; testa att köra\n"
+"vissa lokala referenser kunde inte uppdateras; testa att köra\n"
 " \"git remote prune %s\" för att ta bort gamla grenar som står i konflikt"
 
 #: builtin/fetch.c:540
@@ -2872,7 +2872,7 @@ msgstr "Sänder till %s\n"
 #: builtin/push.c:135
 #, c-format
 msgid "failed to push some refs to '%s'"
-msgstr "misslyckades sända några referenser till \"%s\""
+msgstr "misslyckades sända vissa referenser till \"%s\""
 
 #: builtin/push.c:143
 #, c-format
@@ -3251,29 +3251,29 @@ msgstr "Patchformatet $patch_format stöds inte."
 msgid "Patch format detection failed."
 msgstr "Misslyckades detektera patchformat."
 
-#: git-am.sh:409
+#: git-am.sh:411
 msgid "-d option is no longer supported.  Do not use."
 msgstr "Flaggan -d stöds inte lägre. Använd inte."
 
-#: git-am.sh:472
+#: git-am.sh:474
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
 msgstr "tidigare rebase-katalog $dotest finns fortfarande, men mbox angavs."
 
-#: git-am.sh:477
+#: git-am.sh:479
 msgid "Please make up your mind. --skip or --abort?"
 msgstr "Bestäm dig. --skip eller --abort?"
 
-#: git-am.sh:504
+#: git-am.sh:506
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr "Lösningsoperation pågår inte, vi återupptar inte."
 
-#: git-am.sh:570
+#: git-am.sh:572
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
 msgstr "Smutsigt index: kan inte applicera patchar (smutsiga: $files)"
 
-#: git-am.sh:746
+#: git-am.sh:748
 msgid "cannot be interactive without stdin connected to a terminal."
 msgstr ""
 "kan inte vara interaktiv om standard in inte är ansluten till en terminal."
@@ -3281,20 +3281,20 @@ msgstr ""
 #. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
 #. in your translation. The program will only accept English
 #. input at this point.
-#: git-am.sh:757
+#: git-am.sh:759
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr "Applicera? Y=ja/N=nej/E=redigera/V=visa patch/A=godta alla "
 
-#: git-am.sh:793
+#: git-am.sh:795
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr "Applicerar: $FIRSTLINE"
 
-#: git-am.sh:838
+#: git-am.sh:840
 msgid "No changes -- Patch already applied."
 msgstr "Inga ändringar -- Patchen har redan applicerats."
 
-#: git-am.sh:864
+#: git-am.sh:866
 msgid "applying to an empty history"
 msgstr "applicerar på en tom historik"
 
@@ -3539,11 +3539,16 @@ msgstr "kan inte ta bort en komponent från url:en \"$remoteurl\""
 msgid "No submodule mapping found in .gitmodules for path '$path'"
 msgstr "Hittade ingen undermodulmappning i .gitmodules för sökvägen \"$path\""
 
-#: git-submodule.sh:173
+#: git-submodule.sh:149
 #, sh-format
 msgid "Clone of '$url' into submodule path '$path' failed"
 msgstr "Misslyckades klona \"$url\" till undermodulsökvägen \"$path\""
 
+#: git-submodule.sh:159
+#, sh-format
+msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
+msgstr "Gitkatalog \"$a\" ingår i underkatalogsökvägen \"$b\" eller omvänt"
+
 #: git-submodule.sh:247
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
index 713542fdcd22bd459cc6043a2dbe358724ab1ea0..64747394807b169e6dc9f64e101a03ee659c8075 100644 (file)
@@ -12,7 +12,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-03-08 10:19+0800\n"
+"POT-Creation-Date: 2012-03-16 20:18+0800\n"
 "PO-Revision-Date: 2012-01-30 00:00+0800\n"
 "Last-Translator: Jiang Xin <worldhello.net@gmail.com>\n"
 "Language-Team: GitHub <https://github.com/gotgit/git/>\n"
@@ -70,13 +70,13 @@ msgstr "无法写入 rev-list:%s"
 msgid "failed to close rev-list's stdin: %s"
 msgstr "无法关闭 rev-list 的标准输入:%s"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: diff.c:105
 #, c-format
 msgid "  Failed to parse dirstat cut-off percentage '%.*s'\n"
 msgstr "  无法解析 dirstat 阈值 '%.*s'\n"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: diff.c:110
 #, c-format
 msgid "  Unknown dirstat parameter '%.*s'\n"
@@ -88,12 +88,12 @@ msgid ""
 "Found errors in 'diff.dirstat' config variable:\n"
 "%s"
 msgstr ""
-"配置变量 'diff.dirstat' 出错:\n"
+"发现配置变量 'diff.dirstat' 中的错误:\n"
 "%s"
 
 #: diff.c:1336
 msgid " 0 files changed\n"
-msgstr "0 个文件被修改\n"
+msgstr " 0 个文件被修改\n"
 
 #: diff.c:1340
 #, c-format
@@ -169,7 +169,7 @@ msgstr[0] "您的分支领先 '%s' 共 %d 个提交。\n"
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
 "Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
-msgstr[0] "您的分支落后 '%s' 共 %d 个提交,且可以快进。\n"
+msgstr[0] "您的分支落后 '%s' 共 %d 个提交,且可以快进。\n"
 
 #: remote.c:1621
 #, c-format
@@ -187,13 +187,13 @@ msgstr[0] ""
 #: builtin/merge.c:1095 builtin/merge.c:1105
 #, c-format
 msgid "Could not open '%s' for writing"
-msgstr "无法打开 '%s' 以写入"
+msgstr "不能为写入打开 '%s'"
 
 #: sequencer.c:122 builtin/merge.c:334 builtin/merge.c:867
 #: builtin/merge.c:1097 builtin/merge.c:1110
 #, c-format
 msgid "Could not write to '%s'"
-msgstr "无法写入 '%s'"
+msgstr "不能写入 '%s'"
 
 #: sequencer.c:143
 msgid ""
@@ -238,11 +238,11 @@ msgstr "提交您的修改或保存进度后再继续。"
 #: sequencer.c:232
 #, c-format
 msgid "%s: Unable to write new index file"
-msgstr "%s:无法写入新暂存区文件"
+msgstr "%s:无法写入新索引文件"
 
 #: sequencer.c:298
 msgid "Your index file is unmerged."
-msgstr "您的暂存区文件未完成合并。"
+msgstr "您的索引文件未完成合并。"
 
 #: sequencer.c:301
 msgid "You do not have a valid HEAD"
@@ -261,7 +261,7 @@ msgstr "提交 %s 没有父提交 %d"
 #: sequencer.c:328
 #, c-format
 msgid "Mainline was specified but commit %s is not a merge."
-msgstr "æ\8f\90ä¾\9b了主线但提交 %s 不是一个合并。"
+msgstr "æ\8c\87å®\9a了主线但提交 %s 不是一个合并。"
 
 #. TRANSLATORS: The first %s will be "revert" or
 #. "cherry-pick", the second %s a SHA1
@@ -298,26 +298,26 @@ msgstr "提供了空的提交集"
 #: sequencer.c:461
 #, c-format
 msgid "git %s: failed to read the index"
-msgstr "git %s: 无法读取暂存区"
+msgstr "git %s:无法读取索引"
 
 #: sequencer.c:466
 #, c-format
 msgid "git %s: failed to refresh the index"
-msgstr "git %s: 无法刷新暂存区"
+msgstr "git %s:无法刷新索引"
 
 #: sequencer.c:551
 #, c-format
 msgid "Cannot %s during a %s"
-msgstr "无法 %s 在 %s 过程中"
+msgstr "无法 %s 在一个 %s 过程中"
 
 #: sequencer.c:573
 #, c-format
 msgid "Could not parse line %d."
-msgstr "无法解析第 %d 行。"
+msgstr "不能解析第 %d 行。"
 
 #: sequencer.c:578
 msgid "No commits parsed."
-msgstr "æ\9cª有提交被解析。"
+msgstr "没有提交被解析。"
 
 #: sequencer.c:591
 #, c-format
@@ -360,7 +360,7 @@ msgstr "尝试 \"git cherry-pick (--continue | --quit | --abort)\""
 #: sequencer.c:671
 #, c-format
 msgid "Could not create sequencer directory %s"
-msgstr "无法创建序列目录 %s"
+msgstr "不能创建序列目录 %s"
 
 #: sequencer.c:687 sequencer.c:772
 #, c-format
@@ -377,7 +377,7 @@ msgstr "不能解析 HEAD"
 
 #: sequencer.c:710
 msgid "cannot abort from a branch yet to be born"
-msgstr "不能从未初始分支终止"
+msgstr "不能从尚未建立的分支终止"
 
 #: sequencer.c:732
 #, c-format
@@ -396,7 +396,7 @@ msgstr "未预期的文件结束"
 #: sequencer.c:742
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
-msgstr "保存预拣选提交的 HEAD 文件 '%s' 损坏"
+msgstr "保存拣选提交前的 HEAD 文件 '%s' 损坏"
 
 #: sequencer.c:765
 #, c-format
@@ -415,18 +415,18 @@ msgstr "不能拣选到空分支"
 msgid "Unmerged paths:"
 msgstr "未合并的路径:"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: wt-status.c:140 wt-status.c:157
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (使用 \"git reset %s <file>...\" 撤出暂存区)"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: wt-status.c:142 wt-status.c:159
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (使用 \"git rm --cached <file>...\" 撤出暂存区)"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: wt-status.c:143
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr "  (酌情使用 \"git add/rm <file>...\" 标记解决方案)"
@@ -437,25 +437,25 @@ msgstr "要提交的变更:"
 
 #: wt-status.c:169
 msgid "Changes not staged for commit:"
-msgstr "未暂存至提交的变更:"
+msgstr "尚未暂存以备提交的变更:"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: wt-status.c:173
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr "  (使用 \"git add <file>...\" 更新要提交的内容)"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: wt-status.c:175
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr "  (使用 \"git add/rm <file>...\" 更新要提交的内容)"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: wt-status.c:176
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr "  (使用 \"git checkout -- <file>...\" 丢弃工作区的改动)"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: wt-status.c:178
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr "  (提交或丢弃子模组中未跟踪或修改的内容)"
@@ -465,11 +465,11 @@ msgstr "  (提交或丢弃子模组中未跟踪或修改的内容)"
 msgid "%s files:"
 msgstr "%s文件:"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: wt-status.c:190
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
-msgstr "  (使用 \"git %s <file>...\" 包含到提交列表)"
+msgstr "  (使用 \"git %s <file>...\" 以包含要提交的内容)"
 
 #: wt-status.c:207
 msgid "bug"
@@ -503,61 +503,64 @@ msgstr "双方添加:"
 msgid "both modified:"
 msgstr "双方修改:"
 
+#  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
 #: wt-status.c:248
 msgid "new commits, "
 msgstr "新提交, "
 
+#  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
 #: wt-status.c:250
 msgid "modified content, "
 msgstr "修改的内容, "
 
+#  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
 #: wt-status.c:252
 msgid "untracked content, "
 msgstr "未跟踪的内容, "
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: wt-status.c:266
 #, c-format
 msgid "new file:   %s"
 msgstr "新文件:    %s"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: wt-status.c:269
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "拷贝:      %s -> %s"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: wt-status.c:272
 #, c-format
 msgid "deleted:    %s"
 msgstr "删除:      %s"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: wt-status.c:275
 #, c-format
 msgid "modified:   %s"
 msgstr "修改:      %s"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: wt-status.c:278
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "重命名:    %s -> %s"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: wt-status.c:281
 #, c-format
 msgid "typechange: %s"
 msgstr "类型变更:  %s"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: wt-status.c:284
 #, c-format
 msgid "unknown:    %s"
 msgstr "未知:      %s"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: wt-status.c:287
 #, c-format
 msgid "unmerged:   %s"
@@ -566,7 +569,7 @@ msgstr "未合并:    %s"
 #: wt-status.c:290
 #, c-format
 msgid "bug: unhandled diff status %c"
-msgstr "bug未处理的差异状态 %c"
+msgstr "bug未处理的差异状态 %c"
 
 #: wt-status.c:713
 msgid "On branch "
@@ -593,10 +596,10 @@ msgstr "忽略的"
 msgid "Untracked files not listed%s"
 msgstr "未跟踪的文件没有列出%s"
 
-#  注意保持前导空格
+#  译者:中文字符串拼接,可删除前导空格
 #: wt-status.c:751
 msgid " (use -u option to show untracked files)"
-msgstr " (使用 -u 参数显示未跟踪的文件)"
+msgstr "(使用 -u 参数显示未跟踪的文件)"
 
 #: wt-status.c:757
 msgid "No changes"
@@ -607,61 +610,61 @@ msgstr "没有修改"
 msgid "no changes added to commit%s\n"
 msgstr "修改尚未加入提交%s\n"
 
-#  注意保持前导空格
+#  译者:中文字符串拼接,可删除前导空格
 #: wt-status.c:763
 msgid " (use \"git add\" and/or \"git commit -a\")"
-msgstr " (使用 \"git add\" 和/或 \"git commit -a\")"
+msgstr "(使用 \"git add\" 和/或 \"git commit -a\")"
 
 #: wt-status.c:765
 #, c-format
 msgid "nothing added to commit but untracked files present%s\n"
 msgstr "空提交但存在未跟踪文件%s\n"
 
-#  注意保持前导空格
+#  译者:中文字符串拼接,可删除前导空格
 #: wt-status.c:767
 msgid " (use \"git add\" to track)"
-msgstr " (使用 \"git add\" 建立跟踪)"
+msgstr "(使用 \"git add\" 建立跟踪)"
 
 #: wt-status.c:769 wt-status.c:772 wt-status.c:775
 #, c-format
 msgid "nothing to commit%s\n"
 msgstr "无须提交%s\n"
 
-#  注意保持前导空格
+#  译者:中文字符串拼接,可删除前导空格
 #: wt-status.c:770
 msgid " (create/copy files and use \"git add\" to track)"
-msgstr " (新建/拷贝的文件使用 \"git add\" 建立跟踪)"
+msgstr "(新建/拷贝的文件使用 \"git add\" 建立跟踪)"
 
-#  注意保持前导空格
+#  译者:中文字符串拼接,可删除前导空格
 #: wt-status.c:773
 msgid " (use -u to show untracked files)"
-msgstr " (使用 -u 显示未跟踪文件)"
+msgstr "(使用 -u 显示未跟踪文件)"
 
-#  注意保持前导空格
+#  译者:中文字符串拼接,可删除前导空格
 #: wt-status.c:776
 msgid " (working directory clean)"
-msgstr " (干净的工作区)"
+msgstr "(干净的工作区)"
 
 #: wt-status.c:884
 msgid "HEAD (no branch)"
 msgstr "HEAD(非分支)"
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #: wt-status.c:890
 msgid "Initial commit on "
 msgstr "初始提交于 "
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #: wt-status.c:905
 msgid "behind "
 msgstr "落后 "
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #: wt-status.c:908 wt-status.c:911
 msgid "ahead "
 msgstr "领先 "
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #: wt-status.c:913
 msgid ", behind "
 msgstr ",落后 "
@@ -687,7 +690,7 @@ msgstr "路径 '%s' 属于模组 '%.*s'"
 
 #: builtin/add.c:192
 msgid "Unstaged changes after refreshing the index:"
-msgstr "刷新暂存区后未暂存的变更:"
+msgstr "刷新索引之后尚未被暂存的变更:"
 
 #: builtin/add.c:195 builtin/add.c:456 builtin/rm.c:186
 #, c-format
@@ -701,21 +704,21 @@ msgstr "'%s' 位于符号链接中"
 
 #: builtin/add.c:276
 msgid "Could not read the index"
-msgstr "无法读取暂存区"
+msgstr "不能读取索引"
 
 #: builtin/add.c:286
 #, c-format
 msgid "Could not open '%s' for writing."
-msgstr "无法打开 '%s' 以写入。"
+msgstr "不能为写入打开 '%s'。"
 
 #: builtin/add.c:290
 msgid "Could not write patch"
-msgstr "无法写补丁"
+msgstr "不能写补丁"
 
 #: builtin/add.c:295
 #, c-format
 msgid "Could not stat '%s'"
-msgstr "无法查看文件状态 '%s'"
+msgstr "不能查看文件状态 '%s'"
 
 #: builtin/add.c:297
 msgid "Empty patch. Aborted."
@@ -724,7 +727,7 @@ msgstr "空补丁。异常终止。"
 #: builtin/add.c:303
 #, c-format
 msgid "Could not apply '%s'"
-msgstr "无法应用 '%s'"
+msgstr "不能应用 '%s'"
 
 #: builtin/add.c:312
 msgid "The following paths are ignored by one of your .gitignore files:\n"
@@ -733,7 +736,7 @@ msgstr "下列路径被您的一个 .gitignore 文件所忽略:\n"
 #: builtin/add.c:352
 #, c-format
 msgid "Use -f if you really want to add them.\n"
-msgstr "使用 -f 参数如果确实要添加它们。\n"
+msgstr "使用 -f 参数如果确实要添加它们。\n"
 
 #: builtin/add.c:353
 msgid "no files added"
@@ -754,7 +757,7 @@ msgstr "选项 --ignore-missing 只能和 --dry-run 共用"
 #: builtin/add.c:413
 #, c-format
 msgid "Nothing specified, nothing added.\n"
-msgstr "æ\9cªæ\8f\90ä¾\9bå\8f\82æ\95°ï¼\8c没有文件被添加。\n"
+msgstr "没æ\9c\89æ\8c\87å®\9aæ\96\87件ï¼\8cä¹\9f没有文件被添加。\n"
 
 #: builtin/add.c:414
 #, c-format
@@ -764,33 +767,33 @@ msgstr "也许您想要执行 'git add .'?\n"
 #: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:358 builtin/mv.c:82
 #: builtin/rm.c:162
 msgid "index file corrupt"
-msgstr "暂存区文件损坏"
+msgstr "索引文件损坏"
 
 #: builtin/add.c:476 builtin/mv.c:229 builtin/rm.c:260
 msgid "Unable to write new index file"
-msgstr "无法写入新暂存区文件"
+msgstr "无法写入新索引文件"
 
 #: builtin/archive.c:17
 #, c-format
 msgid "could not create archive file '%s'"
-msgstr "无法创建归档文件 '%s'"
+msgstr "不能创建归档文件 '%s'"
 
 #: builtin/archive.c:20
 msgid "could not redirect output"
-msgstr "无法重定向输出"
+msgstr "不能输出重定向"
 
 #: builtin/archive.c:37
 msgid "git archive: Remote with no URL"
-msgstr "git archive未提供远程URL"
+msgstr "git archive未提供远程URL"
 
 #: builtin/archive.c:58
 msgid "git archive: expected ACK/NAK, got EOF"
-msgstr "git archive期待ACK/NACK,却得到EOF"
+msgstr "git archive期待ACK/NACK,却得到EOF"
 
 #: builtin/archive.c:63
 #, c-format
 msgid "git archive: NACK %s"
-msgstr "git archiveNACK %s"
+msgstr "git archiveNACK %s"
 
 #: builtin/archive.c:65
 #, c-format
@@ -799,13 +802,13 @@ msgstr "远程错误:%s"
 
 #: builtin/archive.c:66
 msgid "git archive: protocol error"
-msgstr "git archive协议错误"
+msgstr "git archive协议错误"
 
 #: builtin/archive.c:71
 msgid "git archive: expected a flush"
-msgstr "git archive预期一个刷新"
+msgstr "git archive预期一个刷新"
 
-#  保持原换行格式,在输出时 %s 的替代内容会让字串变长
+#  译者:保持原换行格式,在输出时 %s 的替代内容会让字符串变长
 #: builtin/branch.c:137
 #, c-format
 msgid ""
@@ -815,7 +818,7 @@ msgstr ""
 "将要删除的分支 '%s' 已经被合并到\n"
 "         '%s',但未合并到 HEAD。"
 
-#  保持原换行格式,在输出时 %s 的替代内容会让字串变长
+#  译者:保持原换行格式,在输出时 %s 的替代内容会让字符串变长
 #: builtin/branch.c:141
 #, c-format
 msgid ""
@@ -825,7 +828,7 @@ msgstr ""
 "并未删除分支 '%s', 虽然它已经合并到 HEAD,\n"
 "         然而却尚未被合并到分支 '%s' 。"
 
-#  汉字之间无空格,故删除尾部空格
+#  译者:汉字之间无空格,故删除尾部空格
 #. TRANSLATORS: This is "remote " in "remote branch '%s' not found"
 #: builtin/branch.c:163
 msgid "remote "
@@ -866,7 +869,7 @@ msgstr ""
 #: builtin/branch.c:214
 #, c-format
 msgid "Error deleting %sbranch '%s'"
-msgstr "删除 %s分支 '%s' 时错误"
+msgstr "删除 %s分支 '%s' 时出错"
 
 #: builtin/branch.c:219
 #, c-format
@@ -882,19 +885,19 @@ msgstr "无法更新 config 文件"
 msgid "branch '%s' does not point at a commit"
 msgstr "分支 '%s' 未指向一个提交"
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #: builtin/branch.c:394
 #, c-format
 msgid "behind %d] "
 msgstr "落后 %d] "
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #: builtin/branch.c:396
 #, c-format
 msgid "ahead %d] "
 msgstr "领先 %d] "
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #: builtin/branch.c:398
 #, c-format
 msgid "ahead %d, behind %d] "
@@ -906,11 +909,11 @@ msgstr "(非分支)"
 
 #: builtin/branch.c:566
 msgid "some refs could not be read"
-msgstr "一些引用无法读取"
+msgstr "一些引用不能读取"
 
 #: builtin/branch.c:579
 msgid "cannot rename the current branch while not on any."
-msgstr "无法重命名不存在的当前分支。"
+msgstr "无法重命名当前分支因为不处于任何分支上。"
 
 #: builtin/branch.c:589
 #, c-format
@@ -951,7 +954,7 @@ msgstr "无法将 HEAD 解析为有效引用。"
 
 #: builtin/branch.c:751 builtin/clone.c:558
 msgid "HEAD not found below refs/heads!"
-msgstr "未在 /refs/heads 下发现 HEAD!"
+msgstr "HEAD 没有位于 /refs/heads 之下!"
 
 #: builtin/branch.c:809
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
@@ -964,11 +967,11 @@ msgstr "%s 可以\n"
 
 #: builtin/bundle.c:56
 msgid "Need a repository to create a bundle."
-msgstr "需要一个版本库来创建包"
+msgstr "需要一个版本库来创建包"
 
 #: builtin/bundle.c:60
 msgid "Need a repository to unbundle."
-msgstr "需要一个版本库来解包"
+msgstr "需要一个版本库来解包"
 
 #: builtin/checkout.c:113 builtin/checkout.c:146
 #, c-format
@@ -993,7 +996,7 @@ msgstr "路径 '%s' 没有必须的版本"
 #: builtin/checkout.c:192
 #, c-format
 msgid "path '%s': cannot merge"
-msgstr "path '%s'无法合并"
+msgstr "path '%s'无法合并"
 
 #: builtin/checkout.c:209
 #, c-format
@@ -1007,7 +1010,7 @@ msgstr "对路径 '%s' 的 make_cache_entry 操作失败"
 
 #: builtin/checkout.c:234 builtin/checkout.c:392
 msgid "corrupt index file"
-msgstr "冲突的暂存区文件"
+msgstr "损坏的索引文件"
 
 #: builtin/checkout.c:264 builtin/checkout.c:271
 #, c-format
@@ -1017,7 +1020,7 @@ msgstr "路径 '%s' 未合并"
 #: builtin/checkout.c:302 builtin/checkout.c:498 builtin/clone.c:583
 #: builtin/merge.c:811
 msgid "unable to write new index file"
-msgstr "无法写新的暂存区文件"
+msgstr "无法写新的索引文件"
 
 #: builtin/checkout.c:319 builtin/diff.c:302 builtin/merge.c:408
 msgid "diff_setup_done failed"
@@ -1025,12 +1028,12 @@ msgstr "diff_setup_done 失败"
 
 #: builtin/checkout.c:414
 msgid "you need to resolve your current index first"
-msgstr "您需要先解决当前暂存区的冲突"
+msgstr "您需要先解决当前索引的冲突"
 
 #: builtin/checkout.c:533
 #, c-format
 msgid "Can not do reflog for '%s'\n"
-msgstr "不能对 '%s' 保存引用日志\n"
+msgstr "不能对 '%s' 执行 reflog 操作\n"
 
 #: builtin/checkout.c:565
 msgid "HEAD is now at"
@@ -1061,11 +1064,11 @@ msgstr "切换到一个新分支 '%s'\n"
 msgid "Switched to branch '%s'\n"
 msgstr "切换到分支 '%s'\n"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: builtin/checkout.c:639
 #, c-format
 msgid " ... and %d more.\n"
-msgstr " ... 及 %d 更多。\n"
+msgstr " ... 及其它 %d 个。\n"
 
 #. The singular version
 #: builtin/checkout.c:645
@@ -1110,7 +1113,7 @@ msgstr "之前的 HEAD 位置是"
 
 #: builtin/checkout.c:722
 msgid "You are on a branch yet to be born"
-msgstr "您位于一个未初始化的分支"
+msgstr "您位于一个未初始化的分支"
 
 #. case (1)
 #: builtin/checkout.c:853
@@ -1158,11 +1161,11 @@ msgstr "--orphan 不能和 -t 共用"
 
 #: builtin/checkout.c:1017
 msgid "git checkout: -f and -m are incompatible"
-msgstr "git checkout-f 和 -m 不兼容"
+msgstr "git checkout-f 和 -m 不兼容"
 
 #: builtin/checkout.c:1051
 msgid "invalid path specification"
-msgstr "无效的路径"
+msgstr "无效的路径规格"
 
 #: builtin/checkout.c:1059
 #, c-format
@@ -1170,24 +1173,23 @@ msgid ""
 "git checkout: updating paths is incompatible with switching branches.\n"
 "Did you intend to checkout '%s' which can not be resolved as commit?"
 msgstr ""
-"git checkout更新路径和切换分支不兼容。\n"
+"git checkout更新路径和切换分支不兼容。\n"
 "您是想要检出 '%s' 但未能将其解析为提交么?"
 
 #: builtin/checkout.c:1061
 msgid "git checkout: updating paths is incompatible with switching branches."
-msgstr "git checkout更新路径和切换分支不兼容。"
+msgstr "git checkout更新路径和切换分支不兼容。"
 
 #: builtin/checkout.c:1066
 msgid "git checkout: --detach does not take a path argument"
-msgstr "git checkout--detach 不跟路径参数"
+msgstr "git checkout--detach 不跟路径参数"
 
 #: builtin/checkout.c:1069
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
-"git checkout: --ours/--theirs, --force 和 --merge 不兼容当\n"
-"检出暂存区时。"
+"git checkout:在从索引检出时,--ours/--theirs、--force 和 --merge 不兼容。"
 
 #: builtin/checkout.c:1088
 msgid "Cannot switch branch to a non-commit."
@@ -1205,14 +1207,14 @@ msgstr "-x 和 -X 不能共用"
 msgid ""
 "clean.requireForce set to true and neither -n nor -f given; refusing to clean"
 msgstr ""
-"clean.requireForce 设置为 true,若未提供 -n 或 -f 选项,拒绝执行清理动作"
+"clean.requireForce 设置为 true 且未提供 -n 或 -f 选项,拒绝执行清理动作"
 
 #: builtin/clean.c:85
 msgid ""
 "clean.requireForce defaults to true and neither -n nor -f given; refusing to "
 "clean"
 msgstr ""
-"clean.requireForce 默认为 true,若未提供 -n 或 -f 选项,拒绝执行清理动作"
+"clean.requireForce 默认为 true 且未提供 -n 或 -f 选项,拒绝执行清理动作"
 
 #: builtin/clean.c:155 builtin/clean.c:176
 #, c-format
@@ -1247,17 +1249,17 @@ msgstr "引用版本库 '%s' 不是一个本地目录。"
 #: builtin/clone.c:302
 #, c-format
 msgid "failed to open '%s'"
-msgstr "æ\89\93å¼\80 '%s' å¤±è´¥"
+msgstr "æ\97 æ³\95æ\89\93å¼\80 '%s'"
 
 #: builtin/clone.c:306
 #, c-format
 msgid "failed to create directory '%s'"
-msgstr "创建目录 '%s' 失败"
+msgstr "无法创建目录 '%s'"
 
 #: builtin/clone.c:308 builtin/diff.c:75
 #, c-format
 msgid "failed to stat '%s'"
-msgstr "æ\9e\9a举 '%s' ç\8a¶æ\80\81失败"
+msgstr "æ\97 æ³\95æ\9e\9a举 '%s' ç\8a¶æ\80\81"
 
 #: builtin/clone.c:310
 #, c-format
@@ -1267,22 +1269,22 @@ msgstr "%s 存在且不是一个目录"
 #: builtin/clone.c:324
 #, c-format
 msgid "failed to stat %s\n"
-msgstr "æ\9e\9a举 %s ç\8a¶æ\80\81失败\n"
+msgstr "æ\97 æ³\95æ\9e\9a举 %s ç\8a¶æ\80\81\n"
 
 #: builtin/clone.c:341
 #, c-format
 msgid "failed to unlink '%s'"
-msgstr "删除 '%s' 失败"
+msgstr "无法删除 '%s'"
 
 #: builtin/clone.c:346
 #, c-format
 msgid "failed to create link '%s'"
-msgstr "创建链接 '%s' 失败"
+msgstr "无法创建链接 '%s'"
 
 #: builtin/clone.c:350
 #, c-format
 msgid "failed to copy file to '%s'"
-msgstr "æ\8b·è´\9dæ\96\87件è\87³ '%s' å¤±è´¥"
+msgstr "æ\97 æ³\95æ\8b·è´\9dæ\96\87件è\87³ '%s'"
 
 #: builtin/clone.c:373
 #, c-format
@@ -1292,7 +1294,7 @@ msgstr "完成。\n"
 #: builtin/clone.c:440
 #, c-format
 msgid "Could not find remote branch %s to clone."
-msgstr "无法发现要克隆的远程分支 %s。"
+msgstr "不能发现要克隆的远程分支 %s。"
 
 #: builtin/clone.c:549
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
@@ -1304,7 +1306,7 @@ msgstr "太多参数。"
 
 #: builtin/clone.c:643
 msgid "You must specify a repository to clone."
-msgstr "你必须指定一个版本库来克隆"
+msgstr "您必须指定一个版本库来克隆。"
 
 #: builtin/clone.c:654
 #, c-format
@@ -1323,7 +1325,7 @@ msgstr "--depth 在本地克隆被忽略,改为 file:// 协议试试。"
 #: builtin/clone.c:683
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
-msgstr "目标路径 '%s' 已经存在且不是一个空目录。"
+msgstr "目标路径 '%s' 已经存在,并且不是一个空目录。"
 
 #: builtin/clone.c:693
 #, c-format
@@ -1333,12 +1335,12 @@ msgstr "工作区 '%s' 已经存在。"
 #: builtin/clone.c:706 builtin/clone.c:720
 #, c-format
 msgid "could not create leading directories of '%s'"
-msgstr "无法为 '%s' 创建目录"
+msgstr "不能为 '%s' 创建先导目录"
 
 #: builtin/clone.c:709
 #, c-format
 msgid "could not create work tree dir '%s'."
-msgstr "无法为 '%s' 创建工作区目录。"
+msgstr "不能为 '%s' 创建工作区目录。"
 
 #: builtin/clone.c:728
 #, c-format
@@ -1377,13 +1379,13 @@ msgid ""
 "\n"
 "    git commit --amend --reset-author\n"
 msgstr ""
-"您的姓名和邮件地址会基于您的用户名和主机地址自动配置。请检查它们\n"
-"正确与否。您可通过下面命令对其显式声明以避免重复出现类似提示:\n"
+"您的姓名和邮件地址基于登录名和主机名进行了自动设置。请检查它们正确\n"
+"与否。您可以通过下面的命令对其进行明确地设置以免再出现本提示信息:\n"
 "\n"
 "    git config --global user.name \"Your Name\"\n"
 "    git config --global user.email you@example.com\n"
 "\n"
-"设置完毕后,您可用下面命令来更改此次提交所使用的用户ID:\n"
+"设置完毕后,您可以用下面的命令来修正本次提交所使用的用户身份:\n"
 "\n"
 "    git commit --amend --reset-author\n"
 
@@ -1422,11 +1424,11 @@ msgstr "拣选"
 
 #: builtin/commit.c:325
 msgid "failed to unpack HEAD tree object"
-msgstr "解包 HEAD 树对象失败"
+msgstr "无法解包 HEAD 树对象"
 
 #: builtin/commit.c:367
 msgid "unable to create temporary index"
-msgstr "不能创建临时暂存区"
+msgstr "不能创建临时索引"
 
 #: builtin/commit.c:373
 msgid "interactive add failed"
@@ -1434,9 +1436,9 @@ msgstr "交互式添加失败"
 
 #: builtin/commit.c:406 builtin/commit.c:427 builtin/commit.c:473
 msgid "unable to write new_index file"
-msgstr "无法写入新暂存区文件"
+msgstr "无法写 new_index 文件"
 
-#  %s若翻为中文,前后不需要空格
+#  译者:%s若翻为中文,前后不需要空格
 #: builtin/commit.c:457
 #, c-format
 msgid "cannot do a partial commit during a %s."
@@ -1444,11 +1446,11 @@ msgstr "在%s过程中不能做部分提交。"
 
 #: builtin/commit.c:466
 msgid "cannot read the index"
-msgstr "无法读取暂存区"
+msgstr "无法读取索引"
 
 #: builtin/commit.c:486
 msgid "unable to write temporary index file"
-msgstr "无法写临时暂存区文件"
+msgstr "无法写临时索引文件"
 
 #: builtin/commit.c:550 builtin/commit.c:556
 #, c-format
@@ -1462,7 +1464,7 @@ msgstr "非法的 --author 参数"
 #: builtin/commit.c:635
 #, c-format
 msgid "Malformed ident string: '%s'"
-msgstr "é\9d\9eæ³\95ç\9a\84è¯\86å\88«å­\97串:'%s'"
+msgstr "é\9d\9eæ³\95ç\9a\84身份å­\97符串:'%s'"
 
 #: builtin/commit.c:670 builtin/commit.c:703 builtin/commit.c:1000
 #, c-format
@@ -1472,16 +1474,16 @@ msgstr "不能查询提交 %s"
 #: builtin/commit.c:682 builtin/shortlog.c:296
 #, c-format
 msgid "(reading log message from standard input)\n"
-msgstr "(正从标准输入中读取说明信息)\n"
+msgstr "(正从标准输入中读取日志信息)\n"
 
 #: builtin/commit.c:684
 msgid "could not read log from standard input"
-msgstr "无法从标准输入中读取说明信息"
+msgstr "不能从标准输入中读取日志信息"
 
 #: builtin/commit.c:688
 #, c-format
 msgid "could not read log file '%s'"
-msgstr "无法读取说明文件 '%s'"
+msgstr "不能读取日志文件 '%s'"
 
 #: builtin/commit.c:694
 msgid "commit has empty message"
@@ -1489,27 +1491,27 @@ msgstr "提交说明为空"
 
 #: builtin/commit.c:710
 msgid "could not read MERGE_MSG"
-msgstr "无法读取 MERGE_MSG"
+msgstr "不能读取 MERGE_MSG"
 
 #: builtin/commit.c:714
 msgid "could not read SQUASH_MSG"
-msgstr "无法读取 SQUASH_MSG"
+msgstr "不能读取 SQUASH_MSG"
 
 #: builtin/commit.c:718
 #, c-format
 msgid "could not read '%s'"
-msgstr "无法读取 '%s'"
+msgstr "不能读取 '%s'"
 
 #: builtin/commit.c:746
 #, c-format
 msgid "could not open '%s'"
-msgstr "无法打开 '%s'"
+msgstr "不能打开 '%s'"
 
 #: builtin/commit.c:770
 msgid "could not write commit template"
-msgstr "无法写提交模版"
+msgstr "不能写提交模版"
 
-#  %s若翻为中文,前后不需要空格
+#  译者:%s若翻为中文,前后不需要空格
 #: builtin/commit.c:783
 #, c-format
 msgid ""
@@ -1529,7 +1531,7 @@ msgstr ""
 msgid "Please enter the commit message for your changes."
 msgstr "请为您的修改输入提交说明。"
 
-#  前导空格用于拼接英文字串,中文字串拼接无需空格
+#  译者:中文字符串拼接,可删除前导空格
 #: builtin/commit.c:799
 msgid ""
 " Lines starting\n"
@@ -1538,7 +1540,7 @@ msgstr ""
 "以 '#' 开头\n"
 "的行将被忽略,并且空的提交说明将会中止提交。\n"
 
-#  前导空格用于拼接英文字串,中文字串拼接无需空格
+#  译者:中文字符串拼接,可删除前导空格
 #: builtin/commit.c:804
 msgid ""
 " Lines starting\n"
@@ -1549,13 +1551,13 @@ msgstr ""
 "的行将被保留,您可以删除它们如果您想这样做的话。空的提交说明将会\n"
 "中止提交。\n"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: builtin/commit.c:816
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%s作者:     %s"
 
-#  为保证在输出中对齐,注意调整句中空格!
+#  译者:为保证在输出中对齐,注意调整句中空格!
 #: builtin/commit.c:823
 #, c-format
 msgid "%sCommitter: %s"
@@ -1563,7 +1565,7 @@ msgstr "%s提交者:   %s"
 
 #: builtin/commit.c:843
 msgid "Cannot read index"
-msgstr "无法读取暂存区"
+msgstr "无法读取索引"
 
 #: builtin/commit.c:880
 msgid "Error building trees"
@@ -1572,7 +1574,7 @@ msgstr "无法创建树对象"
 #: builtin/commit.c:895 builtin/tag.c:357
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
-msgstr "请使用 -m 或者 -F 选项提供说明。\n"
+msgstr "请使用 -m 或者 -F 选项提供提交说明。\n"
 
 #: builtin/commit.c:975
 #, c-format
@@ -1582,7 +1584,7 @@ msgstr "没有找到匹配 '%s' 的作者"
 #: builtin/commit.c:990 builtin/commit.c:1182
 #, c-format
 msgid "Invalid untracked files mode '%s'"
-msgstr "无效的追踪文件参数 '%s'"
+msgstr "无效的追踪文件参数 '%s'"
 
 #: builtin/commit.c:1030
 msgid "Using both --reset-author and --author does not make sense"
@@ -1590,13 +1592,13 @@ msgstr "同时使用 --reset-author 和 --author 没有意义"
 
 #: builtin/commit.c:1041
 msgid "You have nothing to amend."
-msgstr "您没有要修补。"
+msgstr "您没有可修补的提交。"
 
-#  %s若翻为中文,前后不需要空格
+#  译者:%s若翻为中文,前后不需要空格
 #: builtin/commit.c:1043
 #, c-format
 msgid "You are in the middle of a %s -- cannot amend."
-msgstr "您正处于一个%s过程中 -- 无法修补提交。"
+msgstr "您正处于一个%s过程中 -- 无法修补提交。"
 
 #: builtin/commit.c:1045
 msgid "Options --squash and --fixup cannot be used together"
@@ -1612,7 +1614,7 @@ msgstr "选项 -m 不能和 -c/-C/-F/--fixup 共用。"
 
 #: builtin/commit.c:1063
 msgid "--reset-author can be used only with -C, -c or --amend."
-msgstr "--reset-author 只能和 -C-c 或 --amend 共用。"
+msgstr "--reset-author 只能和 -C-c 或 --amend 共用。"
 
 #: builtin/commit.c:1080
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
@@ -1624,11 +1626,11 @@ msgstr "参数 --include/--only 不跟路径没有意义。"
 
 #: builtin/commit.c:1084
 msgid "Clever... amending the last one with dirty index."
-msgstr "聪明... 在暂存区不干净下修补最后的提交。"
+msgstr "聪明... 在索引不干净下修补最后的提交。"
 
 #: builtin/commit.c:1086
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
-msgstr "没æ\9c\89ç\94¨ -i æ\88\96 -o é\80\89项è\80\8cæ\98¾å¼\8få\9c°æ\8f\90ä¾\9bè·¯å¾\84ï¼\8c认为是 --only paths..."
+msgstr "æ\8c\87å®\9aäº\86æ\98\8eç¡®ç\9a\84è·¯å¾\84è\80\8c没æ\9c\89使ç\94¨ -i æ\88\96 -o é\80\89项ï¼\9b认为是 --only paths..."
 
 #: builtin/commit.c:1096 builtin/tag.c:556
 #, c-format
@@ -1645,39 +1647,39 @@ msgstr "无法找到新创建的提交"
 
 #: builtin/commit.c:1282
 msgid "could not parse newly created commit"
-msgstr "无法解析新创建的提交"
+msgstr "不能解析新创建的提交"
 
 #: builtin/commit.c:1323
 msgid "detached HEAD"
 msgstr "分离头指针"
 
-#  注意保持前导空格
+#  译者:中文字符串拼接,可删除前导空格
 #: builtin/commit.c:1325
 msgid " (root-commit)"
-msgstr " (根提交)"
+msgstr "(根提交)"
 
 #: builtin/commit.c:1415
 msgid "could not parse HEAD commit"
-msgstr "无法解析 HEAD 提交"
+msgstr "不能解析 HEAD 提交"
 
 #: builtin/commit.c:1452 builtin/merge.c:509
 #, c-format
 msgid "could not open '%s' for reading"
-msgstr "无法打开 '%s' 读取"
+msgstr "不能为读入打开 '%s'"
 
 #: builtin/commit.c:1459
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
-msgstr "损坏的 MERGE_HEAD 文件 (%s)"
+msgstr "损坏的 MERGE_HEAD 文件(%s)"
 
 #: builtin/commit.c:1466
 msgid "could not read MERGE_MODE"
-msgstr "无法读取 MERGE_MODE"
+msgstr "不能读取 MERGE_MODE"
 
 #: builtin/commit.c:1485
 #, c-format
 msgid "could not read commit message: %s"
-msgstr "无法读取提交说明:%s"
+msgstr "不能读取提交说明:%s"
 
 #: builtin/commit.c:1499
 #, c-format
@@ -1686,7 +1688,7 @@ msgstr "终止提交因为提交说明为空。\n"
 
 #: builtin/commit.c:1514 builtin/merge.c:935 builtin/merge.c:968
 msgid "failed to write commit object"
-msgstr "写提交对象失败"
+msgstr "无法写提交对象"
 
 #: builtin/commit.c:1535
 msgid "cannot lock HEAD ref"
@@ -1702,8 +1704,8 @@ msgid ""
 "new_index file. Check that disk is not full or quota is\n"
 "not exceeded, and then \"git reset HEAD\" to recover."
 msgstr ""
-"版本库已被更新,但无法写入新暂存区文件。检查是否磁盘\n"
-"已满或磁盘配额耗尽,然后执行 \"git reset HEAD\" 恢复。"
+"版本库已更新,但无法写 new_index 文件。检查是否磁盘已满\n"
+"或磁盘配额已耗尽,然后执行 \"git reset HEAD\" 恢复。"
 
 #: builtin/describe.c:234
 #, c-format
@@ -1718,7 +1720,7 @@ msgstr "注释 tag %s 没有嵌入名称"
 #: builtin/describe.c:240
 #, c-format
 msgid "tag '%s' is really '%s' here"
-msgstr "tag '%s' 确是在 '%s'"
+msgstr "tag '%s' ç\9a\84ç¡®æ\98¯å\9c¨ '%s'"
 
 #: builtin/describe.c:267
 #, c-format
@@ -1761,7 +1763,7 @@ msgid ""
 "Try --always, or create some tags."
 msgstr ""
 "没有注释 tag 能描述 '%s'。\n"
-"尝试 --always,或创建一些 tag。"
+"尝试 --always,或创建一些 tag。"
 
 #: builtin/describe.c:378
 #, c-format
@@ -1774,8 +1776,8 @@ msgid ""
 "more than %i tags found; listed %i most recent\n"
 "gave up search at %s\n"
 msgstr ""
-"å\8f\91ç\8e°å¤\9aäº\8e %i ä¸ª tagï¼\9b列出最近的 %i 个\n"
-"放弃搜索 %s\n"
+"å\8f\91ç\8e°å¤\9aäº\8e %i ä¸ª tagï¼\8c列出最近的 %i 个\n"
+"在 %s 放弃搜索\n"
 
 #: builtin/describe.c:436
 msgid "--long is incompatible with --abbrev=0"
@@ -1783,7 +1785,7 @@ msgstr "--long 与 --abbrev=0 不兼容"
 
 #: builtin/describe.c:462
 msgid "No names found, cannot describe anything."
-msgstr "没有发现名称,无法描述任何东西"
+msgstr "没有发现名称,无法描述任何东西"
 
 #: builtin/describe.c:482
 msgid "--dirty is incompatible with committishes"
@@ -1849,7 +1851,7 @@ msgstr "[已拒绝]"
 msgid "[tag update]"
 msgstr "[tag更新]"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: builtin/fetch.c:286 builtin/fetch.c:313 builtin/fetch.c:331
 msgid "  (unable to update local ref)"
 msgstr "  (不能更新本地引用)"
@@ -1872,7 +1874,7 @@ msgstr "强制更新"
 
 #: builtin/fetch.c:353
 msgid "(non-fast-forward)"
-msgstr "(非快进式推送)"
+msgstr "(非快进式)"
 
 #: builtin/fetch.c:384 builtin/fetch.c:676
 #, c-format
@@ -1898,13 +1900,13 @@ msgstr ""
 "一些本地引用不能被更新;尝试运行\n"
 " 'git remote prune %s' 来删除旧的、有冲突的分支"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: builtin/fetch.c:540
 #, c-format
 msgid "   (%s will become dangling)\n"
 msgstr "   (%s 将成为悬空状态)\n"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: builtin/fetch.c:541
 #, c-format
 msgid "   (%s has become dangling)\n"
@@ -1952,11 +1954,11 @@ msgstr "不能获取 %s"
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
-msgstr "æ\9cªæ\8f\90ä¾\9bè¿\9cç¨\8bç\89\88æ\9c¬åº\93ã\80\82请æ\8f\90ä¾\9bä¸\80个URLæ\88\96è¿\9cç¨\8bç\89\88æ\9c¬åº\93å\90\8dï¼\8cç\94¨äº\8eè\8e·å\8f\96æ\96°ç\89\88æ\9c¬。"
+msgstr "æ\9cªæ\8c\87å®\9aè¿\9cç¨\8bç\89\88æ\9c¬åº\93ã\80\82请é\80\9aè¿\87ä¸\80个URLæ\88\96è¿\9cç¨\8bç\89\88æ\9c¬åº\93å\90\8dæ\8c\87å®\9aï¼\8cç\94¨ä»¥è\8e·å\8f\96æ\96°æ\8f\90交。"
 
 #: builtin/fetch.c:918
 msgid "You need to specify a tag name."
-msgstr "你需要提供一个 tag 名称"
+msgstr "您需要指定一个 tag 名称。"
 
 #: builtin/fetch.c:970
 msgid "fetch --all does not take a repository argument"
@@ -1973,7 +1975,7 @@ msgstr "没有这样的远程或远程组:%s"
 
 #: builtin/fetch.c:991
 msgid "Fetching a group and specifying refspecs does not make sense"
-msgstr "è\8e·å\8f\96ç»\84并æ\8f\90ä¾\9b引用表达式没有意义"
+msgstr "è\8e·å\8f\96ç»\84并æ\8c\87å®\9a引用表达式没有意义"
 
 #: builtin/gc.c:63
 #, c-format
@@ -1982,7 +1984,7 @@ msgstr "无效的 %s:'%s'"
 
 #: builtin/gc.c:78
 msgid "Too many options specified"
-msgstr "æ\8f\90ä¾\9b了太多的选项"
+msgstr "æ\8c\87å®\9a了太多的选项"
 
 #: builtin/gc.c:103
 #, c-format
@@ -2000,18 +2002,18 @@ msgid ""
 "Auto packing the repository for optimum performance. You may also\n"
 "run \"git gc\" manually. See \"git help gc\" for more information.\n"
 msgstr ""
-"自动打包版本库以求最佳性能。你还可以\n"
-"手动运行 \"git gc\"。 参见 \"git help gc\" 获取更多信息。\n"
+"自动打包版本库以求最佳性能。您还可以手动运行 \"git gc\"。\n"
+"参见 \"git help gc\" 以获取更多信息。\n"
 
 #: builtin/gc.c:256
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
-msgstr "有太多无指向的松散对象,运行 'git prune' 删除它们。"
+msgstr "有太多不可达的松散对象,运行 'git prune' 删除它们。"
 
 #: builtin/grep.c:216
 #, c-format
 msgid "grep: failed to create thread: %s"
-msgstr "grep无法创建线程:%s"
+msgstr "grep无法创建线程:%s"
 
 #: builtin/grep.c:402
 #, c-format
@@ -2021,7 +2023,7 @@ msgstr "无法切换目录:%s"
 #: builtin/grep.c:478 builtin/grep.c:512
 #, c-format
 msgid "unable to read tree (%s)"
-msgstr "无法读取代码树(%s)"
+msgstr "无法读取树(%s)"
 
 #: builtin/grep.c:526
 #, c-format
@@ -2053,7 +2055,7 @@ msgstr "--open-files-in-pager 仅用于工作区"
 
 #: builtin/grep.c:966
 msgid "--cached or --untracked cannot be used with --no-index."
-msgstr "--cached 或 --untracked 不能与 --no-index 共用"
+msgstr "--cached 或 --untracked 不能与 --no-index 共用"
 
 #: builtin/grep.c:971
 msgid "--no-index or --untracked cannot be used with revs."
@@ -2061,7 +2063,7 @@ msgstr "--no-index 或 --untracked 不能和版本共用。"
 
 #: builtin/grep.c:974
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
-msgstr "--[no-]exclude-standard 不能用于跟踪内容。"
+msgstr "--[no-]exclude-standard 不能用于跟踪内容。"
 
 #: builtin/grep.c:982
 msgid "both --cached and trees are given."
@@ -2105,7 +2107,7 @@ msgstr "太长的符号链接 %s"
 #: builtin/init-db.c:102
 #, c-format
 msgid "cannot symlink '%s' '%s'"
-msgstr "不能创建符号链接 '%s' 到 '%s'"
+msgstr "不能自 '%s' 到 '%s' 创建符号链接"
 
 #: builtin/init-db.c:106
 #, c-format
@@ -2175,10 +2177,10 @@ msgstr "重新初始化现存的"
 msgid "Initialized empty"
 msgstr "初始化空的"
 
-#  汉字字串合并,之间无空格,故删除前导空格
+#  译者:中文字符串拼接,可删除前导空格
 #: builtin/init-db.c:421
 msgid " shared"
-msgstr "共享"
+msgstr "共享"
 
 #: builtin/init-db.c:440
 msgid "cannot tell cwd"
@@ -2200,7 +2202,7 @@ msgid ""
 "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
 "dir=<directory>)"
 msgstr ""
-"不允许 %s(或 --work-tree=<directory>)而没有 %s(或 --git-dir=<directory>)"
+"不允许 %s(或 --work-tree=<directory>)而没有指定 %s(或 --git-dir=<directory>)"
 
 #: builtin/init-db.c:578
 msgid "Cannot access current working directory"
@@ -2219,7 +2221,7 @@ msgstr "最终输出:%d %s\n"
 #: builtin/log.c:395 builtin/log.c:483
 #, c-format
 msgid "Could not read object %s"
-msgstr "无法读取对象 %s"
+msgstr "不能读取对象 %s"
 
 #: builtin/log.c:507
 #, c-format
@@ -2249,7 +2251,7 @@ msgstr "不是一个范围。"
 
 #: builtin/log.c:739
 msgid "Could not extract email from committer identity."
-msgstr "无法从提交者身份中提取邮件地址。"
+msgstr "不能从提交者身份中提取邮件地址。"
 
 #: builtin/log.c:785
 msgid "Cover letter needs email format"
@@ -2301,7 +2303,7 @@ msgstr "标准输出或目录,哪一个?"
 #: builtin/log.c:1257
 #, c-format
 msgid "Could not create directory '%s'"
-msgstr "无法创建目录 '%s'"
+msgstr "不能创建目录 '%s'"
 
 #: builtin/log.c:1410
 msgid "Failed to create output files"
@@ -2311,7 +2313,7 @@ msgstr "无法创建输出文件"
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
-msgstr "无法找到跟踪的远程分支,请手工提供 <upstream>。\n"
+msgstr "不能找到跟踪的远程分支,请手工指定 <upstream>。\n"
 
 #: builtin/log.c:1530 builtin/log.c:1532 builtin/log.c:1544
 #, c-format
@@ -2325,7 +2327,7 @@ msgstr "开关 `m' 需要一个值"
 #: builtin/merge.c:128
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
-msgstr "无法找到合并策略 '%s'。\n"
+msgstr "不能找到合并策略 '%s'。\n"
 
 #: builtin/merge.c:129
 #, c-format
@@ -2354,7 +2356,7 @@ msgstr "不是一个有效对象:%s"
 msgid "read-tree failed"
 msgstr "读取树失败"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: builtin/merge.c:317
 msgid " (nothing to squash)"
 msgstr " (无可压缩)"
@@ -2385,7 +2387,7 @@ msgstr "'%s' 没有指向一个提交"
 #: builtin/merge.c:536
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
-msgstr "错的 branch.%s.mergeoptions 字串:%s"
+msgstr "坏的 branch.%s.mergeoptions 字符串:%s"
 
 #: builtin/merge.c:629
 msgid "git write-tree failed to write a tree"
@@ -2397,7 +2399,7 @@ msgstr "无法读取缓存"
 
 #: builtin/merge.c:696
 msgid "Unable to write index."
-msgstr "不能写暂存区。"
+msgstr "不能写索引。"
 
 #: builtin/merge.c:709
 msgid "Not handling anything other than two heads merge."
@@ -2457,15 +2459,15 @@ msgstr "'%s' 不是一个提交"
 
 #: builtin/merge.c:1057
 msgid "No current branch."
-msgstr "当前不在分支上。"
+msgstr "没有当前分支。"
 
 #: builtin/merge.c:1059
 msgid "No remote for the current branch."
-msgstr "当前分支没有远程版本库。"
+msgstr "当前分支没有对应的远程版本库。"
 
 #: builtin/merge.c:1061
 msgid "No default upstream defined for the current branch."
-msgstr "å½\93å\89\8då\88\86æ\94¯æ\9cªå®\9aä¹\89é»\98认上游分支。"
+msgstr "å½\93å\89\8då\88\86æ\94¯æ²¡æ\9c\89å®\9aä¹\89é»\98认ç\9a\84上游分支。"
 
 #: builtin/merge.c:1066
 #, c-format
@@ -2474,7 +2476,7 @@ msgstr "%s 没有来自 %s 的远程跟踪分支"
 
 #: builtin/merge.c:1188
 msgid "There is no merge to abort (MERGE_HEAD missing)."
-msgstr "没有要终止的合并(MERGE_HEAD 丢失)"
+msgstr "没有要终止的合并(MERGE_HEAD 丢失)"
 
 #: builtin/merge.c:1204 git-pull.sh:31
 msgid ""
@@ -2482,7 +2484,7 @@ msgid ""
 "Please, commit your changes before you can merge."
 msgstr ""
 "您尚未结束您的合并(存在 MERGE_HEAD)。\n"
-"请å\85\88æ\8f\90交æ\82¨ç\9a\84ä¿®æ\94¹ï¼\8cæ\82¨æ\89\8dè\83½å\90\88并。"
+"请å\9c¨å\90\88并å\89\8då\85\88æ\8f\90交æ\82¨ç\9a\84ä¿®æ\94¹。"
 
 #: builtin/merge.c:1207 git-pull.sh:34
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
@@ -2494,7 +2496,7 @@ msgid ""
 "Please, commit your changes before you can merge."
 msgstr ""
 "您尚未结束您的拣选(存在 CHERRY_PICK_HEAD)。\n"
-"请å\85\88æ\8f\90交æ\82¨ç\9a\84ä¿®æ\94¹ï¼\8cæ\82¨æ\89\8dè\83½å\90\88并。"
+"请å\9c¨å\90\88并å\89\8då\85\88æ\8f\90交æ\82¨ç\9a\84ä¿®æ\94¹。"
 
 #: builtin/merge.c:1214
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
@@ -2510,11 +2512,11 @@ msgstr "您不能将 --no-ff 与 --ff-only 共用。"
 
 #: builtin/merge.c:1235
 msgid "No commit specified and merge.defaultToUpstream not set."
-msgstr "æ\9cªæ\8c\87å\87º提交并且 merge.defaultToUpstream 未设置。"
+msgstr "æ\9cªæ\8c\87å®\9a提交并且 merge.defaultToUpstream 未设置。"
 
 #: builtin/merge.c:1266
 msgid "Can merge only exactly one commit into empty head"
-msgstr "只将一个提交合并到空分支上"
+msgstr "只将一个提交合并到空分支上"
 
 #: builtin/merge.c:1269
 msgid "Squash commit into empty head not supported yet"
@@ -2537,7 +2539,7 @@ msgstr "更新 %s..%s\n"
 #: builtin/merge.c:1423
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
-msgstr "尝试非常小的暂存区内合并...\n"
+msgstr "尝试非常小的索引内合并...\n"
 
 #: builtin/merge.c:1430
 #, c-format
@@ -2598,7 +2600,7 @@ msgstr "不能将目录移动到文件"
 #: builtin/mv.c:128
 #, c-format
 msgid "Huh? %.*s is in index?"
-msgstr "嗯?%.*s 在暂存区中?"
+msgstr "嗯?%.*s 在索引中?"
 
 #: builtin/mv.c:140
 msgid "source directory is empty"
@@ -2698,7 +2700,7 @@ msgstr "不能打开或读取 '%s'"
 #: builtin/notes.c:968 builtin/reset.c:293 builtin/tag.c:537
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
-msgstr "无法解析 '%s' 为一个有效引用"
+msgstr "无法解析 '%s' 为一个有效引用"
 
 #: builtin/notes.c:275
 #, c-format
@@ -2712,7 +2714,7 @@ msgstr "不能提交未初始化/未引用的注解树"
 #: builtin/notes.c:340
 #, c-format
 msgid "Bad notes.rewriteMode value: '%s'"
-msgstr "错误的 notes.rewriteMode 值:'%s'"
+msgstr "的 notes.rewriteMode 值:'%s'"
 
 #: builtin/notes.c:350
 #, c-format
@@ -2724,7 +2726,7 @@ msgstr "拒绝向 %s(在 refs/notes/ 之外)写入注解"
 #: builtin/notes.c:377
 #, c-format
 msgid "Bad %s value: '%s'"
-msgstr "错误的 %s 值:'%s'"
+msgstr "的 %s 值:'%s'"
 
 #: builtin/notes.c:441
 #, c-format
@@ -2734,7 +2736,7 @@ msgstr "非法的输入行:'%s'。"
 #: builtin/notes.c:456
 #, c-format
 msgid "Failed to copy notes from '%s' to '%s'"
-msgstr "无法从 '%s' 拷贝注解到 '%s'"
+msgstr "无法从 '%s' 到 '%s' 拷贝注解"
 
 #: builtin/notes.c:500 builtin/notes.c:554 builtin/notes.c:627
 #: builtin/notes.c:639 builtin/notes.c:712 builtin/notes.c:759
@@ -2781,7 +2783,7 @@ msgid ""
 "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n"
 "Please use 'git notes add -f -m/-F/-c/-C' instead.\n"
 msgstr ""
-"选项 -m/-F/-c/-C 已为 'edit' 子命令废弃。\n"
+"子命令 'edit' 的选项 -m/-F/-c/-C 已弃用。\n"
 "请换用 'git notes add -f -m/-F/-c/-C'。\n"
 
 #: builtin/notes.c:971
@@ -2797,17 +2799,17 @@ msgstr "未知子命令:%s"
 #: builtin/pack-objects.c:2310
 #, c-format
 msgid "unsupported index version %s"
-msgstr "不支持的暂存区版本 %s"
+msgstr "不支持的索引版本 %s"
 
 #: builtin/pack-objects.c:2314
 #, c-format
 msgid "bad index version '%s'"
-msgstr "错误的暂存区版本 '%s'"
+msgstr "坏的索引版本 '%s'"
 
 #: builtin/pack-objects.c:2322
 #, c-format
 msgid "option %s does not accept negative form"
-msgstr "选项 '%s' 不接受否定格式"
+msgstr "选项 %s 不接受否定格式"
 
 #: builtin/pack-objects.c:2326
 #, c-format
@@ -2820,7 +2822,7 @@ msgstr "tag 简写没有跟 <tag> 参数"
 
 #: builtin/push.c:63
 msgid "--delete only accepts plain target ref names"
-msgstr "--delete 只接受简单的引用名称"
+msgstr "--delete 只接受简单的目标引用名"
 
 #: builtin/push.c:73
 #, c-format
@@ -2832,7 +2834,7 @@ msgid ""
 "    git push %s HEAD:<name-of-remote-branch>\n"
 msgstr ""
 "您当前不在一个分支上。\n"
-"现在为推送当前历史(分离头指针),使用\n"
+"现在为推送当前(分离头指针)的历史,使用\n"
 "\n"
 "    git push %s HEAD:<name-of-remote-branch>\n"
 
@@ -2857,7 +2859,7 @@ msgstr "当前分支 %s 有多个上游分支,拒绝推送。"
 #: builtin/push.c:111
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
-msgstr "æ\82¨æ²¡æ\9c\89为æ\8e¨é\80\81æ\8f\90ä¾\9b任何引用表达式,并且 push.default 为 \"nothing\"。"
+msgstr "æ\82¨æ²¡æ\9c\89为æ\8e¨é\80\81æ\8c\87å®\9a任何引用表达式,并且 push.default 为 \"nothing\"。"
 
 #: builtin/push.c:131
 #, c-format
@@ -2876,14 +2878,14 @@ msgid ""
 "Merge the remote changes (e.g. 'git pull') before pushing again.  See the\n"
 "'Note about fast-forwards' section of 'git push --help' for details.\n"
 msgstr ""
-"为防止您丢失提交历史,禁止非快进式推送。\n"
+"为了防止您丢失提交历史,非快进式更新被拒绝。\n"
 "再次推送前先与远程变更合并(如 'git pull')。详见\n"
 "'git push --help' 中的 'Note about fast-forwards' 小节。\n"
 
 #: builtin/push.c:160
 #, c-format
 msgid "bad repository '%s'"
-msgstr "错误的版本库 '%s'"
+msgstr "的版本库 '%s'"
 
 #: builtin/push.c:161
 msgid ""
@@ -2897,8 +2899,8 @@ msgid ""
 "\n"
 "    git push <name>\n"
 msgstr ""
-"æ\9cª配置推送目标。\n"
-"æ\88\96è\80\85é\80\9aè¿\87å\91½ä»¤è¡\8cæ\8f\90ä¾\9bURL,或者用下面命令配置一个远程版本库\n"
+"没æ\9c\89配置推送目标。\n"
+"æ\88\96è\80\85é\80\9aè¿\87å\91½ä»¤è¡\8cæ\8c\87å®\9aURL,或者用下面命令配置一个远程版本库\n"
 "\n"
 "    git remote add <name> <url>\n"
 "\n"
@@ -2965,7 +2967,7 @@ msgstr "无法找到 %s 指向的树。"
 
 #: builtin/reset.c:96
 msgid "Could not write new index file."
-msgstr "无法写入新的暂存区文件。"
+msgstr "不能写入新的索引文件。"
 
 #: builtin/reset.c:106
 #, c-format
@@ -2974,13 +2976,13 @@ msgstr "HEAD 现在位于 %s"
 
 #: builtin/reset.c:130
 msgid "Could not read index"
-msgstr "不能读取暂存区"
+msgstr "不能读取索引"
 
 #: builtin/reset.c:133
 msgid "Unstaged changes after reset:"
-msgstr "重置后变更撤出暂存区:"
+msgstr "重置后撤出暂存区的变更:"
 
-#  汉字之间无空格,故删除%s前后空格
+#  译者:汉字之间无空格,故删除%s前后空格
 #: builtin/reset.c:223
 #, c-format
 msgid "Cannot do a %s reset in the middle of a merge."
@@ -2999,13 +3001,13 @@ msgstr "--patch 与 --{hard,mixed,soft} 不兼容"
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr "--mixed 带路径已弃用,代之以 'git reset -- <paths>'。"
 
-#  汉字之间无空格,故删除%s前后空格
+#  译者:汉字之间无空格,故删除%s前后空格
 #: builtin/reset.c:313
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "不能带路径进行%s重置。"
 
-#  汉字之间无空格,故删除%s前后空格
+#  译者:汉字之间无空格,故删除%s前后空格
 #: builtin/reset.c:325
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
@@ -3014,12 +3016,12 @@ msgstr "不能对裸版本库进行%s重置"
 #: builtin/reset.c:341
 #, c-format
 msgid "Could not reset index file to revision '%s'."
-msgstr "不能重置暂存区至版本 '%s'。"
+msgstr "不能重置索引文件至版本 '%s'。"
 
 #: builtin/revert.c:70 builtin/revert.c:91
 #, c-format
 msgid "%s: %s cannot be used with %s"
-msgstr "%s%s 不能和 %s 共用"
+msgstr "%s%s 不能和 %s 共用"
 
 #: builtin/revert.c:126
 msgid "program error"
@@ -3039,7 +3041,7 @@ msgid ""
 "'%s' has staged content different from both the file and the HEAD\n"
 "(use -f to force removal)"
 msgstr ""
-"'%s' 暂存的内容和工作区文件及 HEAD 中的都不一样\n"
+"'%s' 暂存的内容和工作区及 HEAD 中的都不一样\n"
 "(使用 -f 强制删除)"
 
 #: builtin/rm.c:115
@@ -3048,7 +3050,7 @@ msgid ""
 "'%s' has changes staged in the index\n"
 "(use --cached to keep the file, or -f to force removal)"
 msgstr ""
-"'%s' 有变更已加入暂存区中\n"
+"'%s' 有变更已暂存至索引中\n"
 "(使用 --cached 保存文件,或用 -f 强制删除)"
 
 #: builtin/rm.c:119
@@ -3139,11 +3141,11 @@ msgstr "无法写 tag 文件"
 
 #: builtin/tag.c:321
 msgid "bad object type."
-msgstr "无效的对象类型"
+msgstr "坏的对象类型。"
 
 #: builtin/tag.c:334
 msgid "tag header too big."
-msgstr "tag 头信息太大"
+msgstr "tag 头信息太大"
 
 #: builtin/tag.c:366
 msgid "no tag message?"
@@ -3186,7 +3188,7 @@ msgstr "太多参数"
 #: builtin/tag.c:540
 #, c-format
 msgid "'%s' is not a valid tag name."
-msgstr "'%s' 不是一个有效的tag名称"
+msgstr "'%s' 不是一个有效的tag名称"
 
 #: builtin/tag.c:545
 #, c-format
@@ -3222,11 +3224,11 @@ msgid ""
 "It does not apply to blobs recorded in its index."
 msgstr ""
 "您是否曾手动编辑过您的补丁?\n"
-"无法应用补丁到暂存区的数据中。"
+"无法应用补丁到索引中的数据上。"
 
 #: git-am.sh:156
 msgid "Falling back to patching base and 3-way merge..."
-msgstr "转而使用补丁应用的基础版本和三路合并..."
+msgstr "回退到补丁基础版本并使用三路合并..."
 
 #: git-am.sh:268
 msgid "Only one StGIT patch series can be applied at once"
@@ -3241,54 +3243,54 @@ msgstr "不支持 $patch_format 补丁格式。"
 msgid "Patch format detection failed."
 msgstr "补丁格式检测失败。"
 
-#: git-am.sh:409
+#: git-am.sh:411
 msgid "-d option is no longer supported.  Do not use."
 msgstr "不再支持 -d 选项。不要使用。"
 
-#: git-am.sh:472
+#: git-am.sh:474
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
 msgstr "之前的变基目录 $dotest 仍然存在但给出了mbox。"
 
-#: git-am.sh:477
+#: git-am.sh:479
 msgid "Please make up your mind. --skip or --abort?"
 msgstr "请下决心。--skip 或是 --abort ?"
 
-#: git-am.sh:504
+#: git-am.sh:506
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr "解决操作未进行,我们不会继续。"
 
-#: git-am.sh:570
+#: git-am.sh:572
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
-msgstr "脏的暂存区:不能应用补丁(脏文件:$files)"
+msgstr "脏的索引:不能应用补丁(脏文件:$files)"
 
-#: git-am.sh:746
+#: git-am.sh:748
 msgid "cannot be interactive without stdin connected to a terminal."
-msgstr "没æ\9c\89å\92\8cç»\88端å\85³è\81\94ç\9a\84æ \87å\87\86è¾\93å\85¥不能进行交互式操作。"
+msgstr "æ \87å\87\86è¾\93å\85¥æ²¡æ\9c\89å\92\8cç»\88端å\85³è\81\94ï¼\8c不能进行交互式操作。"
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
 #. in your translation. The program will only accept English
 #. input at this point.
-#: git-am.sh:757
+#: git-am.sh:759
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr "应用?[y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 
-#: git-am.sh:793
+#: git-am.sh:795
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr "正应用:$FIRSTLINE"
 
-#: git-am.sh:838
+#: git-am.sh:840
 msgid "No changes -- Patch already applied."
 msgstr "没有变更 -- 补丁已经应用过。"
 
-#: git-am.sh:864
+#: git-am.sh:866
 msgid "applying to an empty history"
 msgstr "正应用到一个空历史上"
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #. TRANSLATORS: Make sure to include [Y] and [n] in your
 #. translation. The program will only accept English input
 #. at this point.
@@ -3322,17 +3324,17 @@ msgstr "不会在已查找过的树上二分查找"
 
 #: git-bisect.sh:144
 msgid "Bad HEAD - strange symbolic ref"
-msgstr "错误的 HEAD - 奇怪的符号引用"
+msgstr "的 HEAD - 奇怪的符号引用"
 
 #: git-bisect.sh:189
 #, sh-format
 msgid "Bad bisect_write argument: $state"
-msgstr "错误的bisect_write参数:$state"
+msgstr "坏的 bisect_write 参数:$state"
 
 #: git-bisect.sh:218
 #, sh-format
 msgid "Bad rev input: $arg"
-msgstr "输入错误版本:$arg"
+msgstr "输入坏的版本:$arg"
 
 #: git-bisect.sh:232
 msgid "Please call 'bisect_state' with at least one argument."
@@ -3347,7 +3349,7 @@ msgstr "输入坏的版本:$rev"
 msgid "'git bisect bad' can take only one argument."
 msgstr "'git bisect bad' 只能带一个参数。"
 
-#  注意保持句尾空格
+#  译者:注意保持句尾空格
 #. TRANSLATORS: Make sure to include [Y] and [n] in your
 #. translation. The program will only accept English input
 #. at this point.
@@ -3384,7 +3386,7 @@ msgstr "?? 您在说什么?"
 
 #: git-bisect.sh:474
 msgid "We are not bisecting."
-msgstr "我们没有进行二分查找。"
+msgstr "我们没有二分查找。"
 
 #: git-pull.sh:21
 msgid ""
@@ -3392,17 +3394,17 @@ msgid ""
 "Please, fix them up in the work tree, and then use 'git add/rm <file>'\n"
 "as appropriate to mark resolution, or use 'git commit -a'."
 msgstr ""
-"Pull 不可用,因为尚有未合并的文件。请先在工作区改正文件,\n"
+"Pull 不可用,因为尚有未合并的文件。请先在工作区改正文件,\n"
 "然后酌情使用 'git add/rm <file>' 标记解决方案,\n"
-"或使用 'git commit -a'。"
+"或使用 'git commit -a'。"
 
 #: git-pull.sh:25
 msgid "Pull is not possible because you have unmerged files."
-msgstr "Pull 不可用,因为尚有未合并的文件。"
+msgstr "Pull 不可用,因为尚有未合并的文件。"
 
 #: git-pull.sh:197
 msgid "updating an unborn branch with changes added to the index"
-msgstr "更新尚未诞生的分支,变更添加至暂存区"
+msgstr "更新尚未诞生的分支,变更添加至索引"
 
 #: git-pull.sh:253
 msgid "Cannot merge multiple branches into empty head"
@@ -3422,7 +3424,7 @@ msgstr "您尚未建立初始提交"
 
 #: git-stash.sh:89
 msgid "Cannot save the current index state"
-msgstr "无法保存当前暂存区状态"
+msgstr "无法保存当前索引状态"
 
 #: git-stash.sh:123 git-stash.sh:136
 msgid "Cannot save the current worktree state"
@@ -3430,11 +3432,11 @@ msgstr "无法保存当前工作区状态"
 
 #: git-stash.sh:140
 msgid "No changes selected"
-msgstr "没有修改被选择"
+msgstr "没有选择变更"
 
 #: git-stash.sh:143
 msgid "Cannot remove temporary index (can't happen)"
-msgstr "无法删除临时暂存区(不应发生)"
+msgstr "无法删除临时索引(不应发生)"
 
 #: git-stash.sh:156
 msgid "Cannot record working tree state"
@@ -3446,7 +3448,7 @@ msgstr "没有要保存的本地修改"
 
 #: git-stash.sh:227
 msgid "Cannot initialize stash"
-msgstr "无法初始化stash"
+msgstr "无法初始化 stash"
 
 #: git-stash.sh:235
 msgid "Cannot save the current status"
@@ -3458,12 +3460,12 @@ msgstr "无法删除工作区变更"
 
 #: git-stash.sh:352
 msgid "No stash found."
-msgstr "未发现stash。"
+msgstr "未发现 stash。"
 
 #: git-stash.sh:359
 #, sh-format
 msgid "Too many revisions specified: $REV"
-msgstr "æ\8f\90ä¾\9b太多的版本:$REV"
+msgstr "æ\8c\87å®\9aäº\86太多的版本:$REV"
 
 #: git-stash.sh:365
 #, sh-format
@@ -3473,16 +3475,16 @@ msgstr "$reference 不是有效的引用"
 #: git-stash.sh:393
 #, sh-format
 msgid "'$args' is not a stash-like commit"
-msgstr "'$args' 不是stash样提交"
+msgstr "'$args' 不是 stash 样提交"
 
 #: git-stash.sh:404
 #, sh-format
 msgid "'$args' is not a stash reference"
-msgstr "'$args' 不是一个stash引用"
+msgstr "'$args' 不是一个 stash 引用"
 
 #: git-stash.sh:412
 msgid "unable to refresh index"
-msgstr "无法刷新暂存区"
+msgstr "无法刷新索引"
 
 #: git-stash.sh:416
 msgid "Cannot apply a stash in the middle of a merge"
@@ -3490,11 +3492,11 @@ msgstr "无法在合并过程中恢复进度"
 
 #: git-stash.sh:424
 msgid "Conflicts in index. Try without --index."
-msgstr "暂存区冲突。尝试不用 --index。"
+msgstr "索引中有冲突。尝试不使用 --index。"
 
 #: git-stash.sh:426
 msgid "Could not save index tree"
-msgstr "无法保存暂存区"
+msgstr "不能保存索引树"
 
 #: git-stash.sh:460
 msgid "Cannot unstage modified files"
@@ -3508,7 +3510,7 @@ msgstr "丢弃了 ${REV} ($s)"
 #: git-stash.sh:492
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
-msgstr "${REV}: 无法丢弃进度条目"
+msgstr "${REV}:不能丢弃进度条目"
 
 #: git-stash.sh:499
 msgid "No branch name specified"
@@ -3528,10 +3530,15 @@ msgstr "无法从 url '$remoteurl' 剥离一个组件"
 msgid "No submodule mapping found in .gitmodules for path '$path'"
 msgstr "未在 .gitmodules 中发现路径 '$path' 的子模组映射"
 
-#: git-submodule.sh:173
+#: git-submodule.sh:149
 #, sh-format
 msgid "Clone of '$url' into submodule path '$path' failed"
-msgstr "克隆 '$url' 到子模组路径 '$path' 失败"
+msgstr "无法克隆 '$url' 到子模组路径 '$path'"
+
+#: git-submodule.sh:159
+#, sh-format
+msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
+msgstr "Gitdir '$a' 在子模组路径 '$b' 之下或者相反"
 
 #: git-submodule.sh:247
 #, sh-format
@@ -3541,7 +3548,7 @@ msgstr "版本库URL:'$repo' 必须是绝对路径或以 ./|../ 起始"
 #: git-submodule.sh:264
 #, sh-format
 msgid "'$path' already exists in the index"
-msgstr "'$path' 已经存在于暂存区中"
+msgstr "'$path' 已经存在于索引中"
 
 #: git-submodule.sh:281
 #, sh-format
@@ -3576,7 +3583,7 @@ msgstr "停止于 '$path',脚本返回非零值。"
 #: git-submodule.sh:401
 #, sh-format
 msgid "No url found for submodule path '$path' in .gitmodules"
-msgstr "在 .gitmodules 中未找到子模组路径 '$path' 的url"
+msgstr "在 .gitmodules 中未找到子模组路径 '$path' 的 url"
 
 #: git-submodule.sh:410
 #, sh-format
@@ -3600,7 +3607,7 @@ msgid ""
 "Maybe you want to use 'update --init'?"
 msgstr ""
 "子模组路径 '$path' 没有初始化\n"
-"也许想用 'update --init'?"
+"也许想用 'update --init'?"
 
 #: git-submodule.sh:532
 #, sh-format
@@ -3651,19 +3658,19 @@ msgstr "无法递归进子模组路径 '$path'"
 msgid "--"
 msgstr "--"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: git-submodule.sh:766
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_src"
 msgstr "  警告:$name 未包含提交 $sha1_src"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: git-submodule.sh:769
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_dst"
 msgstr "  警告:$name 未包含提交 $sha1_dst"
 
-#  注意保持前导空格
+#  译者:注意保持前导空格
 #: git-submodule.sh:772
 #, sh-format
 msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
@@ -3680,4 +3687,4 @@ msgstr "子模组"
 #: git-submodule.sh:969
 #, sh-format
 msgid "Synchronizing submodule url for '$name'"
-msgstr "为 '$name' 同步子模组url"
+msgstr "为 '$name' 同步子模组 url"
index 8688b8f2d45a493aa8b51b29f7d46b2abff7f30e..f2dee308b887efc9a23ee1b2dcda9119f23cc9a4 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -531,41 +531,24 @@ static size_t format_person_part(struct strbuf *sb, char part,
 {
        /* currently all placeholders have same length */
        const int placeholder_len = 2;
-       int start, end, tz = 0;
+       int tz;
        unsigned long date = 0;
-       char *ep;
-       const char *name_start, *name_end, *mail_start, *mail_end, *msg_end = msg+len;
        char person_name[1024];
        char person_mail[1024];
+       struct ident_split s;
+       const char *name_start, *name_end, *mail_start, *mail_end;
 
-       /* advance 'end' to point to email start delimiter */
-       for (end = 0; end < len && msg[end] != '<'; end++)
-               ; /* do nothing */
-
-       /*
-        * When end points at the '<' that we found, it should have
-        * matching '>' later, which means 'end' must be strictly
-        * below len - 1.
-        */
-       if (end >= len - 2)
+       if (split_ident_line(&s, msg, len) < 0)
                goto skip;
 
-       /* Seek for both name and email part */
-       name_start = msg;
-       name_end = msg+end;
-       while (name_end > name_start && isspace(*(name_end-1)))
-               name_end--;
-       mail_start = msg+end+1;
-       mail_end = mail_start;
-       while (mail_end < msg_end && *mail_end != '>')
-               mail_end++;
-       if (mail_end == msg_end)
-               goto skip;
-       end = mail_end-msg;
+       name_start = s.name_begin;
+       name_end = s.name_end;
+       mail_start = s.mail_begin;
+       mail_end = s.mail_end;
 
        if (part == 'N' || part == 'E') { /* mailmap lookup */
-               strlcpy(person_name, name_start, name_end-name_start+1);
-               strlcpy(person_mail, mail_start, mail_end-mail_start+1);
+               strlcpy(person_name, name_start, name_end - name_start + 1);
+               strlcpy(person_mail, mail_start, mail_end - mail_start + 1);
                mailmap_name(person_mail, sizeof(person_mail), person_name, sizeof(person_name));
                name_start = person_name;
                name_end = name_start + strlen(person_name);
@@ -581,28 +564,20 @@ static size_t format_person_part(struct strbuf *sb, char part,
                return placeholder_len;
        }
 
-       /* advance 'start' to point to date start delimiter */
-       for (start = end + 1; start < len && isspace(msg[start]); start++)
-               ; /* do nothing */
-       if (start >= len)
-               goto skip;
-       date = strtoul(msg + start, &ep, 10);
-       if (msg + start == ep)
+       if (!s.date_begin)
                goto skip;
 
+       date = strtoul(s.date_begin, NULL, 10);
+
        if (part == 't') {      /* date, UNIX timestamp */
-               strbuf_add(sb, msg + start, ep - (msg + start));
+               strbuf_add(sb, s.date_begin, s.date_end - s.date_begin);
                return placeholder_len;
        }
 
        /* parse tz */
-       for (start = ep - msg + 1; start < len && isspace(msg[start]); start++)
-               ; /* do nothing */
-       if (start + 1 < len) {
-               tz = strtoul(msg + start + 1, NULL, 10);
-               if (msg[start] == '-')
-                       tz = -tz;
-       }
+       tz = strtoul(s.tz_begin + 1, NULL, 10);
+       if (*s.tz_begin == '-')
+               tz = -tz;
 
        switch (part) {
        case 'd':       /* date */
@@ -621,8 +596,9 @@ static size_t format_person_part(struct strbuf *sb, char part,
 
 skip:
        /*
-        * bogus commit, 'sb' cannot be updated, but we still need to
-        * compute a valid return value.
+        * reading from either a bogus commit, or a reflog entry with
+        * %gn, %ge, etc.; 'sb' cannot be updated, but we still need
+        * to compute a valid return value.
         */
        if (part == 'n' || part == 'e' || part == 't' || part == 'd'
            || part == 'D' || part == 'r' || part == 'i')
index 4f06a0e450359744528d3b125fb09eacebf1eb4a..ad314f08b9abd9a16b410483f9a9629ce59345cf 100644 (file)
@@ -19,6 +19,7 @@
 #include "pack-revindex.h"
 #include "sha1-lookup.h"
 #include "bulk-checkin.h"
+#include "streaming.h"
 
 #ifndef O_NOATIME
 #if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
@@ -1146,10 +1147,47 @@ static const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
        return NULL;
 }
 
-int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type)
+/*
+ * With an in-core object data in "map", rehash it to make sure the
+ * object name actually matches "sha1" to detect object corruption.
+ * With "map" == NULL, try reading the object named with "sha1" using
+ * the streaming interface and rehash it to do the same.
+ */
+int check_sha1_signature(const unsigned char *sha1, void *map,
+                        unsigned long size, const char *type)
 {
        unsigned char real_sha1[20];
-       hash_sha1_file(map, size, type, real_sha1);
+       enum object_type obj_type;
+       struct git_istream *st;
+       git_SHA_CTX c;
+       char hdr[32];
+       int hdrlen;
+
+       if (map) {
+               hash_sha1_file(map, size, type, real_sha1);
+               return hashcmp(sha1, real_sha1) ? -1 : 0;
+       }
+
+       st = open_istream(sha1, &obj_type, &size, NULL);
+       if (!st)
+               return -1;
+
+       /* Generate the header */
+       hdrlen = sprintf(hdr, "%s %lu", typename(obj_type), size) + 1;
+
+       /* Sha1.. */
+       git_SHA1_Init(&c);
+       git_SHA1_Update(&c, hdr, hdrlen);
+       for (;;) {
+               char buf[1024 * 16];
+               ssize_t readlen = read_istream(st, buf, sizeof(buf));
+
+               if (!readlen)
+                       break;
+               git_SHA1_Update(&c, buf, readlen);
+       }
+       git_SHA1_Final(real_sha1, &c);
+       close_istream(st);
        return hashcmp(sha1, real_sha1) ? -1 : 0;
 }
 
index 71072e1b1da670cdb4b048a3a6e83a4ae806bf5f..7e7ee2be6fe147ff660f8ab25618fbe4d4d0f11c 100644 (file)
@@ -489,3 +489,58 @@ static open_method_decl(incore)
 
        return st->u.incore.buf ? 0 : -1;
 }
+
+
+/****************************************************************
+ * Users of streaming interface
+ ****************************************************************/
+
+int stream_blob_to_fd(int fd, unsigned const char *sha1, struct stream_filter *filter,
+                     int can_seek)
+{
+       struct git_istream *st;
+       enum object_type type;
+       unsigned long sz;
+       ssize_t kept = 0;
+       int result = -1;
+
+       st = open_istream(sha1, &type, &sz, filter);
+       if (!st)
+               return result;
+       if (type != OBJ_BLOB)
+               goto close_and_exit;
+       for (;;) {
+               char buf[1024 * 16];
+               ssize_t wrote, holeto;
+               ssize_t readlen = read_istream(st, buf, sizeof(buf));
+
+               if (!readlen)
+                       break;
+               if (can_seek && sizeof(buf) == readlen) {
+                       for (holeto = 0; holeto < readlen; holeto++)
+                               if (buf[holeto])
+                                       break;
+                       if (readlen == holeto) {
+                               kept += holeto;
+                               continue;
+                       }
+               }
+
+               if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1)
+                       goto close_and_exit;
+               else
+                       kept = 0;
+               wrote = write_in_full(fd, buf, readlen);
+
+               if (wrote != readlen)
+                       goto close_and_exit;
+       }
+       if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 ||
+                    write(fd, "", 1) != 1))
+               goto close_and_exit;
+       result = 0;
+
+ close_and_exit:
+       close_istream(st);
+       return result;
+}
index 589e857b8c4ad68e30b91da2eb29a076b98ef903..3e827709c85eeaf6669d05d0d59e288541ceb579 100644 (file)
@@ -12,4 +12,6 @@ extern struct git_istream *open_istream(const unsigned char *, enum object_type
 extern int close_istream(struct git_istream *);
 extern ssize_t read_istream(struct git_istream *, char *, size_t);
 
+extern int stream_blob_to_fd(int fd, const unsigned char *, struct stream_filter *, int can_seek);
+
 #endif /* STREAMING_H */
index 80e04f3c8cfe9a49865ef54f61efaa3bc67dca5c..9c5e5c0c30676d5dc8be685c97b7d7f303dd7842 100644 (file)
@@ -13,7 +13,7 @@ enum {
 void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
                const char *path);
 int submodule_config(const char *var, const char *value, void *cb);
-void gitmodules_config();
+void gitmodules_config(void);
 int parse_submodule_config_option(const char *var, const char *value);
 void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *);
 int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg);
index 267f4c8ba3284d30492d8907b6fc3230f40e02fc..f028fd1418285107a90e170a6ea1cd7657e31bb8 100755 (executable)
@@ -1,39 +1,60 @@
 #!/bin/sh
 
-test_description='external credential helper tests'
-. ./test-lib.sh
-. "$TEST_DIRECTORY"/lib-credential.sh
+test_description='external credential helper tests
 
-pre_test() {
-       test -z "$GIT_TEST_CREDENTIAL_HELPER_SETUP" ||
-       eval "$GIT_TEST_CREDENTIAL_HELPER_SETUP"
+This is a tool for authors of external helper tools to sanity-check
+their helpers. If you have written the "git-credential-foo" helper,
+you check it with:
+
+  make GIT_TEST_CREDENTIAL_HELPER=foo t0303-credential-external.sh
+
+This assumes that your helper is capable of both storing and
+retrieving credentials (some helpers may be read-only, and they will
+fail these tests).
+
+Please note that the individual tests do not verify all of the
+preconditions themselves, but rather build on each other. A failing
+test means that tests later in the sequence can return false "OK"
+results.
+
+If your helper supports time-based expiration with a configurable
+timeout, you can test that feature with:
+
+  make GIT_TEST_CREDENTIAL_HELPER=foo \
+       GIT_TEST_CREDENTIAL_HELPER_TIMEOUT="foo --timeout=1" \
+       t0303-credential-external.sh
 
-       # clean before the test in case there is cruft left
-       # over from a previous run that would impact results
-       helper_test_clean "$GIT_TEST_CREDENTIAL_HELPER"
-}
+If your helper requires additional setup before the tests are started,
+you can set GIT_TEST_CREDENTIAL_HELPER_SETUP to a sequence of shell
+commands.
+'
 
-post_test() {
-       # clean afterwards so that we are good citizens
-       # and don't leave cruft in the helper's storage, which
-       # might be long-term system storage
-       helper_test_clean "$GIT_TEST_CREDENTIAL_HELPER"
-}
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-credential.sh
 
 if test -z "$GIT_TEST_CREDENTIAL_HELPER"; then
-       say "# skipping external helper tests (set GIT_TEST_CREDENTIAL_HELPER)"
-else
-       pre_test
-       helper_test "$GIT_TEST_CREDENTIAL_HELPER"
-       post_test
+       skip_all="used to test external credential helpers"
+       test_done
 fi
 
+test -z "$GIT_TEST_CREDENTIAL_HELPER_SETUP" ||
+       eval "$GIT_TEST_CREDENTIAL_HELPER_SETUP"
+
+# clean before the test in case there is cruft left
+# over from a previous run that would impact results
+helper_test_clean "$GIT_TEST_CREDENTIAL_HELPER"
+
+helper_test "$GIT_TEST_CREDENTIAL_HELPER"
+
 if test -z "$GIT_TEST_CREDENTIAL_HELPER_TIMEOUT"; then
-       say "# skipping external helper timeout tests"
+       say "# skipping timeout tests (GIT_TEST_CREDENTIAL_HELPER_TIMEOUT not set)"
 else
-       pre_test
        helper_test_timeout "$GIT_TEST_CREDENTIAL_HELPER_TIMEOUT"
-       post_test
 fi
 
+# clean afterwards so that we are good citizens
+# and don't leave cruft in the helper's storage, which
+# might be long-term system storage
+helper_test_clean "$GIT_TEST_CREDENTIAL_HELPER"
+
 test_done
index 29d6024b7f1b55c09cbd7e9ed682a3e745c550d6..4d127f19b78cc76018e316532c905137e9c7ab08 100755 (executable)
@@ -6,11 +6,15 @@ test_description='adding and checking out large blobs'
 . ./test-lib.sh
 
 test_expect_success setup '
-       git config core.bigfilethreshold 200k &&
+       # clone does not allow us to pass core.bigfilethreshold to
+       # new repos, so set core.bigfilethreshold globally
+       git config --global core.bigfilethreshold 200k &&
        echo X | dd of=large1 bs=1k seek=2000 &&
        echo X | dd of=large2 bs=1k seek=2000 &&
        echo X | dd of=large3 bs=1k seek=2000 &&
-       echo Y | dd of=huge bs=1k seek=2500
+       echo Y | dd of=huge bs=1k seek=2500 &&
+       GIT_ALLOC_LIMIT=1500 &&
+       export GIT_ALLOC_LIMIT
 '
 
 test_expect_success 'add a large file or two' '
@@ -100,4 +104,34 @@ test_expect_success 'packsize limit' '
        )
 '
 
+test_expect_success 'diff --raw' '
+       git commit -q -m initial &&
+       echo modified >>large1 &&
+       git add large1 &&
+       git commit -q -m modified &&
+       git diff --raw HEAD^
+'
+
+test_expect_success 'hash-object' '
+       git hash-object large1
+'
+
+test_expect_success 'cat-file a large file' '
+       git cat-file blob :large1 >/dev/null
+'
+
+test_expect_success 'cat-file a large file from a tag' '
+       git tag -m largefile largefiletag :large1 &&
+       git cat-file blob largefiletag >/dev/null
+'
+
+test_expect_success 'git-show a large file' '
+       git show :large1 >/dev/null
+
+'
+
+test_expect_success 'repack' '
+       git repack -ad
+'
+
 test_done
index 9f00ada5f7776b2377993cc9392b89e5312a513f..c53c9f65ebd2824d4a0d528b25d85e1e0b26f4df 100755 (executable)
@@ -15,184 +15,204 @@ p0='no-funny'
 p1='tabs       ," (dq) and spaces'
 p2='just space'
 
-cat >"$p0" <<\EOF
-1. A quick brown fox jumps over the lazy cat, oops dog.
-2. A quick brown fox jumps over the lazy cat, oops dog.
-3. A quick brown fox jumps over the lazy cat, oops dog.
-EOF
-
-cat 2>/dev/null >"$p1" "$p0"
-echo 'Foo Bar Baz' >"$p2"
+test_expect_success 'setup' '
+       cat >"$p0" <<-\EOF &&
+       1. A quick brown fox jumps over the lazy cat, oops dog.
+       2. A quick brown fox jumps over the lazy cat, oops dog.
+       3. A quick brown fox jumps over the lazy cat, oops dog.
+       EOF
+
+       { cat "$p0" >"$p1" || :; } &&
+       { echo "Foo Bar Baz" >"$p2" || :; } &&
+
+       if test -f "$p1" && cmp "$p0" "$p1"
+       then
+               test_set_prereq TABS_IN_FILENAMES
+       fi
+'
 
-if test -f "$p1" && cmp "$p0" "$p1"
+if ! test_have_prereq TABS_IN_FILENAMES
 then
-    test_set_prereq TABS_IN_FILENAMES
-else
        # since FAT/NTFS does not allow tabs in filenames, skip this test
-       say 'Your filesystem does not allow tabs in filenames'
+       skip_all='Your filesystem does not allow tabs in filenames'
+       test_done
 fi
 
-test_expect_success TABS_IN_FILENAMES 'setup expect' "
-echo 'just space
-no-funny' >expected
-"
+test_expect_success 'setup: populate index and tree' '
+       git update-index --add "$p0" "$p2" &&
+       t0=$(git write-tree)
+'
 
-test_expect_success TABS_IN_FILENAMES 'git ls-files no-funny' \
-       'git update-index --add "$p0" "$p2" &&
+test_expect_success 'ls-files prints space in filename verbatim' '
+       printf "%s\n" "just space" no-funny >expected &&
        git ls-files >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-t0=`git write-tree` &&
-echo "$t0" >t0 &&
+       test_cmp expected current
+'
 
-cat > expected <<\EOF
-just space
-no-funny
-"tabs\t,\" (dq) and spaces"
-EOF
+test_expect_success 'setup: add funny filename' '
+       git update-index --add "$p1" &&
+       t1=$(git write-tree)
 '
 
-test_expect_success TABS_IN_FILENAMES 'git ls-files with-funny' \
-       'git update-index --add "$p1" &&
+test_expect_success 'ls-files quotes funny filename' '
+       cat >expected <<-\EOF &&
+       just space
+       no-funny
+       "tabs\t,\" (dq) and spaces"
+       EOF
        git ls-files >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' "
-echo 'just space
-no-funny
-tabs   ,\" (dq) and spaces' >expected
-"
-
-test_expect_success TABS_IN_FILENAMES 'git ls-files -z with-funny' \
-       'git ls-files -z | perl -pe y/\\000/\\012/ >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-t1=`git write-tree` &&
-echo "$t1" >t1 &&
-
-cat > expected <<\EOF
-just space
-no-funny
-"tabs\t,\" (dq) and spaces"
-EOF
-'
-
-test_expect_success TABS_IN_FILENAMES 'git ls-tree with funny' \
-       'git ls-tree -r $t1 | sed -e "s/^[^     ]*      //" >current &&
-        test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-cat > expected <<\EOF
-A      "tabs\t,\" (dq) and spaces"
-EOF
-'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-index with-funny' \
-       'git diff-index --name-status $t0 >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-tree with-funny' \
-       'git diff-tree --name-status $t0 $t1 >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' "
-echo 'A
-tabs   ,\" (dq) and spaces' >expected
-"
-
-test_expect_success TABS_IN_FILENAMES 'git diff-index -z with-funny' \
-       'git diff-index -z --name-status $t0 | perl -pe y/\\000/\\012/ >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-tree -z with-funny' \
-       'git diff-tree -z --name-status $t0 $t1 | perl -pe y/\\000/\\012/ >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-cat > expected <<\EOF
-CNUM   no-funny        "tabs\t,\" (dq) and spaces"
-EOF
-'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-tree -C with-funny' \
-       'git diff-tree -C --find-copies-harder --name-status \
-               $t0 $t1 | sed -e 's/^C[0-9]*/CNUM/' >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-cat > expected <<\EOF
-RNUM   no-funny        "tabs\t,\" (dq) and spaces"
-EOF
-'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny' \
-       'git update-index --force-remove "$p0" &&
-       git diff-index -M --name-status \
-               $t0 | sed -e 's/^R[0-9]*/RNUM/' >current &&
-       test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-cat > expected <<\EOF
-diff --git a/no-funny "b/tabs\t,\" (dq) and spaces"
-similarity index NUM%
-rename from no-funny
-rename to "tabs\t,\" (dq) and spaces"
-EOF
-'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny' \
-       'git diff-index -M -p $t0 |
-        sed -e "s/index [0-9]*%/index NUM%/" >current &&
-        test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-chmod +x "$p1" &&
-cat > expected <<\EOF
-diff --git a/no-funny "b/tabs\t,\" (dq) and spaces"
-old mode 100644
-new mode 100755
-similarity index NUM%
-rename from no-funny
-rename to "tabs\t,\" (dq) and spaces"
-EOF
-'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny' \
-       'git diff-index -M -p $t0 |
-        sed -e "s/index [0-9]*%/index NUM%/" >current &&
-        test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-cat >expected <<\EOF
- "tabs\t,\" (dq) and spaces"
- 1 file changed, 0 insertions(+), 0 deletions(-)
-EOF
-'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-tree rename with-funny applied' \
-       'git diff-index -M -p $t0 |
-        git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current &&
-        test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'setup expect' '
-cat > expected <<\EOF
- no-funny
- "tabs\t,\" (dq) and spaces"
- 2 files changed, 3 insertions(+), 3 deletions(-)
-EOF
-'
-
-test_expect_success TABS_IN_FILENAMES 'git diff-tree delete with-funny applied' \
-       'git diff-index -p $t0 |
-        git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current &&
-        test_cmp expected current'
-
-test_expect_success TABS_IN_FILENAMES 'git apply non-git diff' \
-       'git diff-index -p $t0 |
-        sed -ne "/^[-+@]/p" |
-        git apply --stat | sed -e "s/|.*//" -e "s/ *\$//" >current &&
-        test_cmp expected current'
+       test_cmp expected current
+'
+
+test_expect_success 'ls-files -z does not quote funny filename' '
+       cat >expected <<-\EOF &&
+       just space
+       no-funny
+       tabs    ," (dq) and spaces
+       EOF
+       git ls-files -z >ls-files.z &&
+       perl -pe "y/\000/\012/" <ls-files.z >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'ls-tree quotes funny filename' '
+       cat >expected <<-\EOF &&
+       just space
+       no-funny
+       "tabs\t,\" (dq) and spaces"
+       EOF
+       git ls-tree -r $t1 >ls-tree &&
+       sed -e "s/^[^   ]*      //" <ls-tree >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'diff-index --name-status quotes funny filename' '
+       cat >expected <<-\EOF &&
+       A       "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-index --name-status $t0 >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'diff-tree --name-status quotes funny filename' '
+       cat >expected <<-\EOF &&
+       A       "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-tree --name-status $t0 $t1 >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'diff-index -z does not quote funny filename' '
+       cat >expected <<-\EOF &&
+       A
+       tabs    ," (dq) and spaces
+       EOF
+       git diff-index -z --name-status $t0 >diff-index.z &&
+       perl -pe "y/\000/\012/" <diff-index.z >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'diff-tree -z does not quote funny filename' '
+       cat >expected <<-\EOF &&
+       A
+       tabs    ," (dq) and spaces
+       EOF
+       git diff-tree -z --name-status $t0 $t1 >diff-tree.z &&
+       perl -pe y/\\000/\\012/ <diff-tree.z >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'diff-tree --find-copies-harder quotes funny filename' '
+       cat >expected <<-\EOF &&
+       CNUM    no-funny        "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-tree -C --find-copies-harder --name-status $t0 $t1 >out &&
+       sed -e "s/^C[0-9]*/CNUM/" <out >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'setup: remove unfunny index entry' '
+       git update-index --force-remove "$p0"
+'
+
+test_expect_success 'diff-tree -M quotes funny filename' '
+       cat >expected <<-\EOF &&
+       RNUM    no-funny        "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-index -M --name-status $t0 >out &&
+       sed -e "s/^R[0-9]*/RNUM/" <out >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'diff-index -M -p quotes funny filename' '
+       cat >expected <<-\EOF &&
+       diff --git a/no-funny "b/tabs\t,\" (dq) and spaces"
+       similarity index NUM%
+       rename from no-funny
+       rename to "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-index -M -p $t0 >diff &&
+       sed -e "s/index [0-9]*%/index NUM%/" <diff >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'setup: mode change' '
+       chmod +x "$p1"
+'
+
+test_expect_success 'diff-index -M -p with mode change quotes funny filename' '
+       cat >expected <<-\EOF &&
+       diff --git a/no-funny "b/tabs\t,\" (dq) and spaces"
+       old mode 100644
+       new mode 100755
+       similarity index NUM%
+       rename from no-funny
+       rename to "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-index -M -p $t0 >diff &&
+       sed -e "s/index [0-9]*%/index NUM%/" <diff >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'diffstat for rename quotes funny filename' '
+       cat >expected <<-\EOF &&
+        "tabs\t,\" (dq) and spaces"
+        1 file changed, 0 insertions(+), 0 deletions(-)
+       EOF
+       git diff-index -M -p $t0 >diff &&
+       git apply --stat <diff >diffstat &&
+       sed -e "s/|.*//" -e "s/ *\$//" <diffstat >current &&
+       test_i18ncmp expected current
+'
+
+test_expect_success 'numstat for rename quotes funny filename' '
+       cat >expected <<-\EOF &&
+       0       0       "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-index -M -p $t0 >diff &&
+       git apply --numstat <diff >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'numstat without -M quotes funny filename' '
+       cat >expected <<-\EOF &&
+       0       3       no-funny
+       3       0       "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-index -p $t0 >diff &&
+       git apply --numstat <diff >current &&
+       test_cmp expected current
+'
+
+test_expect_success 'numstat for non-git rename diff quotes funny filename' '
+       cat >expected <<-\EOF &&
+       0       3       no-funny
+       3       0       "tabs\t,\" (dq) and spaces"
+       EOF
+       git diff-index -p $t0 >git-diff &&
+       sed -ne "/^[-+@]/p" <git-diff >diff &&
+       git apply --numstat <diff >current &&
+       test_cmp expected current
+'
 
 test_done
index 436719795376f78e3a32a441e9e7e0a4606ac2f5..195bb97f859d6a4990c292da46b9674be0f6153f 100755 (executable)
@@ -324,7 +324,7 @@ y and z notes on 4th commit
 EOF
        git notes merge --commit &&
        # No .git/NOTES_MERGE_* files left
-       test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
+       test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
        test_cmp /dev/null output &&
        # Merge commit has pre-merge y and pre-merge z as parents
        test "$(git rev-parse refs/notes/m^1)" = "$(cat pre_merge_y)" &&
@@ -386,7 +386,7 @@ test_expect_success 'redo merge of z into m (== y) with default ("manual") resol
 test_expect_success 'abort notes merge' '
        git notes merge --abort &&
        # No .git/NOTES_MERGE_* files left
-       test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
+       test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
        test_cmp /dev/null output &&
        # m has not moved (still == y)
        test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" &&
@@ -453,7 +453,7 @@ EOF
        # Finalize merge
        git notes merge --commit &&
        # No .git/NOTES_MERGE_* files left
-       test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
+       test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
        test_cmp /dev/null output &&
        # Merge commit has pre-merge y and pre-merge z as parents
        test "$(git rev-parse refs/notes/m^1)" = "$(cat pre_merge_y)" &&
@@ -542,7 +542,7 @@ EOF
 test_expect_success 'resolve situation by aborting the notes merge' '
        git notes merge --abort &&
        # No .git/NOTES_MERGE_* files left
-       test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
+       test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null &&
        test_cmp /dev/null output &&
        # m has not moved (still == w)
        test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" &&
@@ -553,4 +553,23 @@ test_expect_success 'resolve situation by aborting the notes merge' '
        verify_notes z
 '
 
+cat >expect_notes <<EOF
+foo
+bar
+EOF
+
+test_expect_success 'switch cwd before committing notes merge' '
+       git notes add -m foo HEAD &&
+       git notes --ref=other add -m bar HEAD &&
+       test_must_fail git notes merge refs/notes/other &&
+       (
+               cd .git/NOTES_MERGE_WORKTREE &&
+               echo "foo" > $(git rev-parse HEAD) &&
+               echo "bar" >> $(git rev-parse HEAD) &&
+               git notes merge --commit
+       ) &&
+       git notes show HEAD > actual_notes &&
+       test_cmp expect_notes actual_notes
+'
+
 test_done
index 1b3a344158aa8077c1e5b47f9ab8bd6394e153ed..75f7ff4f2fe21e86e0a26fe5a6c2119bef38404c 100755 (executable)
@@ -35,6 +35,16 @@ test_expect_success setup '
 '
 
 test_expect_success 'cherry-pick first..fourth works' '
+       git checkout -f master &&
+       git reset --hard first &&
+       test_tick &&
+       git cherry-pick first..fourth &&
+       git diff --quiet other &&
+       git diff --quiet HEAD other &&
+       check_head_differs_from fourth
+'
+
+test_expect_success 'output to keep user entertained during multi-pick' '
        cat <<-\EOF >expected &&
        [master OBJID] second
         Author: A U Thor <author@example.com>
@@ -51,15 +61,22 @@ test_expect_success 'cherry-pick first..fourth works' '
        git reset --hard first &&
        test_tick &&
        git cherry-pick first..fourth >actual &&
+       sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy &&
+       test_line_count -ge 3 actual.fuzzy &&
+       test_i18ncmp expected actual.fuzzy
+'
+
+test_expect_success 'cherry-pick --strategy resolve first..fourth works' '
+       git checkout -f master &&
+       git reset --hard first &&
+       test_tick &&
+       git cherry-pick --strategy resolve first..fourth &&
        git diff --quiet other &&
        git diff --quiet HEAD other &&
-
-       sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy &&
-       test_cmp expected actual.fuzzy &&
        check_head_differs_from fourth
 '
 
-test_expect_success 'cherry-pick --strategy resolve first..fourth works' '
+test_expect_success 'output during multi-pick indicates merge strategy' '
        cat <<-\EOF >expected &&
        Trying simple merge.
        [master OBJID] second
@@ -79,11 +96,8 @@ test_expect_success 'cherry-pick --strategy resolve first..fourth works' '
        git reset --hard first &&
        test_tick &&
        git cherry-pick --strategy resolve first..fourth >actual &&
-       git diff --quiet other &&
-       git diff --quiet HEAD other &&
        sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy &&
-       test_cmp expected actual.fuzzy &&
-       check_head_differs_from fourth
+       test_i18ncmp expected actual.fuzzy
 '
 
 test_expect_success 'cherry-pick --ff first..fourth works' '
index 663c60a12e82c96065e60fd448a6583c91e5a2cd..3addb804d56fe2f0bcbf2d78bddd541880098c8d 100755 (executable)
@@ -432,7 +432,7 @@ test_expect_success 'stash branch - stashes on stack, stash-like argument' '
        test $(git ls-files --modified | wc -l) -eq 1
 '
 
-test_expect_success 'stash show - stashes on stack, stash-like argument' '
+test_expect_success 'stash show format defaults to --stat' '
        git stash clear &&
        test_when_finished "git reset --hard HEAD" &&
        git reset --hard &&
@@ -447,6 +447,21 @@ test_expect_success 'stash show - stashes on stack, stash-like argument' '
         1 file changed, 1 insertion(+)
        EOF
        git stash show ${STASH_ID} >actual &&
+       test_i18ncmp expected actual
+'
+
+test_expect_success 'stash show - stashes on stack, stash-like argument' '
+       git stash clear &&
+       test_when_finished "git reset --hard HEAD" &&
+       git reset --hard &&
+       echo foo >> file &&
+       git stash &&
+       test_when_finished "git stash drop" &&
+       echo bar >> file &&
+       STASH_ID=$(git stash create) &&
+       git reset --hard &&
+       echo "1 0       file" >expected &&
+       git stash show --numstat ${STASH_ID} >actual &&
        test_cmp expected actual
 '
 
@@ -480,11 +495,8 @@ test_expect_success 'stash show - no stashes on stack, stash-like argument' '
        echo foo >> file &&
        STASH_ID=$(git stash create) &&
        git reset --hard &&
-       cat >expected <<-EOF &&
-        file |    1 +
-        1 file changed, 1 insertion(+)
-       EOF
-       git stash show ${STASH_ID} >actual &&
+       echo "1 0       file" >expected &&
+       git stash show --numstat ${STASH_ID} >actual &&
        test_cmp expected actual
 '
 
index 2d9f9a0cf1555cab24af19f264d495e134c27352..ed24ddd88a828408f4edca008b559a70f5749769 100755 (executable)
@@ -8,6 +8,13 @@ test_description='Binary diff and apply
 
 . ./test-lib.sh
 
+cat >expect.binary-numstat <<\EOF
+1      1       a
+-      -       b
+1      1       c
+-      -       d
+EOF
+
 test_expect_success 'prepare repository' \
        'echo AIT >a && echo BIT >b && echo CIT >c && echo DIT >d &&
         git update-index --add a b c d &&
@@ -23,13 +30,23 @@ cat > expected <<\EOF
  d |  Bin
  4 files changed, 2 insertions(+), 2 deletions(-)
 EOF
-test_expect_success 'diff without --binary' \
-       'git diff | git apply --stat --summary >current &&
-        test_cmp expected current'
+test_expect_success '"apply --stat" output for binary file change' '
+       git diff >diff &&
+       git apply --stat --summary <diff >current &&
+       test_i18ncmp expected current
+'
 
-test_expect_success 'diff with --binary' \
-       'git diff --binary | git apply --stat --summary >current &&
-        test_cmp expected current'
+test_expect_success 'apply --numstat notices binary file change' '
+       git diff >diff &&
+       git apply --numstat <diff >current &&
+       test_cmp expect.binary-numstat current
+'
+
+test_expect_success 'apply --numstat understands diff --binary format' '
+       git diff --binary >diff &&
+       git apply --numstat <diff >current &&
+       test_cmp expect.binary-numstat current
+'
 
 # apply needs to be able to skip the binary material correctly
 # in order to report the line number of a corrupt patch.
index 93a6f208710befc064b7b99bcd758bb8b6381918..e77c09c37eede2f039610199ba8e3c45e94213d4 100755 (executable)
@@ -128,7 +128,12 @@ do
                } >"$actual" &&
                if test -f "$expect"
                then
-                       test_cmp "$expect" "$actual" &&
+                       case $cmd in
+                       *format-patch* | *-stat*)
+                               test_i18ncmp "$expect" "$actual";;
+                       *)
+                               test_cmp "$expect" "$actual";;
+                       esac &&
                        rm -f "$actual"
                else
                        # this is to help developing new tests.
index 7dfe716cf9ed63f08f512cfa123d9bf93fa92839..b473b6d6ebbf75f77be99085c26b68781b7f5fc6 100755 (executable)
@@ -518,11 +518,6 @@ test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 '
 
 cat > expect << EOF
----
- file |   16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
-diff --git a/file b/file
 index 40f36c6..2dc5c23 100644
 --- a/file
 +++ b/file
@@ -537,7 +532,9 @@ EOF
 test_expect_success 'format-patch respects -U' '
 
        git format-patch -U4 -2 &&
-       sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output &&
+       sed -e "1,/^diff/d" -e "/^+5/q" \
+               <0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
+               >output &&
        test_cmp expect output
 
 '
index ab0c2f0574f915296b885a21c6151a6947bdae7e..3ec71184bac00c956b48ddc3f6c51a37cabcbbf2 100755 (executable)
@@ -57,22 +57,33 @@ test_expect_success TABS_IN_FILENAMES 'git diff --summary -M HEAD' '
        test_cmp expect actual
 '
 
-test_expect_success TABS_IN_FILENAMES 'setup expected files' '
-cat >expect <<\EOF
- pathname.1 => "Rpathname\twith HT.0"            |    0
- pathname.3 => "Rpathname\nwith LF.0"            |    0
- "pathname\twith HT.3" => "Rpathname\nwith LF.1" |    0
- pathname.2 => Rpathname with SP.0               |    0
- "pathname\twith HT.2" => Rpathname with SP.1    |    0
- pathname.0 => Rpathname.0                       |    0
- "pathname\twith HT.0" => Rpathname.1            |    0
- 7 files changed, 0 insertions(+), 0 deletions(-)
-EOF
+test_expect_success TABS_IN_FILENAMES 'git diff --numstat -M HEAD' '
+       cat >expect <<-\EOF &&
+       0       0       pathname.1 => "Rpathname\twith HT.0"
+       0       0       pathname.3 => "Rpathname\nwith LF.0"
+       0       0       "pathname\twith HT.3" => "Rpathname\nwith LF.1"
+       0       0       pathname.2 => Rpathname with SP.0
+       0       0       "pathname\twith HT.2" => Rpathname with SP.1
+       0       0       pathname.0 => Rpathname.0
+       0       0       "pathname\twith HT.0" => Rpathname.1
+       EOF
+       git diff --numstat -M HEAD >actual &&
+       test_cmp expect actual
 '
 
 test_expect_success TABS_IN_FILENAMES 'git diff --stat -M HEAD' '
+       cat >expect <<-\EOF &&
+        pathname.1 => "Rpathname\twith HT.0"            |    0
+        pathname.3 => "Rpathname\nwith LF.0"            |    0
+        "pathname\twith HT.3" => "Rpathname\nwith LF.1" |    0
+        pathname.2 => Rpathname with SP.0               |    0
+        "pathname\twith HT.2" => Rpathname with SP.1    |    0
+        pathname.0 => Rpathname.0                       |    0
+        "pathname\twith HT.0" => Rpathname.1            |    0
+        7 files changed, 0 insertions(+), 0 deletions(-)
+       EOF
        git diff --stat -M HEAD >actual &&
-       test_cmp expect actual
+       test_i18ncmp expect actual
 '
 
 test_done
index 4ac162cfcf891e5fe0a36a3074db0d486ffa5cf0..06b05df848cded95827d2d8a2b410850fef4f5eb 100755 (executable)
@@ -91,7 +91,11 @@ EOF
 test_expect_success 'diffstat does not run textconv' '
        echo file diff=fail >.gitattributes &&
        git diff --stat HEAD^ HEAD >actual &&
-       test_cmp expect.stat actual
+       test_i18ncmp expect.stat actual &&
+
+       head -n1 <expect.stat >expect.line1 &&
+       head -n1 <actual >actual.line1 &&
+       test_cmp expect.line1 actual.line1
 '
 # restore working setup
 echo file diff=foo >.gitattributes
index 7d7470f21b66a937e7414f4fe5419f8830fd8e86..c8296fa4fc1fbfe2645554d4818ae586d1cc2a14 100755 (executable)
@@ -44,10 +44,16 @@ test_expect_success 'rewrite diff can show binary patch' '
        grep "GIT binary patch" diff
 '
 
-test_expect_success 'rewrite diff --stat shows binary changes' '
+test_expect_success 'rewrite diff --numstat shows binary changes' '
+       git diff -B --numstat --summary >diff &&
+       grep -e "-      -       " diff &&
+       grep " rewrite file" diff
+'
+
+test_expect_success 'diff --stat counts binary rewrite as 0 lines' '
        git diff -B --stat --summary >diff &&
        grep "Bin" diff &&
-       grep "0 insertions.*0 deletions" diff &&
+       test_i18ngrep "0 insertions.*0 deletions" diff &&
        grep " rewrite file" diff
 '
 
index 5c2012111c28d338ad979fb7bcca871e744184fe..30d42cb3bfd856a7d920119f1c4226c408a8f82f 100755 (executable)
@@ -3,6 +3,7 @@
 test_description='word diff colors'
 
 . ./test-lib.sh
+. "$TEST_DIRECTORY"/diff-lib.sh
 
 cat >pre.simple <<-\EOF
        h(4)
@@ -293,6 +294,10 @@ test_expect_success '--word-diff=none' '
        word_diff --word-diff=plain --word-diff=none
 '
 
+test_expect_success 'unset default driver' '
+       test_unconfig diff.wordregex
+'
+
 test_language_driver bibtex
 test_language_driver cpp
 test_language_driver csharp
@@ -348,4 +353,35 @@ test_expect_success 'word-diff with no newline at EOF' '
        word_diff --word-diff=plain
 '
 
+test_expect_success 'setup history with two files' '
+       echo "a b; c" >a.tex &&
+       echo "a b; c" >z.txt &&
+       git add a.tex z.txt &&
+       git commit -minitial &&
+
+       # modify both
+       echo "a bx; c" >a.tex &&
+       echo "a bx; c" >z.txt &&
+       git commit -mmodified -a
+'
+
+test_expect_success 'wordRegex for the first file does not apply to the second' '
+       echo "*.tex diff=tex" >.gitattributes &&
+       git config diff.tex.wordRegex "[a-z]+|." &&
+       cat >expect <<-\EOF &&
+               diff --git a/a.tex b/a.tex
+               --- a/a.tex
+               +++ b/a.tex
+               @@ -1 +1 @@
+               a [-b-]{+bx+}; c
+               diff --git a/z.txt b/z.txt
+               --- a/z.txt
+               +++ b/z.txt
+               @@ -1 +1 @@
+               a [-b;-]{+bx;+} c
+       EOF
+       git diff --word-diff HEAD~ >actual &&
+       compare_diff_patch expect actual
+'
+
 test_done
index 06012811a1abf2e7d9c766e84b32dae8a95a7321..2a2cf91352037b6f2c238237474aa1d78928f5ad 100755 (executable)
@@ -23,9 +23,8 @@ test_expect_success 'move the files into a "sub" directory' '
 '
 
 cat > expected <<\EOF
- bar => sub/bar |  Bin 5 -> 5 bytes
- foo => sub/foo |    0
- 2 files changed, 0 insertions(+), 0 deletions(-)
+-      -       bar => sub/bar
+0      0       foo => sub/foo
 
 diff --git a/bar b/sub/bar
 similarity index 100%
@@ -38,7 +37,8 @@ rename to sub/foo
 EOF
 
 test_expect_success 'git show -C -C report renames' '
-       git show -C -C --raw --binary --stat | tail -n 12 > current &&
+       git show -C -C --raw --binary --numstat >patch-with-stat &&
+       tail -n 11 patch-with-stat >current &&
        test_cmp expected current
 '
 
index bd119be106f1a2d6d91f982a1bf8afcbf6b8c831..18fadcf06eac8054574fed153058776a447897ac 100755 (executable)
@@ -29,6 +29,18 @@ test_expect_success "-p $*" "
 "
 }
 
+check_numstat() {
+expect=$1; shift
+cat >expected <<EOF
+1      0       $expect
+EOF
+test_expect_success "--numstat $*" "
+       echo '1 0       $expect' >expected &&
+       git diff --numstat $* HEAD^ >actual &&
+       test_cmp expected actual
+"
+}
+
 check_stat() {
 expect=$1; shift
 cat >expected <<EOF
@@ -37,7 +49,7 @@ cat >expected <<EOF
 EOF
 test_expect_success "--stat $*" "
        git diff --stat $* HEAD^ >actual &&
-       test_cmp expected actual
+       test_i18ncmp expected actual
 "
 }
 
@@ -52,7 +64,7 @@ test_expect_success "--raw $*" "
 "
 }
 
-for type in diff stat raw; do
+for type in diff numstat stat raw; do
        check_$type file2 --relative=subdir/
        check_$type file2 --relative=subdir
        check_$type dir/file2 --relative=sub
index 29e80a58cdcf43077bcc5bf42834aa8b4daad93d..ed7e093366bcbdaa177bac4294a07fc52d4233ed 100755 (executable)
@@ -252,50 +252,47 @@ EOF
 '
 
 cat <<EOF >expect_diff_stat
- changed/text             |    2 +-
- dst/copy/changed/text    |   10 ++++++++++
- dst/copy/rearranged/text |   10 ++++++++++
- dst/copy/unchanged/text  |   10 ++++++++++
- dst/move/changed/text    |   10 ++++++++++
- dst/move/rearranged/text |   10 ++++++++++
- dst/move/unchanged/text  |   10 ++++++++++
- rearranged/text          |    2 +-
- src/move/changed/text    |   10 ----------
- src/move/rearranged/text |   10 ----------
- src/move/unchanged/text  |   10 ----------
- 11 files changed, 62 insertions(+), 32 deletions(-)
+1      1       changed/text
+10     0       dst/copy/changed/text
+10     0       dst/copy/rearranged/text
+10     0       dst/copy/unchanged/text
+10     0       dst/move/changed/text
+10     0       dst/move/rearranged/text
+10     0       dst/move/unchanged/text
+1      1       rearranged/text
+0      10      src/move/changed/text
+0      10      src/move/rearranged/text
+0      10      src/move/unchanged/text
 EOF
 
 cat <<EOF >expect_diff_stat_M
- changed/text                      |    2 +-
- dst/copy/changed/text             |   10 ++++++++++
- dst/copy/rearranged/text          |   10 ++++++++++
- dst/copy/unchanged/text           |   10 ++++++++++
- {src => dst}/move/changed/text    |    2 +-
- {src => dst}/move/rearranged/text |    2 +-
- {src => dst}/move/unchanged/text  |    0
- rearranged/text                   |    2 +-
- 8 files changed, 34 insertions(+), 4 deletions(-)
+1      1       changed/text
+10     0       dst/copy/changed/text
+10     0       dst/copy/rearranged/text
+10     0       dst/copy/unchanged/text
+1      1       {src => dst}/move/changed/text
+1      1       {src => dst}/move/rearranged/text
+0      0       {src => dst}/move/unchanged/text
+1      1       rearranged/text
 EOF
 
 cat <<EOF >expect_diff_stat_CC
- changed/text                      |    2 +-
- {src => dst}/copy/changed/text    |    2 +-
- {src => dst}/copy/rearranged/text |    2 +-
- {src => dst}/copy/unchanged/text  |    0
- {src => dst}/move/changed/text    |    2 +-
- {src => dst}/move/rearranged/text |    2 +-
- {src => dst}/move/unchanged/text  |    0
- rearranged/text                   |    2 +-
- 8 files changed, 6 insertions(+), 6 deletions(-)
-EOF
-
-test_expect_success 'sanity check setup (--stat)' '
-       git diff --stat HEAD^..HEAD >actual_diff_stat &&
+1      1       changed/text
+1      1       {src => dst}/copy/changed/text
+1      1       {src => dst}/copy/rearranged/text
+0      0       {src => dst}/copy/unchanged/text
+1      1       {src => dst}/move/changed/text
+1      1       {src => dst}/move/rearranged/text
+0      0       {src => dst}/move/unchanged/text
+1      1       rearranged/text
+EOF
+
+test_expect_success 'sanity check setup (--numstat)' '
+       git diff --numstat HEAD^..HEAD >actual_diff_stat &&
        test_cmp expect_diff_stat actual_diff_stat &&
-       git diff --stat -M HEAD^..HEAD >actual_diff_stat_M &&
+       git diff --numstat -M HEAD^..HEAD >actual_diff_stat_M &&
        test_cmp expect_diff_stat_M actual_diff_stat_M &&
-       git diff --stat -C -C HEAD^..HEAD >actual_diff_stat_CC &&
+       git diff --numstat -C -C HEAD^..HEAD >actual_diff_stat_CC &&
        test_cmp expect_diff_stat_CC actual_diff_stat_CC
 '
 
index a6d1887536e240e89b8e2263e5f0a643e9a55f71..591ffbc07539e6d45d4d0e8cc4d7c015f0952a3a 100755 (executable)
@@ -19,7 +19,7 @@ test_expect_success setup '
         2 files changed, 2 insertions(+)
        EOF
        git diff --stat --stat-count=2 >actual &&
-       test_cmp expect actual
+       test_i18ncmp expect actual
 '
 
 test_done
index 9b433de83630774206fb89dfae1a4396264390cc..744b8e51beab59c78807e0622f10bf421b3142ec 100755 (executable)
@@ -17,13 +17,13 @@ do
        test_expect_success "$title" '
                git apply --stat --summary \
                        <"$TEST_DIRECTORY/t4100/t-apply-$num.patch" >current &&
-               test_cmp "$TEST_DIRECTORY"/t4100/t-apply-$num.expect current
+               test_i18ncmp "$TEST_DIRECTORY"/t4100/t-apply-$num.expect current
        '
 
        test_expect_success "$title with recount" '
                sed -e "$UNC" <"$TEST_DIRECTORY/t4100/t-apply-$num.patch" |
                git apply --recount --stat --summary >current &&
-               test_cmp "$TEST_DIRECTORY"/t4100/t-apply-$num.expect current
+               test_i18ncmp "$TEST_DIRECTORY"/t4100/t-apply-$num.expect current
        '
 done <<\EOF
 rename
index 2af8947eebb3e9ee45f83acb398335ec163a521c..432f98c357601057cb89f9dd6bfbe1ab02e9477a 100755 (executable)
@@ -216,7 +216,7 @@ test_expect_success 'pull request format' '
                git request-pull initial "$downstream_url" >../request
        ) &&
        <request sed -nf fuzz.sed >request.fuzzy &&
-       test_cmp expect request.fuzzy
+       test_i18ncmp expect request.fuzzy
 
 '
 
index ee7f0cd4596f982f16cbf3859675e6faba424faa..984889b39d3f8e9941a2aadc8cec833fe42176a2 100755 (executable)
@@ -118,4 +118,22 @@ test_expect_success 'with failing hook requiring GIT_PREFIX' '
        git checkout -- file
 '
 
+test_expect_success 'check the author in hook' '
+       write_script "$HOOK" <<-\EOF &&
+       test "$GIT_AUTHOR_NAME" = "New Author" &&
+       test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
+       EOF
+       test_must_fail git commit --allow-empty -m "by a.u.thor" &&
+       (
+               GIT_AUTHOR_NAME="New Author" &&
+               GIT_AUTHOR_EMAIL="newauthor@example.com" &&
+               export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
+               git commit --allow-empty -m "by new.author via env" &&
+               git show -s
+       ) &&
+       git commit --author="New Author <newauthor@example.com>" \
+               --allow-empty -m "by new.author via command line" &&
+       git show -s
+'
+
 test_done
index 5783ebf3ab042d3c78633a89d842c432c96a0d4d..bce0bd37cb6006f29b9c8c532863947c44509486 100755 (executable)
@@ -66,7 +66,7 @@ EOF
 test_expect_success 'merge output uses pretty names' '
        git reset --hard c1 &&
        git merge c2 c3 c4 >actual &&
-       test_cmp actual expected
+       test_i18ncmp expected actual
 '
 
 cat >expected <<\EOF
@@ -80,7 +80,7 @@ EOF
 
 test_expect_success 'merge up-to-date output uses pretty names' '
        git merge c4 c5 >actual &&
-       test_cmp actual expected
+       test_i18ncmp expected actual
 '
 
 cat >expected <<\EOF
@@ -97,7 +97,7 @@ EOF
 test_expect_success 'merge fast-forward output uses pretty names' '
        git reset --hard c0 &&
        git merge c1 c2 >actual &&
-       test_cmp actual expected
+       test_i18ncmp expected actual
 '
 
 test_done
index aa74184c31cd6b2bd2e0e566e6805e60eed7aff8..6547eb8f5459d4d95113469d338e1879f86b79ea 100755 (executable)
@@ -92,6 +92,15 @@ test_expect_success 'will not overwrite removed file with staged changes' '
        test_cmp important c1.c
 '
 
+test_expect_failure 'will not overwrite unstaged changes in renamed file' '
+       git reset --hard c1 &&
+       git mv c1.c other.c &&
+       git commit -m rename &&
+       cp important other.c &&
+       git merge c1a &&
+       test_cmp important other.c
+'
+
 test_expect_success 'will not overwrite untracked subtree' '
        git reset --hard c0 &&
        rm -rf sub &&
index 30ed4d74bb2851c1b76f343160a0e34758d580f5..b7d7100c4e5c060c1956e5d4f372fa1fa6ee8c85 100644 (file)
@@ -46,7 +46,7 @@ EDITOR=:
 # /usr/xpg4/bin/sh and /bin/ksh to bail out.  So keep the unsets
 # deriving from the command substitution clustered with the other
 # ones.
-unset VISUAL EMAIL LANGUAGE $(perl -e '
+unset VISUAL EMAIL LANGUAGE COLUMNS $(perl -e '
        my @env = keys %ENV;
        my $ok = join("|", qw(
                TRACE
index 8926bc52a9a6e2a16924664372a8af3ee2ed3136..f2d4c0d22bd418836eb47424a03d0e903246d92e 100644 (file)
@@ -1,7 +1,7 @@
 #include "cache.h"
 #include "run-command.h"
 
-int main(int argc, char **argv)
+int main(int argc, const char **argv)
 {
        struct child_process cp;
        int nogit = 0;
@@ -9,12 +9,12 @@ int main(int argc, char **argv)
        setup_git_directory_gently(&nogit);
        if (nogit)
                die("No git repo found");
-       if (!strcmp(argv[1], "--setup-work-tree")) {
+       if (argc > 1 && !strcmp(argv[1], "--setup-work-tree")) {
                setup_work_tree();
                argv++;
        }
        memset(&cp, 0, sizeof(cp));
        cp.git_cmd = 1;
-       cp.argv = (const char **)argv+1;
+       cp.argv = argv + 1;
        return run_command(&cp);
 }
index 181f8f24d14e91c106b1d36133292a7ee99333fb..ea9dcb6612d92c123c66c2eee03bc933ccb2b13a 100644 (file)
@@ -1154,7 +1154,7 @@ int transport_disconnect(struct transport *transport)
 }
 
 /*
- * Strip username (and password) from an url and return
+ * Strip username (and password) from a URL and return
  * it in a newly allocated string.
  */
 char *transport_anonymize_url(const char *url)
index 85f09df747637b94e0488ad65984c3f97c732034..6ccd0595f43d0ef62bd60a5863804f9a842a4235 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -9,6 +9,18 @@ static void do_nothing(size_t size)
 
 static void (*try_to_free_routine)(size_t size) = do_nothing;
 
+static void memory_limit_check(size_t size)
+{
+       static int limit = -1;
+       if (limit == -1) {
+               const char *env = getenv("GIT_ALLOC_LIMIT");
+               limit = env ? atoi(env) * 1024 : 0;
+       }
+       if (limit && size > limit)
+               die("attempting to allocate %"PRIuMAX" over limit %d",
+                   (intmax_t)size, limit);
+}
+
 try_to_free_t set_try_to_free_routine(try_to_free_t routine)
 {
        try_to_free_t old = try_to_free_routine;
@@ -32,7 +44,10 @@ char *xstrdup(const char *str)
 
 void *xmalloc(size_t size)
 {
-       void *ret = malloc(size);
+       void *ret;
+
+       memory_limit_check(size);
+       ret = malloc(size);
        if (!ret && !size)
                ret = malloc(1);
        if (!ret) {
@@ -79,7 +94,10 @@ char *xstrndup(const char *str, size_t len)
 
 void *xrealloc(void *ptr, size_t size)
 {
-       void *ret = realloc(ptr, size);
+       void *ret;
+
+       memory_limit_check(size);
+       ret = realloc(ptr, size);
        if (!ret && !size)
                ret = realloc(ptr, 1);
        if (!ret) {
@@ -95,7 +113,10 @@ void *xrealloc(void *ptr, size_t size)
 
 void *xcalloc(size_t nmemb, size_t size)
 {
-       void *ret = calloc(nmemb, size);
+       void *ret;
+
+       memory_limit_check(size * nmemb);
+       ret = calloc(nmemb, size);
        if (!ret && (!nmemb || !size))
                ret = calloc(1, 1);
        if (!ret) {
index 00d36c3ac7a7642831d2ffc49647caf77a4d066c..09215afe6e0250fd29897390f074234a7b89f4d8 100644 (file)
@@ -32,14 +32,12 @@ extern "C" {
 #define XDF_IGNORE_WHITESPACE (1 << 2)
 #define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
 #define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4)
-#define XDF_PATIENCE_DIFF (1 << 5)
-#define XDF_HISTOGRAM_DIFF (1 << 6)
 #define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
 
-#define XDL_PATCH_NORMAL '-'
-#define XDL_PATCH_REVERSE '+'
-#define XDL_PATCH_MODEMASK ((1 << 8) - 1)
-#define XDL_PATCH_IGNOREBSPACE (1 << 8)
+#define XDF_PATIENCE_DIFF (1 << 5)
+#define XDF_HISTOGRAM_DIFF (1 << 6)
+#define XDF_DIFF_ALGORITHM_MASK (XDF_PATIENCE_DIFF | XDF_HISTOGRAM_DIFF)
+#define XDF_DIFF_ALG(x) ((x) & XDF_DIFF_ALGORITHM_MASK)
 
 #define XDL_EMIT_FUNCNAMES (1 << 0)
 #define XDL_EMIT_COMMON (1 << 1)
index 75a39227501715504cdd12ccc1b4854568a54ad7..bc889e87894fbd261db8aaf29723e8df35f913da 100644 (file)
@@ -328,10 +328,10 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
        xdalgoenv_t xenv;
        diffdata_t dd1, dd2;
 
-       if (xpp->flags & XDF_PATIENCE_DIFF)
+       if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
                return xdl_do_patience_diff(mf1, mf2, xpp, xe);
 
-       if (xpp->flags & XDF_HISTOGRAM_DIFF)
+       if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
                return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
 
        if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
index 18f6f997c321b5ac1f4d4211a4d448dc8542c22f..bf99787c3e4c791426311495dda9d4da81cbb571 100644 (file)
@@ -252,7 +252,7 @@ static int fall_back_to_classic_diff(struct histindex *index,
                int line1, int count1, int line2, int count2)
 {
        xpparam_t xpp;
-       xpp.flags = index->xpp->flags & ~XDF_HISTOGRAM_DIFF;
+       xpp.flags = index->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
 
        return xdl_fall_back_diff(index->env, &xpp,
                                  line1, count1, line2, count2);
index fdd7d0263f576a8dc1a8e791ef50f8dbe25c7ee5..04e1a1ab2a863814df3b9a91d4e854704d47f3f5 100644 (file)
@@ -288,7 +288,7 @@ static int fall_back_to_classic_diff(struct hashmap *map,
                int line1, int count1, int line2, int count2)
 {
        xpparam_t xpp;
-       xpp.flags = map->xpp->flags & ~XDF_PATIENCE_DIFF;
+       xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
 
        return xdl_fall_back_diff(map->env, &xpp,
                                  line1, count1, line2, count2);
index e419f4f726019a5b0365c589285439fb3bfb8db2..63a22c630e521969b08c8ecb1ce9fa3e0f3ff513 100644 (file)
@@ -181,7 +181,7 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
        if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
                goto abort;
 
-       if (xpp->flags & XDF_HISTOGRAM_DIFF)
+       if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
                hbits = hsize = 0;
        else {
                hbits = xdl_hashbits((unsigned int) narec);
@@ -209,8 +209,8 @@ static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_
                        crec->ha = hav;
                        recs[nrec++] = crec;
 
-                       if (!(xpp->flags & XDF_HISTOGRAM_DIFF) &&
-                               xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
+                       if ((XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+                           xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
                                goto abort;
                }
        }
@@ -273,16 +273,15 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
         * (nrecs) will be updated correctly anyway by
         * xdl_prepare_ctx().
         */
-       sample = xpp->flags & XDF_HISTOGRAM_DIFF ? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1;
+       sample = (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF
+                 ? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1);
 
        enl1 = xdl_guess_lines(mf1, sample) + 1;
        enl2 = xdl_guess_lines(mf2, sample) + 1;
 
-       if (!(xpp->flags & XDF_HISTOGRAM_DIFF) &&
-               xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0) {
-
+       if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF &&
+           xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0)
                return -1;
-       }
 
        if (xdl_prepare_ctx(1, mf1, enl1, xpp, &cf, &xe->xdf1) < 0) {
 
@@ -296,9 +295,9 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
                return -1;
        }
 
-       if (!(xpp->flags & XDF_PATIENCE_DIFF) &&
-                       !(xpp->flags & XDF_HISTOGRAM_DIFF) &&
-                       xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
+       if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
+           (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+           xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
 
                xdl_free_ctx(&xe->xdf2);
                xdl_free_ctx(&xe->xdf1);