Merge branch 'jc/test-prereq'
authorJunio C Hamano <gitster@pobox.com>
Wed, 22 Aug 2012 18:51:26 +0000 (11:51 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 22 Aug 2012 18:51:27 +0000 (11:51 -0700)
Teaches the test framework to probe rarely used prerequistes lazily,
and make use of it for detecting SYMLINKS, CASE_INSENSITIVE_FS and
NKD/NKC MacOS x gotcha.

* jc/test-prereq:
t3910: use the UTF8_NFD_TO_NFC test prereq
test-lib: provide UTF8 behaviour as a prerequisite
t0050: use the SYMLINKS test prereq
t0050: use the CASE_INSENSITIVE_FS test prereq
test-lib: provide case insensitivity as a prerequisite
test: allow prerequisite to be evaluated lazily
test: rename $satisfied to $satisfied_prereq

57 files changed:
Documentation/RelNotes/1.7.11.4.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.11.5.txt [new file with mode: 0644]
Documentation/RelNotes/1.7.12.txt
Documentation/git-credential.txt
Documentation/git.txt
GIT-VERSION-GEN
Makefile
builtin/checkout.c
command-list.txt
compat/terminal.c
contrib/mw-to-git/git-remote-mediawiki
diff.c
git-am.sh
git-rebase.sh
git-submodule.sh
git-svn.perl
help.c
merge-recursive.c
perl/.gitignore
perl/Git/IndexInfo.pm [new file with mode: 0644]
perl/Git/SVN.pm [new file with mode: 0644]
perl/Git/SVN/Fetcher.pm
perl/Git/SVN/GlobSpec.pm [new file with mode: 0644]
perl/Git/SVN/Log.pm [new file with mode: 0644]
perl/Git/SVN/Migration.pm [new file with mode: 0644]
perl/Git/SVN/Ra.pm
perl/Git/SVN/Utils.pm [new file with mode: 0644]
perl/Makefile
perl/Makefile.PL
po/de.po
po/git.pot
po/sv.po
po/vi.po
po/zh_CN.po
sha1_file.c
t/Git-SVN/00compile.t [new file with mode: 0644]
t/Git-SVN/Utils/add_path_to_url.t [new file with mode: 0644]
t/Git-SVN/Utils/can_compress.t [new file with mode: 0644]
t/Git-SVN/Utils/canonicalize_url.t [new file with mode: 0644]
t/Git-SVN/Utils/collapse_dotdot.t [new file with mode: 0644]
t/Git-SVN/Utils/fatal.t [new file with mode: 0644]
t/Git-SVN/Utils/join_paths.t [new file with mode: 0644]
t/t0201-gettext-fallbacks.sh
t/t1100-commit-tree-options.sh
t/t3400-rebase.sh
t/t3404-rebase-interactive.sh
t/t3406-rebase-message.sh
t/t6022-merge-rename.sh
t/t6042-merge-rename-corner-cases.sh
t/t7409-submodule-detached-worktree.sh [new file with mode: 0755]
t/t7502-commit.sh
t/t7810-grep.sh
t/t9107-git-svn-migrate.sh
t/t9118-git-svn-funky-branch-names.sh
t/t9163-git-svn-reset-clears-caches.sh [new file with mode: 0755]
t/t9164-git-svn-dcommit-concrrent.sh [new file with mode: 0755]
transport-helper.c
diff --git a/Documentation/RelNotes/1.7.11.4.txt b/Documentation/RelNotes/1.7.11.4.txt
new file mode 100644 (file)
index 0000000..3a640c2
--- /dev/null
@@ -0,0 +1,31 @@
+Git v1.7.11.4 Release Notes
+===========================
+
+Fixes since v1.7.11.3
+---------------------
+
+ * "$GIT_DIR/COMMIT_EDITMSG" file that is used to hold the commit log
+   message user edits was not documented.
+
+ * The advise() function did not use varargs correctly to format
+   its message.
+
+ * When "git am" failed, old timers knew to check .git/rebase-apply/patch
+   to see what went wrong, but we never told the users about it.
+
+ * "git commit-tree" learned a more natural "-p <parent> <tree>" order
+   of arguments long time ago, but recently forgot it by mistake.
+
+ * "git diff --no-ext-diff" did not output anything for a typechange
+   filepair when GIT_EXTERNAL_DIFF is in effect.
+
+ * In 1.7.9 era, we taught "git rebase" about the raw timestamp format
+   but we did not teach the same trick to "filter-branch", which rolled
+   a similar logic on its own.
+
+ * When "git submodule add" clones a submodule repository, it can get
+   confused where to store the resulting submodule repository in the
+   superproject's .git/ directory when there is a symbolic link in the
+   path to the current directory.
+
+Also contains minor typofixes and documentation updates.
diff --git a/Documentation/RelNotes/1.7.11.5.txt b/Documentation/RelNotes/1.7.11.5.txt
new file mode 100644 (file)
index 0000000..0a2ed85
--- /dev/null
@@ -0,0 +1,36 @@
+Git v1.7.11.5 Release Notes
+===========================
+
+Fixes since v1.7.11.4
+---------------------
+
+ * The Makefile rule to create assembly output (primarily for
+   debugging purposes) did not create it next to the source.
+
+ * The code to avoid mistaken attempt to add the object directory
+   itself as its own alternate could read beyond end of a string while
+   comparison.
+
+ * On some architectures, "block-sha1" did not compile correctly
+   when compilers inferred alignment guarantees from our source we
+   did not intend to make.
+
+ * When talking to a remote running ssh on IPv6 enabled host, whose
+   address is spelled as "[HOST]:PORT", we did not parse the address
+   correctly and failed to connect.
+
+ * git-blame.el (in compat/) have been updated to use Elisp more
+   correctly.
+
+ * "git checkout <branchname>" to come back from a detached HEAD state
+   incorrectly computed reachability of the detached HEAD, resulting
+   in unnecessary warnings.
+
+ * "git mergetool" did not support --tool-help option to give the list
+   of supported backends, like "git difftool" does.
+
+ * "git grep" stopped spawning an external "grep" long time ago, but a
+   duplicated test to check internal and external "grep" was left
+   behind.
+
+Also contains minor typofixes and documentation updates.
index 904561de18f35b380759f4794ebe6927828f0198..010d8c7de471a373cf6f1d26422c4ed84ce23ced 100644 (file)
@@ -51,10 +51,6 @@ UI, Workflows & Features
    read. The error message in this case was updated to give better
    hints to the user.
 
- * git native protocol agents learned to show software version over
-   the wire, so that the server log can be examined to see the vintage
-   distribution of clients.
-
  * "git help -w $cmd" can show HTML version of documentation for
    "git-$cmd" by setting help.htmlpath to somewhere other than the
    default location where the build procedure installs them locally;
@@ -117,6 +113,9 @@ Performance, Internal Implementation, etc. (please report possible regressions)
    cycles after showing the first change to find the next one, only to
    discard it.
 
+ * "git svn" got a large-looking code reorganization at the last
+   minute before the code freeze.
+
 
 Also contains minor documentation updates and code clean-ups.
 
@@ -128,42 +127,10 @@ Unless otherwise noted, all the fixes since v1.7.11 in the maintenance
 releases are contained in this release (see release notes to them for
 details).
 
- * "git mergetool" did not support --tool-help option to give the list
-   of supported backends, like "git difftool" does.
-   (merge 109859e jc/mergetool-tool-help later to maint).
-
- * "$GIT_DIR/COMMIT_EDITMSG" file that is used to hold the commit log
-   message user edits was not documented.
-   (merge 41f597d jk/maint-commit-document-editmsg later to maint).
+ * "git submodule add" was confused when the superproject did not have
+   its repository in its usual place in the working tree and GIT_DIR
+   and GIT_WORK_TREE was used to access it.
 
  * "git commit --amend" let the user edit the log message and then died
    when the human-readable committer name was given insufficiently by
    getpwent(3).
-   (merge f20f387 jk/maint-commit-check-committer-early later to maint).
-
- * The advise() function did not use varargs correctly to format
-   its message.
-   (merge 447b99c jk/maint-advise-vaddf later to maint).
-
- * "git commit-tree" learned a more natural "-p <parent> <tree>" order
-   of arguments long time ago, but recently forgot it by mistake.
-   (merge 4b7518a kk/maint-commit-tree later to maint).
-
- * "git diff --no-ext-diff" did not output anything for a typechange
-   filepair when GIT_EXTERNAL_DIFF is in effect.
-   (merge c12f82a jv/maint-no-ext-diff later to maint).
-
- * When "git am" failed, old timers knew to check .git/rebase-apply/patch
-   to see what went wrong, but we never told the users about it.
-   (merge 14bf2d5 pg/maint-1.7.9-am-where-is-patch later to maint).
-
- * When "git submodule add" clones a submodule repository, it can get
-   confused where to store the resulting submodule repository in the
-   superproject's .git/ directory when there is a symbolic link in the
-   path to the current directory.
-   (merge 6eafa6d jl/maint-1.7.10-recurse-submodules-with-symlink later to maint).
-
- * In 1.7.9 era, we taught "git rebase" about the raw timestamp format
-   but we did not teach the same trick to "filter-branch", which rolled
-   a similar logic on its own.
-   (merge 44b85e89 jc/maint-filter-branch-epoch-date later to maint).
index 53adee320361085a0f9bbc9f9da17f0d3db60d20..810e957124feeb383e14e860aa1df46f99a03b5a 100644 (file)
@@ -3,7 +3,7 @@ git-credential(1)
 
 NAME
 ----
-git-credential - retrieve and store user credentials
+git-credential - Retrieve and store user credentials
 
 SYNOPSIS
 --------
index bf22ad527c7b19eecf7338a83ad12d40cf07b948..27da0eb209446ea9d7c1b7705f64403f0013e49b 100644 (file)
@@ -33,7 +33,7 @@ as defined in the configuration file (see linkgit:git-config[1]).
 
 Formatted and hyperlinked version of the latest git
 documentation can be viewed at
-`http://www.kernel.org/pub/software/scm/git/docs/`.
+`http://git-htmldocs.googlecode.com/git/git.html`.
 
 ifdef::stalenotes[]
 [NOTE]
@@ -44,9 +44,16 @@ 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.11.3/git.html[documentation for release 1.7.11.3]
+* link:v1.7.12/git.html[documentation for release 1.7.12]
 
 * release notes for
+  link:RelNotes/1.7.12.txt[1.7.12].
+
+* link:v1.7.11.5/git.html[documentation for release 1.7.11.5]
+
+* release notes for
+  link:RelNotes/1.7.11.5.txt[1.7.11.5],
+  link:RelNotes/1.7.11.4.txt[1.7.11.4],
   link:RelNotes/1.7.11.3.txt[1.7.11.3],
   link:RelNotes/1.7.11.2.txt[1.7.11.2],
   link:RelNotes/1.7.11.1.txt[1.7.11.1],
index 22bb2298ae9087a6db826e231fb803d803b11494..b27a2ff687183607854ed630519b30e4136d0b6c 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.12-rc0
+DEF_VER=v1.7.12
 
 LF='
 '
index b0b3493364550f9f443039708974902df1896413..6b0c961d3acd6eb476c979e51f32a258e15c743d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1014,6 +1014,7 @@ ifeq ($(uname_S),SunOS)
        NO_REGEX = YesPlease
        NO_FNMATCH_CASEFOLD = YesPlease
        NO_MSGFMT_EXTENDED_OPTIONS = YesPlease
+       HAVE_DEV_TTY = YesPlease
        ifeq ($(uname_R),5.6)
                SOCKLEN_T = int
                NO_HSTRERROR = YesPlease
@@ -2090,6 +2091,13 @@ $(SCRIPT_LIB) : % : %.sh GIT-SCRIPT-DEFINES
 ifndef NO_PERL
 $(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak
 
+perl/perl.mak: perl/PM.stamp
+
+perl/PM.stamp: FORCE
+       $(QUIET_GEN)$(FIND) perl -type f -name '*.pm' | sort >$@+ && \
+       { cmp $@+ $@ >/dev/null 2>/dev/null || mv $@+ $@; } && \
+       $(RM) $@+
+
 perl/perl.mak: GIT-CFLAGS GIT-PREFIX perl/Makefile perl/Makefile.PL
        $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F)
 
@@ -2387,7 +2395,8 @@ XGETTEXT_FLAGS = \
        --from-code=UTF-8
 XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \
        --keyword=_ --keyword=N_ --keyword="Q_:1,2"
-XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell
+XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \
+       --keyword=gettextln --keyword=eval_gettextln
 XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl
 LOCALIZED_C := $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H)
 LOCALIZED_SH := $(SCRIPT_SH)
index 6acca75f4740e9412c418124ce791c00f7b4ba4b..d812219b30247795b6db7487329605a088057db1 100644 (file)
@@ -606,7 +606,7 @@ static int add_pending_uninteresting_ref(const char *refname,
                                         const unsigned char *sha1,
                                         int flags, void *cb_data)
 {
-       add_pending_sha1(cb_data, refname, sha1, flags | UNINTERESTING);
+       add_pending_sha1(cb_data, refname, sha1, UNINTERESTING);
        return 0;
 }
 
index 14ea67af038fbfce388dd20b8adcda503106911d..ec64cacf06d1cc7c0f2de4a12bb2b465f5351250 100644 (file)
@@ -25,6 +25,7 @@ git-commit                              mainporcelain common
 git-commit-tree                         plumbingmanipulators
 git-config                              ancillarymanipulators
 git-count-objects                       ancillaryinterrogators
+git-credential                          purehelpers
 git-cvsexportcommit                     foreignscminterface
 git-cvsimport                           foreignscminterface
 git-cvsserver                           foreignscminterface
index 6d16c8fba0b305a2e1020d9e1c7f1d1ad64d302f..bbb038dd0103034b85b0e9d407dfa91e607c1eeb 100644 (file)
@@ -59,6 +59,7 @@ char *git_terminal_prompt(const char *prompt, int echo)
 
        r = strbuf_getline(&buf, fh, '\n');
        if (!echo) {
+               fseek(fh, SEEK_CUR, 0);
                putc('\n', fh);
                fflush(fh);
        }
index 8647c92df82657d5d3e2c6a43fb315f270548226..68555d426540d710b5220168c9fa8eee9f946219 100755 (executable)
@@ -9,20 +9,7 @@
 # License: GPL v2 or later
 
 # Gateway between Git and MediaWiki.
-#   https://github.com/Bibzball/Git-Mediawiki/wiki
-#
-# Known limitations:
-#
-# - Several strategies are provided to fetch modifications from the
-#   wiki, but no automatic heuristics is provided, the user has
-#   to understand and chose which strategy is appropriate for him.
-#
-# - Git renames could be turned into MediaWiki renames (see TODO
-#   below)
-#
-# - No way to import "one page, and all pages included in it"
-#
-# - Multiple remote MediaWikis have not been very well tested.
+# Documentation & bugtracker: https://github.com/moy/Git-Mediawiki/
 
 use strict;
 use MediaWiki::API;
diff --git a/diff.c b/diff.c
index 62cbe141efb411e831484fc36c0cba95a2b8846b..95706a5b4098afc8f20fe53425ff760c996a3b4e 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1397,7 +1397,7 @@ int print_stat_summary(FILE *fp, int files, int insertions, int deletions)
 
        if (!files) {
                assert(insertions == 0 && deletions == 0);
-               return fputs(_(" 0 files changed\n"), fp);
+               return fprintf(fp, "%s\n", _(" 0 files changed"));
        }
 
        strbuf_addf(&sb,
index c02e62d2aa4f3bd2221c687effa3a4ec44918383..bd9620c6c6b25a083dacc0bb3fe9d45337ed0d7b 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -92,7 +92,7 @@ safe_to_abort () {
        then
                return 0
        fi
-               gettextln "You seem to have moved HEAD since the last 'am' failure.
+       gettextln "You seem to have moved HEAD since the last 'am' failure.
 Not rewinding to ORIG_HEAD" >&2
        return 1
 }
@@ -102,9 +102,9 @@ stop_here_user_resolve () {
            printf '%s\n' "$resolvemsg"
            stop_here $1
     fi
-    eval_gettextln "When you have resolved this problem run \"\$cmdline --resolved\".
-If you would prefer to skip this patch, instead run \"\$cmdline --skip\".
-To restore the original branch and stop patching run \"\$cmdline --abort\"."
+    eval_gettextln "When you have resolved this problem, run \"\$cmdline --resolved\".
+If you prefer to skip this patch, run \"\$cmdline --skip\" instead.
+To restore the original branch and stop patching, run \"\$cmdline --abort\"."
 
     stop_here $1
 }
@@ -136,7 +136,7 @@ fall_back_3way () {
     git write-tree >"$dotest/patch-merge-base+" ||
     cannot_fallback "$(gettext "Repository lacks necessary blobs to fall back on 3-way merge.")"
 
-    say Using index info to reconstruct a base tree...
+    say "$(gettext "Using index info to reconstruct a base tree...")"
 
     cmd='GIT_INDEX_FILE="$dotest/patch-merge-tmp-index"'
 
@@ -176,8 +176,7 @@ It does not apply to blobs recorded in its index.")"
     fi
     git-merge-recursive $orig_tree -- HEAD $his_tree || {
            git rerere $allow_rerere_autoupdate
-           echo Failed to merge in the changes.
-           exit 1
+           die "$(gettext "Failed to merge in the changes.")"
     }
     unset GITHEAD_$his_tree
 }
@@ -387,8 +386,8 @@ do
        -i|--interactive)
                interactive=t ;;
        -b|--binary)
-               echo >&2 "The $1 option has been a no-op for long time, and"
-               echo >&2 "it will be removed. Please do not use it anymore."
+               gettextln >&2 "The -b/--binary option has been a no-op for long time, and
+it will be removed. Please do not use it anymore."
                ;;
        -3|--3way)
                threeway=t ;;
@@ -414,9 +413,6 @@ do
                abort=t ;;
        --rebasing)
                rebasing=t threeway=t ;;
-       -d|--dotest)
-               die "$(gettext "-d option is no longer supported.  Do not use.")"
-               ;;
        --resolvemsg)
                shift; resolvemsg=$1 ;;
        --whitespace|--directory|--exclude|--include)
index 1cd0633b80a8daf00dbc50657ccba228bd578a73..15da926ce0d2cefc0620d4c5c4a761bceb2b911f 100755 (executable)
@@ -3,31 +3,6 @@
 # Copyright (c) 2005 Junio C Hamano.
 #
 
-USAGE='[--interactive | -i] [--exec | -x <cmd>] [-v] [--force-rebase | -f]
-       [--no-ff] [--onto <newbase>] [<upstream>|--root] [<branch>] [--quiet | -q]'
-LONG_USAGE='git-rebase replaces <branch> with a new branch of the
-same name.  When the --onto option is provided the new branch starts
-out with a HEAD equal to <newbase>, otherwise it is equal to <upstream>
-It then attempts to create a new commit for each commit from the original
-<branch> that does not exist in the <upstream> branch.
-
-It is possible that a merge failure will prevent this process from being
-completely automatic.  You will have to resolve any such merge failure
-and run git rebase --continue.  Another option is to bypass the commit
-that caused the merge failure with git rebase --skip.  To check out the
-original <branch> and remove the .git/rebase-apply working files, use the
-command git rebase --abort instead.
-
-Note that if <branch> is not specified on the command line, the
-currently checked out branch is used.
-
-Example:       git-rebase master~1 topic
-
-       A---B---C topic                   A'\''--B'\''--C'\'' topic
-       /                   -->           /
-  D---E---F---G master          D---E---F---G master
-'
-
 SUBDIRECTORY_OK=Yes
 OPTIONS_KEEPDASHDASH=
 OPTIONS_SPEC="\
@@ -65,6 +40,7 @@ abort!             abort and check out the original branch
 skip!              skip current patch and continue
 "
 . git-sh-setup
+. git-sh-i18n
 set_reflog_action rebase
 require_work_tree_exists
 cd_to_toplevel
@@ -73,9 +49,9 @@ LF='
 '
 ok_to_skip_pre_rebase=
 resolvemsg="
-When you have resolved this problem run \"git rebase --continue\".
-If you would prefer to skip this patch, instead run \"git rebase --skip\".
-To check out the original branch and stop rebasing run \"git rebase --abort\".
+$(gettext 'When you have resolved this problem, run "git rebase --continue".
+If you prefer to skip this patch, run "git rebase --skip" instead.
+To check out the original branch and stop rebasing, run "git rebase --abort".')
 "
 unset onto
 cmd=
@@ -161,7 +137,7 @@ move_to_original_branch () {
                git symbolic-ref \
                        -m "rebase finished: returning to $head_name" \
                        HEAD $head_name ||
-               die "Could not move back to $head_name"
+               die "$(gettext "Could not move back to $head_name")"
                ;;
        esac
 }
@@ -180,12 +156,12 @@ run_pre_rebase_hook () {
           test -x "$GIT_DIR/hooks/pre-rebase"
        then
                "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} ||
-               die "The pre-rebase hook refused to rebase."
+               die "$(gettext "The pre-rebase hook refused to rebase.")"
        fi
 }
 
 test -f "$apply_dir"/applying &&
-       die 'It looks like git-am is in progress. Cannot rebase.'
+       die "$(gettext "It looks like git-am is in progress. Cannot rebase.")"
 
 if test -d "$apply_dir"
 then
@@ -316,12 +292,12 @@ test $# -gt 2 && usage
 if test -n "$cmd" &&
    test "$interactive_rebase" != explicit
 then
-       die "--exec option must be used with --interactive option"
+       die "$(gettext "The --exec option must be used with the --interactive option")"
 fi
 
 if test -n "$action"
 then
-       test -z "$in_progress" && die "No rebase in progress?"
+       test -z "$in_progress" && die "$(gettext "No rebase in progress?")"
        # Only interactive rebase uses detailed reflog messages
        if test "$type" = interactive && test "$GIT_REFLOG_ACTION" = rebase
        then
@@ -334,11 +310,11 @@ case "$action" in
 continue)
        # Sanity check
        git rev-parse --verify HEAD >/dev/null ||
-               die "Cannot read HEAD"
+               die "$(gettext "Cannot read HEAD")"
        git update-index --ignore-submodules --refresh &&
        git diff-files --quiet --ignore-submodules || {
-               echo "You must edit all merge conflicts and then"
-               echo "mark them as resolved using git add"
+               echo "$(gettext "You must edit all merge conflicts and then
+mark them as resolved using git add")"
                exit 1
        }
        read_basic_state
@@ -355,7 +331,7 @@ abort)
        case "$head_name" in
        refs/*)
                git symbolic-ref -m "rebase: aborting" HEAD $head_name ||
-               die "Could not move back to $head_name"
+               die "$(eval_gettext "Could not move back to \$head_name")"
                ;;
        esac
        output git reset --hard $orig_head
@@ -367,15 +343,18 @@ esac
 # Make sure no rebase is in progress
 if test -n "$in_progress"
 then
-       die '
-It seems that there is already a '"${state_dir##*/}"' directory, and
+       state_dir_base=${state_dir##*/}
+       cmd_live_rebase="git rebase (--continue | --abort | --skip)"
+       cmd_clear_stale_rebase="rm -fr \"$state_dir\""
+       die "
+$(eval_gettext 'It seems that there is already a $state_dir_base directory, and
 I wonder if you are in the middle of another rebase.  If that is the
 case, please try
-       git rebase (--continue | --abort | --skip)
+       $cmd_live_rebase
 If that is not the case, please
-       rm -fr '"$state_dir"'
+       $cmd_clear_stale_rebase
 and run me again.  I am stopping in case you still have something
-valuable there.'
+valuable there.')"
 fi
 
 if test -n "$rebase_root" && test -z "$onto"
@@ -413,7 +392,7 @@ then
                ;;
        esac
        upstream=`git rev-parse --verify "${upstream_name}^0"` ||
-       die "invalid upstream $upstream_name"
+       die "$(eval_gettext "invalid upstream \$upstream_name")"
        upstream_arg="$upstream_name"
 else
        if test -z "$onto"
@@ -437,19 +416,19 @@ case "$onto_name" in
        then
                case "$onto" in
                ?*"$LF"?*)
-                       die "$onto_name: there are more than one merge bases"
+                       die "$(eval_gettext "\$onto_name: there are more than one merge bases")"
                        ;;
                '')
-                       die "$onto_name: there is no merge base"
+                       die "$(eval_gettext "\$onto_name: there is no merge base")"
                        ;;
                esac
        else
-               die "$onto_name: there is no merge base"
+               die "$(eval_gettext "\$onto_name: there is no merge base")"
        fi
        ;;
 *)
        onto=$(git rev-parse --verify "${onto_name}^0") ||
-       die "Does not point to a valid commit: $onto_name"
+       die "$(eval_gettext "Does not point to a valid commit: \$onto_name")"
        ;;
 esac
 
@@ -472,7 +451,7 @@ case "$#" in
        then
                head_name="detached HEAD"
        else
-               die "fatal: no such branch: $1"
+               die "$(eval_gettext "fatal: no such branch: \$branch_name")"
        fi
        ;;
 0)
@@ -492,7 +471,7 @@ case "$#" in
        ;;
 esac
 
-require_clean_work_tree "rebase" "Please commit or stash them."
+require_clean_work_tree "rebase" "$(gettext "Please commit or stash them.")"
 
 # Now we are rebasing commits $upstream..$orig_head (or with --root,
 # everything leading up to $orig_head) on top of $onto
@@ -510,10 +489,10 @@ then
        then
                # Lazily switch to the target branch if needed...
                test -z "$switch_to" || git checkout "$switch_to" --
-               say "Current branch $branch_name is up to date."
+               say "$(eval_gettext "Current branch \$branch_name is up to date.")"
                exit 0
        else
-               say "Current branch $branch_name is up to date, rebase forced."
+               say "$(eval_gettext "Current branch \$branch_name is up to date, rebase forced.")"
        fi
 fi
 
@@ -524,7 +503,7 @@ if test -n "$diffstat"
 then
        if test -n "$verbose"
        then
-               echo "Changes from $mb to $onto:"
+               echo "$(eval_gettext "Changes from \$mb to \$onto:")"
        fi
        # We want color (if set), but no pager
        GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
@@ -533,7 +512,7 @@ fi
 test "$type" = interactive && run_specific_rebase
 
 # Detach HEAD and reset the tree
-say "First, rewinding head to replay your work on top of it..."
+say "$(gettext "First, rewinding head to replay your work on top of it...")"
 git checkout -q "$onto^0" || die "could not detach HEAD"
 git update-ref ORIG_HEAD $orig_head
 
@@ -541,7 +520,7 @@ git update-ref ORIG_HEAD $orig_head
 # we just fast-forwarded.
 if test "$mb" = "$orig_head"
 then
-       say "Fast-forwarded $branch_name to $onto_name."
+       say "$(eval_gettext "Fast-forwarded \$branch_name to \$onto_name.")"
        move_to_original_branch
        exit 0
 fi
index dba4d39e1fd3e971336e0d85f24c114c29c4d1fd..aac575e74f833c9bce28b779733b28a7611246b2 100755 (executable)
@@ -181,8 +181,11 @@ module_clone()
                rm -f "$gitdir/index"
        else
                mkdir -p "$gitdir_base"
-               git clone $quiet -n ${reference:+"$reference"} \
-                       --separate-git-dir "$gitdir" "$url" "$sm_path" ||
+               (
+                       clear_local_git_env
+                       git clone $quiet -n ${reference:+"$reference"} \
+                               --separate-git-dir "$gitdir" "$url" "$sm_path"
+               ) ||
                die "$(eval_gettext "Clone of '\$url' into submodule path '\$sm_path' failed")"
        fi
 
@@ -748,7 +751,7 @@ cmd_summary() {
        if [ -n "$files" ]
        then
                test -n "$cached" &&
-               die "$(gettext -- "--cached cannot be used with --files")"
+               die "$(gettext "The --cached option cannot be used with the --files option")"
                diff_cmd=diff-files
                head=
        fi
index 6673d21f841c7f5a4806bc7785c5ae7755f9297b..0d77ffb0b92b9e94454aeb94b434d9f86acd8a13 100755 (executable)
 $AUTHOR = 'Eric Wong <normalperson@yhbt.net>';
 $VERSION = '@@GIT_VERSION@@';
 
+use Carp qw/croak/;
+use Digest::MD5;
+use IO::File qw//;
+use File::Basename qw/dirname basename/;
+use File::Path qw/mkpath/;
+use File::Spec;
+use File::Find;
+use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
+use IPC::Open3;
+use Memoize;
+
+use Git::SVN;
+use Git::SVN::Editor;
+use Git::SVN::Fetcher;
+use Git::SVN::Ra;
+use Git::SVN::Prompt;
+use Git::SVN::Log;
+use Git::SVN::Migration;
+
+use Git::SVN::Utils qw(
+       fatal
+       can_compress
+       canonicalize_path
+       canonicalize_url
+       join_paths
+       add_path_to_url
+       join_paths
+);
+
+use Git qw(
+       git_cmd_try
+       command
+       command_oneline
+       command_noisy
+       command_output_pipe
+       command_close_pipe
+       command_bidi_pipe
+       command_close_bidi_pipe
+);
+
+BEGIN {
+       Memoize::memoize 'Git::config';
+       Memoize::memoize 'Git::config_bool';
+}
+
+
 # From which subdir have we been invoked?
 my $cmd_dir_prefix = eval {
        command_oneline([qw/rev-parse --show-prefix/], STDERR => 0)
 
 my $git_dir_user_set = 1 if defined $ENV{GIT_DIR};
 $ENV{GIT_DIR} ||= '.git';
-$Git::SVN::default_repo_id = 'svn';
-$Git::SVN::default_ref_id = $ENV{GIT_SVN_ID} || 'git-svn';
 $Git::SVN::Ra::_log_window_size = 100;
-$Git::SVN::_minimize_url = 'unset';
 
 if (! exists $ENV{SVN_SSH} && exists $ENV{GIT_SSH}) {
        $ENV{SVN_SSH} = $ENV{GIT_SSH};
@@ -35,8 +78,6 @@
 $ENV{TZ} = 'UTC';
 $| = 1; # unbuffer STDOUT
 
-sub fatal (@) { print STDERR "@_\n"; exit 1 }
-
 # All SVN commands do it.  Otherwise we may die on SIGPIPE when the remote
 # repository decides to close the connection which we expect to be kept alive.
 $SIG{PIPE} = 'IGNORE';
@@ -66,39 +107,6 @@ sub _req_svn {
                fatal "Need SVN::Core 1.1.0 or better (got $SVN::Core::VERSION)";
        }
 }
-my $can_compress = eval { require Compress::Zlib; 1};
-use Carp qw/croak/;
-use Digest::MD5;
-use IO::File qw//;
-use File::Basename qw/dirname basename/;
-use File::Path qw/mkpath/;
-use File::Spec;
-use File::Find;
-use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
-use IPC::Open3;
-use Git;
-use Git::SVN::Editor qw//;
-use Git::SVN::Fetcher qw//;
-use Git::SVN::Ra qw//;
-use Git::SVN::Prompt qw//;
-use Memoize;  # core since 5.8.0, Jul 2002
-
-BEGIN {
-       # import functions from Git into our packages, en masse
-       no strict 'refs';
-       foreach (qw/command command_oneline command_noisy command_output_pipe
-                   command_input_pipe command_close_pipe
-                   command_bidi_pipe command_close_bidi_pipe/) {
-               for my $package ( qw(Git::SVN::Migration Git::SVN::Log Git::SVN),
-                       __PACKAGE__) {
-                       *{"${package}::$_"} = \&{"Git::$_"};
-               }
-       }
-       Memoize::memoize 'Git::config';
-       Memoize::memoize 'Git::config_bool';
-}
-
-my ($SVN);
 
 $sha1 = qr/[a-f\d]{40}/;
 $sha1_short = qr/[a-f\d]{4,40}/;
@@ -108,8 +116,11 @@ BEGIN
        $_version, $_fetch_all, $_no_rebase, $_fetch_parent,
        $_merge, $_strategy, $_preserve_merges, $_dry_run, $_local,
        $_prefix, $_no_checkout, $_url, $_verbose,
-       $_git_format, $_commit_url, $_tag, $_merge_info, $_interactive);
-$Git::SVN::_follow_parent = 1;
+       $_commit_url, $_tag, $_merge_info, $_interactive);
+
+# This is a refactoring artifact so Git::SVN can get at this git-svn switch.
+sub opt_prefix { return $_prefix || '' }
+
 $Git::SVN::Fetcher::_placeholder_filename = ".gitignore";
 $_q ||= 0;
 my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
@@ -269,7 +280,7 @@ BEGIN
                    { 'url' => \$_url, } ],
        'blame' => [ \&Git::SVN::Log::cmd_blame,
                    "Show what revision and author last modified each line of a file",
-                   { 'git-format' => \$_git_format } ],
+                   { 'git-format' => \$Git::SVN::Log::_git_format } ],
        'reset' => [ \&cmd_reset,
                     "Undo fetches back to the specified SVN revision",
                     { 'revision|r=s' => \$_revision,
@@ -775,6 +786,44 @@ sub populate_merge_info {
        return undef;
 }
 
+sub dcommit_rebase {
+       my ($is_last, $current, $fetched_ref, $svn_error) = @_;
+       my @diff;
+
+       if ($svn_error) {
+               print STDERR "\nERROR from SVN:\n",
+                               $svn_error->expanded_message, "\n";
+       }
+       unless ($_no_rebase) {
+               # we always want to rebase against the current HEAD,
+               # not any head that was passed to us
+               @diff = command('diff-tree', $current,
+                          $fetched_ref, '--');
+               my @finish;
+               if (@diff) {
+                       @finish = rebase_cmd();
+                       print STDERR "W: $current and ", $fetched_ref,
+                                    " differ, using @finish:\n",
+                                    join("\n", @diff), "\n";
+               } elsif ($is_last) {
+                       print "No changes between ", $current, " and ",
+                             $fetched_ref,
+                             "\nResetting to the latest ",
+                             $fetched_ref, "\n";
+                       @finish = qw/reset --mixed/;
+               }
+               command_noisy(@finish, $fetched_ref) if @finish;
+       }
+       if ($svn_error) {
+               die "ERROR: Not all changes have been committed into SVN"
+                       .($_no_rebase ? ".\n" : ", however the committed\n"
+                       ."ones (if any) seem to be successfully integrated "
+                       ."into the working tree.\n")
+                       ."Please see the above messages for details.\n";
+       }
+       return @diff;
+}
+
 sub cmd_dcommit {
        my $head = shift;
        command_noisy(qw/update-index --refresh/);
@@ -902,6 +951,7 @@ sub cmd_dcommit {
        }
 
        my $rewritten_parent;
+       my $current_head = command_oneline(qw/rev-parse HEAD/);
        Git::SVN::remove_username($expect_url);
        if (defined($_merge_info)) {
                $_merge_info =~ tr{ }{\n};
@@ -941,6 +991,14 @@ sub cmd_dcommit {
                                        },
                                        mergeinfo => $_merge_info,
                                        svn_path => '');
+
+                       my $err_handler = $SVN::Error::handler;
+                       $SVN::Error::handler = sub {
+                               my $err = shift;
+                               dcommit_rebase(1, $current_head, $gs->refname,
+                                       $err);
+                       };
+
                        if (!Git::SVN::Editor->new(\%ed_opts)->apply_diff) {
                                print "No changes\n$d~1 == $d\n";
                        } elsif ($parents->{$d} && @{$parents->{$d}}) {
@@ -948,31 +1006,19 @@ sub cmd_dcommit {
                                                               $parents->{$d};
                        }
                        $_fetch_all ? $gs->fetch_all : $gs->fetch;
+                       $SVN::Error::handler = $err_handler;
                        $last_rev = $cmt_rev;
                        next if $_no_rebase;
 
-                       # we always want to rebase against the current HEAD,
-                       # not any head that was passed to us
-                       my @diff = command('diff-tree', $d,
-                                          $gs->refname, '--');
-                       my @finish;
-                       if (@diff) {
-                               @finish = rebase_cmd();
-                               print STDERR "W: $d and ", $gs->refname,
-                                            " differ, using @finish:\n",
-                                            join("\n", @diff), "\n";
-                       } else {
-                               print "No changes between current HEAD and ",
-                                     $gs->refname,
-                                     "\nResetting to the latest ",
-                                     $gs->refname, "\n";
-                               @finish = qw/reset --mixed/;
-                       }
-                       command_noisy(@finish, $gs->refname);
+                       my @diff = dcommit_rebase(@$linear_refs == 0, $d,
+                                               $gs->refname, undef);
 
-                       $rewritten_parent = command_oneline(qw/rev-parse HEAD/);
+                       $rewritten_parent = command_oneline(qw/rev-parse/,
+                                                       $gs->refname);
 
                        if (@diff) {
+                               $current_head = command_oneline(qw/rev-parse
+                                                               HEAD/);
                                @refs = ();
                                my ($url_, $rev_, $uuid_, $gs_) =
                                              working_head_info('HEAD', \@refs);
@@ -1017,6 +1063,7 @@ sub cmd_dcommit {
                                }
                                $parents = \%p;
                                $linear_refs = \@l;
+                               undef $last_rev;
                        }
                }
        }
@@ -1193,7 +1240,7 @@ sub cmd_show_ignore {
        my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
        $gs ||= Git::SVN->new;
        my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
-       $gs->prop_walk($gs->{path}, $r, sub {
+       $gs->prop_walk($gs->path, $r, sub {
                my ($gs, $path, $props) = @_;
                print STDOUT "\n# $path\n";
                my $s = $props->{'svn:ignore'} or return;
@@ -1209,7 +1256,7 @@ sub cmd_show_externals {
        my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
        $gs ||= Git::SVN->new;
        my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
-       $gs->prop_walk($gs->{path}, $r, sub {
+       $gs->prop_walk($gs->path, $r, sub {
                my ($gs, $path, $props) = @_;
                print STDOUT "\n# $path\n";
                my $s = $props->{'svn:externals'} or return;
@@ -1224,7 +1271,7 @@ sub cmd_create_ignore {
        my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
        $gs ||= Git::SVN->new;
        my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
-       $gs->prop_walk($gs->{path}, $r, sub {
+       $gs->prop_walk($gs->path, $r, sub {
                my ($gs, $path, $props) = @_;
                # $path is of the form /path/to/dir/
                $path = '.' . $path;
@@ -1254,31 +1301,6 @@ sub cmd_mkdirs {
        $gs->mkemptydirs($_revision);
 }
 
-sub canonicalize_path {
-       my ($path) = @_;
-       my $dot_slash_added = 0;
-       if (substr($path, 0, 1) ne "/") {
-               $path = "./" . $path;
-               $dot_slash_added = 1;
-       }
-       # File::Spec->canonpath doesn't collapse x/../y into y (for a
-       # good reason), so let's do this manually.
-       $path =~ s#/+#/#g;
-       $path =~ s#/\.(?:/|$)#/#g;
-       $path =~ s#/[^/]+/\.\.##g;
-       $path =~ s#/$##g;
-       $path =~ s#^\./## if $dot_slash_added;
-       $path =~ s#^/##;
-       $path =~ s#^\.$##;
-       return $path;
-}
-
-sub canonicalize_url {
-       my ($url) = @_;
-       $url =~ s#^([^:]+://[^/]*/)(.*)$#$1 . canonicalize_path($2)#e;
-       return $url;
-}
-
 # get_svnprops(PATH)
 # ------------------
 # Helper for cmd_propget and cmd_proplist below.
@@ -1292,7 +1314,7 @@ sub get_svnprops {
        $path = $cmd_dir_prefix . $path;
        fatal("No such file or directory: $path") unless -e $path;
        my $is_dir = -d $path ? 1 : 0;
-       $path = $gs->{path} . '/' . $path;
+       $path = join_paths($gs->{path}, $path);
 
        # canonicalize the path (otherwise libsvn will abort or fail to
        # find the file)
@@ -1393,8 +1415,8 @@ sub cmd_commit_diff {
                        fatal("Needed URL or usable git-svn --id in ",
                              "the command-line\n", $usage);
                }
-               $url = $gs->{url};
-               $svn_path = $gs->{path};
+               $url = $gs->url;
+               $svn_path = $gs->path;
        }
        unless (defined $_revision) {
                fatal("-r|--revision is a required argument\n", $usage);
@@ -1428,24 +1450,6 @@ sub cmd_commit_diff {
        }
 }
 
-sub escape_uri_only {
-       my ($uri) = @_;
-       my @tmp;
-       foreach (split m{/}, $uri) {
-               s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
-               push @tmp, $_;
-       }
-       join('/', @tmp);
-}
-
-sub escape_url {
-       my ($url) = @_;
-       if ($url =~ m#^([^:]+)://([^/]*)(.*)$#) {
-               my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3));
-               $url = "$scheme://$domain$uri";
-       }
-       $url;
-}
 
 sub cmd_info {
        my $path = canonicalize_path(defined($_[0]) ? $_[0] : ".");
@@ -1470,21 +1474,21 @@ sub cmd_info {
        # canonicalize_path() will return "" to make libsvn 1.5.x happy,
        $path = "." if $path eq "";
 
-       my $full_url = $url . ($fullpath eq "" ? "" : "/$fullpath");
+       my $full_url = canonicalize_url( add_path_to_url( $url, $fullpath ) );
 
        if ($_url) {
-               print escape_url($full_url), "\n";
+               print "$full_url\n";
                return;
        }
 
        my $result = "Path: $path\n";
        $result .= "Name: " . basename($path) . "\n" if $file_type ne "dir";
-       $result .= "URL: " . escape_url($full_url) . "\n";
+       $result .= "URL: $full_url\n";
 
        eval {
                my $repos_root = $gs->repos_root;
                Git::SVN::remove_username($repos_root);
-               $result .= "Repository Root: " . escape_url($repos_root) . "\n";
+               $result .= "Repository Root: " . canonicalize_url($repos_root) . "\n";
        };
        if ($@) {
                $result .= "Repository Root: (offline)\n";
@@ -1578,7 +1582,7 @@ sub cmd_reset {
 }
 
 sub cmd_gc {
-       if (!$can_compress) {
+       if (!can_compress()) {
                warn "Compress::Zlib could not be found; unhandled.log " .
                     "files will not be compressed.\n";
        }
@@ -1631,7 +1635,9 @@ sub post_fetch_checkout {
 
 sub complete_svn_url {
        my ($url, $path) = @_;
-       $path =~ s#/+$##;
+       $path = canonicalize_path($path);
+
+       # If the path is not a URL...
        if ($path !~ m#^[a-z\+]+://#) {
                if (!defined $url || $url !~ m#^[a-z\+]+://#) {
                        fatal("E: '$path' is not a complete URL ",
@@ -1648,7 +1654,7 @@ sub complete_url_ls_init {
                print STDERR "W: $switch not specified\n";
                return;
        }
-       $repo_path =~ s#/+$##;
+       $repo_path = canonicalize_path($repo_path);
        if ($repo_path =~ m#^[a-z\+]+://#) {
                $ra = Git::SVN::Ra->new($repo_path);
                $repo_path = '';
@@ -1659,18 +1665,18 @@ sub complete_url_ls_init {
                              "and a separate URL is not specified");
                }
        }
-       my $url = $ra->{url};
+       my $url = $ra->url;
        my $gs = Git::SVN->init($url, undef, undef, undef, 1);
        my $k = "svn-remote.$gs->{repo_id}.url";
        my $orig_url = eval { command_oneline(qw/config --get/, $k) };
-       if ($orig_url && ($orig_url ne $gs->{url})) {
+       if ($orig_url && ($orig_url ne $gs->url)) {
                die "$k already set: $orig_url\n",
-                   "wanted to set to: $gs->{url}\n";
+                   "wanted to set to: $gs->url\n";
        }
-       command_oneline('config', $k, $gs->{url}) unless $orig_url;
-       my $remote_path = "$gs->{path}/$repo_path";
+       command_oneline('config', $k, $gs->url) unless $orig_url;
+
+       my $remote_path = join_paths( $gs->path, $repo_path );
        $remote_path =~ s{%([0-9A-F]{2})}{chr hex($1)}ieg;
-       $remote_path =~ s#/+#/#g;
        $remote_path =~ s#^/##g;
        $remote_path .= "/*" if $remote_path !~ /\*/;
        my ($n) = ($switch =~ /^--(\w+)/);
@@ -2013,13 +2019,13 @@ sub md5sum {
        } elsif (!$ref) {
                $md5->add($arg) or croak $!;
        } else {
-               ::fatal "Can't provide MD5 hash for unknown ref type: '", $ref, "'";
+               fatal "Can't provide MD5 hash for unknown ref type: '", $ref, "'";
        }
        return $md5->hexdigest();
 }
 
 sub gc_directory {
-       if ($can_compress && -f $_ && basename($_) eq "unhandled.log") {
+       if (can_compress() && -f $_ && basename($_) eq "unhandled.log") {
                my $out_filename = $_ . ".gz";
                open my $in_fh, "<", $_ or die "Unable to open $_: $!\n";
                binmode $in_fh;
@@ -2037,3035 +2043,6 @@ sub gc_directory {
        }
 }
 
-package Git::SVN;
-use strict;
-use warnings;
-use Fcntl qw/:DEFAULT :seek/;
-use constant rev_map_fmt => 'NH40';
-use vars qw/$default_repo_id $default_ref_id $_no_metadata $_follow_parent
-            $_repack $_repack_flags $_use_svm_props $_head
-            $_use_svnsync_props $no_reuse_existing $_minimize_url
-           $_use_log_author $_add_author_from $_localtime/;
-use Carp qw/croak/;
-use File::Path qw/mkpath/;
-use File::Copy qw/copy/;
-use IPC::Open3;
-use Time::Local;
-use Memoize;  # core since 5.8.0, Jul 2002
-use Memoize::Storable;
-use POSIX qw(:signal_h);
-my $can_use_yaml;
-BEGIN {
-       $can_use_yaml = eval { require Git::SVN::Memoize::YAML; 1};
-}
-
-my ($_gc_nr, $_gc_period);
-
-# properties that we do not log:
-my %SKIP_PROP;
-BEGIN {
-       %SKIP_PROP = map { $_ => 1 } qw/svn:wc:ra_dav:version-url
-                                       svn:special svn:executable
-                                       svn:entry:committed-rev
-                                       svn:entry:last-author
-                                       svn:entry:uuid
-                                       svn:entry:committed-date/;
-
-       # some options are read globally, but can be overridden locally
-       # per [svn-remote "..."] section.  Command-line options will *NOT*
-       # override options set in an [svn-remote "..."] section
-       no strict 'refs';
-       for my $option (qw/follow_parent no_metadata use_svm_props
-                          use_svnsync_props/) {
-               my $key = $option;
-               $key =~ tr/_//d;
-               my $prop = "-$option";
-               *$option = sub {
-                       my ($self) = @_;
-                       return $self->{$prop} if exists $self->{$prop};
-                       my $k = "svn-remote.$self->{repo_id}.$key";
-                       eval { command_oneline(qw/config --get/, $k) };
-                       if ($@) {
-                               $self->{$prop} = ${"Git::SVN::_$option"};
-                       } else {
-                               my $v = command_oneline(qw/config --bool/,$k);
-                               $self->{$prop} = $v eq 'false' ? 0 : 1;
-                       }
-                       return $self->{$prop};
-               }
-       }
-}
-
-
-my (%LOCKFILES, %INDEX_FILES);
-END {
-       unlink keys %LOCKFILES if %LOCKFILES;
-       unlink keys %INDEX_FILES if %INDEX_FILES;
-}
-
-sub resolve_local_globs {
-       my ($url, $fetch, $glob_spec) = @_;
-       return unless defined $glob_spec;
-       my $ref = $glob_spec->{ref};
-       my $path = $glob_spec->{path};
-       foreach (command(qw#for-each-ref --format=%(refname) refs/#)) {
-               next unless m#^$ref->{regex}$#;
-               my $p = $1;
-               my $pathname = desanitize_refname($path->full_path($p));
-               my $refname = desanitize_refname($ref->full_path($p));
-               if (my $existing = $fetch->{$pathname}) {
-                       if ($existing ne $refname) {
-                               die "Refspec conflict:\n",
-                                   "existing: $existing\n",
-                                   " globbed: $refname\n";
-                       }
-                       my $u = (::cmt_metadata("$refname"))[0];
-                       $u =~ s!^\Q$url\E(/|$)!! or die
-                         "$refname: '$url' not found in '$u'\n";
-                       if ($pathname ne $u) {
-                               warn "W: Refspec glob conflict ",
-                                    "(ref: $refname):\n",
-                                    "expected path: $pathname\n",
-                                    "    real path: $u\n",
-                                    "Continuing ahead with $u\n";
-                               next;
-                       }
-               } else {
-                       $fetch->{$pathname} = $refname;
-               }
-       }
-}
-
-sub parse_revision_argument {
-       my ($base, $head) = @_;
-       if (!defined $::_revision || $::_revision eq 'BASE:HEAD') {
-               return ($base, $head);
-       }
-       return ($1, $2) if ($::_revision =~ /^(\d+):(\d+)$/);
-       return ($::_revision, $::_revision) if ($::_revision =~ /^\d+$/);
-       return ($head, $head) if ($::_revision eq 'HEAD');
-       return ($base, $1) if ($::_revision =~ /^BASE:(\d+)$/);
-       return ($1, $head) if ($::_revision =~ /^(\d+):HEAD$/);
-       die "revision argument: $::_revision not understood by git-svn\n";
-}
-
-sub fetch_all {
-       my ($repo_id, $remotes) = @_;
-       if (ref $repo_id) {
-               my $gs = $repo_id;
-               $repo_id = undef;
-               $repo_id = $gs->{repo_id};
-       }
-       $remotes ||= read_all_remotes();
-       my $remote = $remotes->{$repo_id} or
-                    die "[svn-remote \"$repo_id\"] unknown\n";
-       my $fetch = $remote->{fetch};
-       my $url = $remote->{url} or die "svn-remote.$repo_id.url not defined\n";
-       my (@gs, @globs);
-       my $ra = Git::SVN::Ra->new($url);
-       my $uuid = $ra->get_uuid;
-       my $head = $ra->get_latest_revnum;
-
-       # ignore errors, $head revision may not even exist anymore
-       eval { $ra->get_log("", $head, 0, 1, 0, 1, sub { $head = $_[1] }) };
-       warn "W: $@\n" if $@;
-
-       my $base = defined $fetch ? $head : 0;
-
-       # read the max revs for wildcard expansion (branches/*, tags/*)
-       foreach my $t (qw/branches tags/) {
-               defined $remote->{$t} or next;
-               push @globs, @{$remote->{$t}};
-
-               my $max_rev = eval { tmp_config(qw/--int --get/,
-                                        "svn-remote.$repo_id.${t}-maxRev") };
-               if (defined $max_rev && ($max_rev < $base)) {
-                       $base = $max_rev;
-               } elsif (!defined $max_rev) {
-                       $base = 0;
-               }
-       }
-
-       if ($fetch) {
-               foreach my $p (sort keys %$fetch) {
-                       my $gs = Git::SVN->new($fetch->{$p}, $repo_id, $p);
-                       my $lr = $gs->rev_map_max;
-                       if (defined $lr) {
-                               $base = $lr if ($lr < $base);
-                       }
-                       push @gs, $gs;
-               }
-       }
-
-       ($base, $head) = parse_revision_argument($base, $head);
-       $ra->gs_fetch_loop_common($base, $head, \@gs, \@globs);
-}
-
-sub read_all_remotes {
-       my $r = {};
-       my $use_svm_props = eval { command_oneline(qw/config --bool
-           svn.useSvmProps/) };
-       $use_svm_props = $use_svm_props eq 'true' if $use_svm_props;
-       my $svn_refspec = qr{\s*(.*?)\s*:\s*(.+?)\s*};
-       foreach (grep { s/^svn-remote\.// } command(qw/config -l/)) {
-               if (m!^(.+)\.fetch=$svn_refspec$!) {
-                       my ($remote, $local_ref, $remote_ref) = ($1, $2, $3);
-                       die("svn-remote.$remote: remote ref '$remote_ref' "
-                           . "must start with 'refs/'\n")
-                               unless $remote_ref =~ m{^refs/};
-                       $local_ref = uri_decode($local_ref);
-                       $r->{$remote}->{fetch}->{$local_ref} = $remote_ref;
-                       $r->{$remote}->{svm} = {} if $use_svm_props;
-               } elsif (m!^(.+)\.usesvmprops=\s*(.*)\s*$!) {
-                       $r->{$1}->{svm} = {};
-               } elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
-                       $r->{$1}->{url} = $2;
-               } elsif (m!^(.+)\.pushurl=\s*(.*)\s*$!) {
-                       $r->{$1}->{pushurl} = $2;
-               } elsif (m!^(.+)\.ignore-refs=\s*(.*)\s*$!) {
-                       $r->{$1}->{ignore_refs_regex} = $2;
-               } elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
-                       my ($remote, $t, $local_ref, $remote_ref) =
-                                                            ($1, $2, $3, $4);
-                       die("svn-remote.$remote: remote ref '$remote_ref' ($t) "
-                           . "must start with 'refs/'\n")
-                               unless $remote_ref =~ m{^refs/};
-                       $local_ref = uri_decode($local_ref);
-                       my $rs = {
-                           t => $t,
-                           remote => $remote,
-                           path => Git::SVN::GlobSpec->new($local_ref, 1),
-                           ref => Git::SVN::GlobSpec->new($remote_ref, 0) };
-                       if (length($rs->{ref}->{right}) != 0) {
-                               die "The '*' glob character must be the last ",
-                                   "character of '$remote_ref'\n";
-                       }
-                       push @{ $r->{$remote}->{$t} }, $rs;
-               }
-       }
-
-       map {
-               if (defined $r->{$_}->{svm}) {
-                       my $svm;
-                       eval {
-                               my $section = "svn-remote.$_";
-                               $svm = {
-                                       source => tmp_config('--get',
-                                           "$section.svm-source"),
-                                       replace => tmp_config('--get',
-                                           "$section.svm-replace"),
-                               }
-                       };
-                       $r->{$_}->{svm} = $svm;
-               }
-       } keys %$r;
-
-       foreach my $remote (keys %$r) {
-               foreach ( grep { defined $_ }
-                         map { $r->{$remote}->{$_} } qw(branches tags) ) {
-                       foreach my $rs ( @$_ ) {
-                               $rs->{ignore_refs_regex} =
-                                   $r->{$remote}->{ignore_refs_regex};
-                       }
-               }
-       }
-
-       $r;
-}
-
-sub init_vars {
-       $_gc_nr = $_gc_period = 1000;
-       if (defined $_repack || defined $_repack_flags) {
-              warn "Repack options are obsolete; they have no effect.\n";
-       }
-}
-
-sub verify_remotes_sanity {
-       return unless -d $ENV{GIT_DIR};
-       my %seen;
-       foreach (command(qw/config -l/)) {
-               if (m!^svn-remote\.(?:.+)\.fetch=.*:refs/remotes/(\S+)\s*$!) {
-                       if ($seen{$1}) {
-                               die "Remote ref refs/remote/$1 is tracked by",
-                                   "\n  \"$_\"\nand\n  \"$seen{$1}\"\n",
-                                   "Please resolve this ambiguity in ",
-                                   "your git configuration file before ",
-                                   "continuing\n";
-                       }
-                       $seen{$1} = $_;
-               }
-       }
-}
-
-sub find_existing_remote {
-       my ($url, $remotes) = @_;
-       return undef if $no_reuse_existing;
-       my $existing;
-       foreach my $repo_id (keys %$remotes) {
-               my $u = $remotes->{$repo_id}->{url} or next;
-               next if $u ne $url;
-               $existing = $repo_id;
-               last;
-       }
-       $existing;
-}
-
-sub init_remote_config {
-       my ($self, $url, $no_write) = @_;
-       $url =~ s!/+$!!; # strip trailing slash
-       my $r = read_all_remotes();
-       my $existing = find_existing_remote($url, $r);
-       if ($existing) {
-               unless ($no_write) {
-                       print STDERR "Using existing ",
-                                    "[svn-remote \"$existing\"]\n";
-               }
-               $self->{repo_id} = $existing;
-       } elsif ($_minimize_url) {
-               my $min_url = Git::SVN::Ra->new($url)->minimize_url;
-               $existing = find_existing_remote($min_url, $r);
-               if ($existing) {
-                       unless ($no_write) {
-                               print STDERR "Using existing ",
-                                            "[svn-remote \"$existing\"]\n";
-                       }
-                       $self->{repo_id} = $existing;
-               }
-               if ($min_url ne $url) {
-                       unless ($no_write) {
-                               print STDERR "Using higher level of URL: ",
-                                            "$url => $min_url\n";
-                       }
-                       my $old_path = $self->{path};
-                       $self->{path} = $url;
-                       $self->{path} =~ s!^\Q$min_url\E(/|$)!!;
-                       if (length $old_path) {
-                               $self->{path} .= "/$old_path";
-                       }
-                       $url = $min_url;
-               }
-       }
-       my $orig_url;
-       if (!$existing) {
-               # verify that we aren't overwriting anything:
-               $orig_url = eval {
-                       command_oneline('config', '--get',
-                                       "svn-remote.$self->{repo_id}.url")
-               };
-               if ($orig_url && ($orig_url ne $url)) {
-                       die "svn-remote.$self->{repo_id}.url already set: ",
-                           "$orig_url\nwanted to set to: $url\n";
-               }
-       }
-       my ($xrepo_id, $xpath) = find_ref($self->refname);
-       if (!$no_write && defined $xpath) {
-               die "svn-remote.$xrepo_id.fetch already set to track ",
-                   "$xpath:", $self->refname, "\n";
-       }
-       unless ($no_write) {
-               command_noisy('config',
-                             "svn-remote.$self->{repo_id}.url", $url);
-               $self->{path} =~ s{^/}{};
-               $self->{path} =~ s{%([0-9A-F]{2})}{chr hex($1)}ieg;
-               command_noisy('config', '--add',
-                             "svn-remote.$self->{repo_id}.fetch",
-                             "$self->{path}:".$self->refname);
-       }
-       $self->{url} = $url;
-}
-
-sub find_by_url { # repos_root and, path are optional
-       my ($class, $full_url, $repos_root, $path) = @_;
-
-       return undef unless defined $full_url;
-       remove_username($full_url);
-       remove_username($repos_root) if defined $repos_root;
-       my $remotes = read_all_remotes();
-       if (defined $full_url && defined $repos_root && !defined $path) {
-               $path = $full_url;
-               $path =~ s#^\Q$repos_root\E(?:/|$)##;
-       }
-       foreach my $repo_id (keys %$remotes) {
-               my $u = $remotes->{$repo_id}->{url} or next;
-               remove_username($u);
-               next if defined $repos_root && $repos_root ne $u;
-
-               my $fetch = $remotes->{$repo_id}->{fetch} || {};
-               foreach my $t (qw/branches tags/) {
-                       foreach my $globspec (@{$remotes->{$repo_id}->{$t}}) {
-                               resolve_local_globs($u, $fetch, $globspec);
-                       }
-               }
-               my $p = $path;
-               my $rwr = rewrite_root({repo_id => $repo_id});
-               my $svm = $remotes->{$repo_id}->{svm}
-                       if defined $remotes->{$repo_id}->{svm};
-               unless (defined $p) {
-                       $p = $full_url;
-                       my $z = $u;
-                       my $prefix = '';
-                       if ($rwr) {
-                               $z = $rwr;
-                               remove_username($z);
-                       } elsif (defined $svm) {
-                               $z = $svm->{source};
-                               $prefix = $svm->{replace};
-                               $prefix =~ s#^\Q$u\E(?:/|$)##;
-                               $prefix =~ s#/$##;
-                       }
-                       $p =~ s#^\Q$z\E(?:/|$)#$prefix# or next;
-               }
-               foreach my $f (keys %$fetch) {
-                       next if $f ne $p;
-                       return Git::SVN->new($fetch->{$f}, $repo_id, $f);
-               }
-       }
-       undef;
-}
-
-sub init {
-       my ($class, $url, $path, $repo_id, $ref_id, $no_write) = @_;
-       my $self = _new($class, $repo_id, $ref_id, $path);
-       if (defined $url) {
-               $self->init_remote_config($url, $no_write);
-       }
-       $self;
-}
-
-sub find_ref {
-       my ($ref_id) = @_;
-       foreach (command(qw/config -l/)) {
-               next unless m!^svn-remote\.(.+)\.fetch=
-                             \s*(.*?)\s*:\s*(.+?)\s*$!x;
-               my ($repo_id, $path, $ref) = ($1, $2, $3);
-               if ($ref eq $ref_id) {
-                       $path = '' if ($path =~ m#^\./?#);
-                       return ($repo_id, $path);
-               }
-       }
-       (undef, undef, undef);
-}
-
-sub new {
-       my ($class, $ref_id, $repo_id, $path) = @_;
-       if (defined $ref_id && !defined $repo_id && !defined $path) {
-               ($repo_id, $path) = find_ref($ref_id);
-               if (!defined $repo_id) {
-                       die "Could not find a \"svn-remote.*.fetch\" key ",
-                           "in the repository configuration matching: ",
-                           "$ref_id\n";
-               }
-       }
-       my $self = _new($class, $repo_id, $ref_id, $path);
-       if (!defined $self->{path} || !length $self->{path}) {
-               my $fetch = command_oneline('config', '--get',
-                                           "svn-remote.$repo_id.fetch",
-                                           ":$ref_id\$") or
-                    die "Failed to read \"svn-remote.$repo_id.fetch\" ",
-                        "\":$ref_id\$\" in config\n";
-               ($self->{path}, undef) = split(/\s*:\s*/, $fetch);
-       }
-       $self->{path} =~ s{/+}{/}g;
-       $self->{path} =~ s{\A/}{};
-       $self->{path} =~ s{/\z}{};
-       $self->{url} = command_oneline('config', '--get',
-                                      "svn-remote.$repo_id.url") or
-                  die "Failed to read \"svn-remote.$repo_id.url\" in config\n";
-       $self->{pushurl} = eval { command_oneline('config', '--get',
-                                 "svn-remote.$repo_id.pushurl") };
-       $self->rebuild;
-       $self;
-}
-
-sub refname {
-       my ($refname) = $_[0]->{ref_id} ;
-
-       # It cannot end with a slash /, we'll throw up on this because
-       # SVN can't have directories with a slash in their name, either:
-       if ($refname =~ m{/$}) {
-               die "ref: '$refname' ends with a trailing slash, this is ",
-                   "not permitted by git nor Subversion\n";
-       }
-
-       # It cannot have ASCII control character space, tilde ~, caret ^,
-       # colon :, question-mark ?, asterisk *, space, or open bracket [
-       # anywhere.
-       #
-       # Additionally, % must be escaped because it is used for escaping
-       # and we want our escaped refname to be reversible
-       $refname =~ s{([ \%~\^:\?\*\[\t])}{uc sprintf('%%%02x',ord($1))}eg;
-
-       # no slash-separated component can begin with a dot .
-       # /.* becomes /%2E*
-       $refname =~ s{/\.}{/%2E}g;
-
-       # It cannot have two consecutive dots .. anywhere
-       # .. becomes %2E%2E
-       $refname =~ s{\.\.}{%2E%2E}g;
-
-       # trailing dots and .lock are not allowed
-       # .$ becomes %2E and .lock becomes %2Elock
-       $refname =~ s{\.(?=$|lock$)}{%2E};
-
-       # the sequence @{ is used to access the reflog
-       # @{ becomes %40{
-       $refname =~ s{\@\{}{%40\{}g;
-
-       return $refname;
-}
-
-sub desanitize_refname {
-       my ($refname) = @_;
-       $refname =~ s{%(?:([0-9A-F]{2}))}{chr hex($1)}eg;
-       return $refname;
-}
-
-sub svm_uuid {
-       my ($self) = @_;
-       return $self->{svm}->{uuid} if $self->svm;
-       $self->ra;
-       unless ($self->{svm}) {
-               die "SVM UUID not cached, and reading remotely failed\n";
-       }
-       $self->{svm}->{uuid};
-}
-
-sub svm {
-       my ($self) = @_;
-       return $self->{svm} if $self->{svm};
-       my $svm;
-       # see if we have it in our config, first:
-       eval {
-               my $section = "svn-remote.$self->{repo_id}";
-               $svm = {
-                 source => tmp_config('--get', "$section.svm-source"),
-                 uuid => tmp_config('--get', "$section.svm-uuid"),
-                 replace => tmp_config('--get', "$section.svm-replace"),
-               }
-       };
-       if ($svm && $svm->{source} && $svm->{uuid} && $svm->{replace}) {
-               $self->{svm} = $svm;
-       }
-       $self->{svm};
-}
-
-sub _set_svm_vars {
-       my ($self, $ra) = @_;
-       return $ra if $self->svm;
-
-       my @err = ( "useSvmProps set, but failed to read SVM properties\n",
-                   "(svm:source, svm:uuid) ",
-                   "from the following URLs:\n" );
-       sub read_svm_props {
-               my ($self, $ra, $path, $r) = @_;
-               my $props = ($ra->get_dir($path, $r))[2];
-               my $src = $props->{'svm:source'};
-               my $uuid = $props->{'svm:uuid'};
-               return undef if (!$src || !$uuid);
-
-               chomp($src, $uuid);
-
-               $uuid =~ m{^[0-9a-f\-]{30,}$}i
-                   or die "doesn't look right - svm:uuid is '$uuid'\n";
-
-               # the '!' is used to mark the repos_root!/relative/path
-               $src =~ s{/?!/?}{/};
-               $src =~ s{/+$}{}; # no trailing slashes please
-               # username is of no interest
-               $src =~ s{(^[a-z\+]*://)[^/@]*@}{$1};
-
-               my $replace = $ra->{url};
-               $replace .= "/$path" if length $path;
-
-               my $section = "svn-remote.$self->{repo_id}";
-               tmp_config("$section.svm-source", $src);
-               tmp_config("$section.svm-replace", $replace);
-               tmp_config("$section.svm-uuid", $uuid);
-               $self->{svm} = {
-                       source => $src,
-                       uuid => $uuid,
-                       replace => $replace
-               };
-       }
-
-       my $r = $ra->get_latest_revnum;
-       my $path = $self->{path};
-       my %tried;
-       while (length $path) {
-               unless ($tried{"$self->{url}/$path"}) {
-                       return $ra if $self->read_svm_props($ra, $path, $r);
-                       $tried{"$self->{url}/$path"} = 1;
-               }
-               $path =~ s#/?[^/]+$##;
-       }
-       die "Path: '$path' should be ''\n" if $path ne '';
-       return $ra if $self->read_svm_props($ra, $path, $r);
-       $tried{"$self->{url}/$path"} = 1;
-
-       if ($ra->{repos_root} eq $self->{url}) {
-               die @err, (map { "  $_\n" } keys %tried), "\n";
-       }
-
-       # nope, make sure we're connected to the repository root:
-       my $ok;
-       my @tried_b;
-       $path = $ra->{svn_path};
-       $ra = Git::SVN::Ra->new($ra->{repos_root});
-       while (length $path) {
-               unless ($tried{"$ra->{url}/$path"}) {
-                       $ok = $self->read_svm_props($ra, $path, $r);
-                       last if $ok;
-                       $tried{"$ra->{url}/$path"} = 1;
-               }
-               $path =~ s#/?[^/]+$##;
-       }
-       die "Path: '$path' should be ''\n" if $path ne '';
-       $ok ||= $self->read_svm_props($ra, $path, $r);
-       $tried{"$ra->{url}/$path"} = 1;
-       if (!$ok) {
-               die @err, (map { "  $_\n" } keys %tried), "\n";
-       }
-       Git::SVN::Ra->new($self->{url});
-}
-
-sub svnsync {
-       my ($self) = @_;
-       return $self->{svnsync} if $self->{svnsync};
-
-       if ($self->no_metadata) {
-               die "Can't have both 'noMetadata' and ",
-                   "'useSvnsyncProps' options set!\n";
-       }
-       if ($self->rewrite_root) {
-               die "Can't have both 'useSvnsyncProps' and 'rewriteRoot' ",
-                   "options set!\n";
-       }
-       if ($self->rewrite_uuid) {
-               die "Can't have both 'useSvnsyncProps' and 'rewriteUUID' ",
-                   "options set!\n";
-       }
-
-       my $svnsync;
-       # see if we have it in our config, first:
-       eval {
-               my $section = "svn-remote.$self->{repo_id}";
-
-               my $url = tmp_config('--get', "$section.svnsync-url");
-               ($url) = ($url =~ m{^([a-z\+]+://\S+)$}) or
-                  die "doesn't look right - svn:sync-from-url is '$url'\n";
-
-               my $uuid = tmp_config('--get', "$section.svnsync-uuid");
-               ($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}i) or
-                  die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
-
-               $svnsync = { url => $url, uuid => $uuid }
-       };
-       if ($svnsync && $svnsync->{url} && $svnsync->{uuid}) {
-               return $self->{svnsync} = $svnsync;
-       }
-
-       my $err = "useSvnsyncProps set, but failed to read " .
-                 "svnsync property: svn:sync-from-";
-       my $rp = $self->ra->rev_proplist(0);
-
-       my $url = $rp->{'svn:sync-from-url'} or die $err . "url\n";
-       ($url) = ($url =~ m{^([a-z\+]+://\S+)$}) or
-                  die "doesn't look right - svn:sync-from-url is '$url'\n";
-
-       my $uuid = $rp->{'svn:sync-from-uuid'} or die $err . "uuid\n";
-       ($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}i) or
-                  die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
-
-       my $section = "svn-remote.$self->{repo_id}";
-       tmp_config('--add', "$section.svnsync-uuid", $uuid);
-       tmp_config('--add', "$section.svnsync-url", $url);
-       return $self->{svnsync} = { url => $url, uuid => $uuid };
-}
-
-# this allows us to memoize our SVN::Ra UUID locally and avoid a
-# remote lookup (useful for 'git svn log').
-sub ra_uuid {
-       my ($self) = @_;
-       unless ($self->{ra_uuid}) {
-               my $key = "svn-remote.$self->{repo_id}.uuid";
-               my $uuid = eval { tmp_config('--get', $key) };
-               if (!$@ && $uuid && $uuid =~ /^([a-f\d\-]{30,})$/i) {
-                       $self->{ra_uuid} = $uuid;
-               } else {
-                       die "ra_uuid called without URL\n" unless $self->{url};
-                       $self->{ra_uuid} = $self->ra->get_uuid;
-                       tmp_config('--add', $key, $self->{ra_uuid});
-               }
-       }
-       $self->{ra_uuid};
-}
-
-sub _set_repos_root {
-       my ($self, $repos_root) = @_;
-       my $k = "svn-remote.$self->{repo_id}.reposRoot";
-       $repos_root ||= $self->ra->{repos_root};
-       tmp_config($k, $repos_root);
-       $repos_root;
-}
-
-sub repos_root {
-       my ($self) = @_;
-       my $k = "svn-remote.$self->{repo_id}.reposRoot";
-       eval { tmp_config('--get', $k) } || $self->_set_repos_root;
-}
-
-sub ra {
-       my ($self) = shift;
-       my $ra = Git::SVN::Ra->new($self->{url});
-       $self->_set_repos_root($ra->{repos_root});
-       if ($self->use_svm_props && !$self->{svm}) {
-               if ($self->no_metadata) {
-                       die "Can't have both 'noMetadata' and ",
-                           "'useSvmProps' options set!\n";
-               } elsif ($self->use_svnsync_props) {
-                       die "Can't have both 'useSvnsyncProps' and ",
-                           "'useSvmProps' options set!\n";
-               }
-               $ra = $self->_set_svm_vars($ra);
-               $self->{-want_revprops} = 1;
-       }
-       $ra;
-}
-
-# prop_walk(PATH, REV, SUB)
-# -------------------------
-# Recursively traverse PATH at revision REV and invoke SUB for each
-# directory that contains a SVN property.  SUB will be invoked as
-# follows:  &SUB(gs, path, props);  where `gs' is this instance of
-# Git::SVN, `path' the path to the directory where the properties
-# `props' were found.  The `path' will be relative to point of checkout,
-# that is, if url://repo/trunk is the current Git branch, and that
-# directory contains a sub-directory `d', SUB will be invoked with `/d/'
-# as `path' (note the trailing `/').
-sub prop_walk {
-       my ($self, $path, $rev, $sub) = @_;
-
-       $path =~ s#^/##;
-       my ($dirent, undef, $props) = $self->ra->get_dir($path, $rev);
-       $path =~ s#^/*#/#g;
-       my $p = $path;
-       # Strip the irrelevant part of the path.
-       $p =~ s#^/+\Q$self->{path}\E(/|$)#/#;
-       # Ensure the path is terminated by a `/'.
-       $p =~ s#/*$#/#;
-
-       # The properties contain all the internal SVN stuff nobody
-       # (usually) cares about.
-       my $interesting_props = 0;
-       foreach (keys %{$props}) {
-               # If it doesn't start with `svn:', it must be a
-               # user-defined property.
-               ++$interesting_props and next if $_ !~ /^svn:/;
-               # FIXME: Fragile, if SVN adds new public properties,
-               # this needs to be updated.
-               ++$interesting_props if /^svn:(?:ignore|keywords|executable
-                                                |eol-style|mime-type
-                                                |externals|needs-lock)$/x;
-       }
-       &$sub($self, $p, $props) if $interesting_props;
-
-       foreach (sort keys %$dirent) {
-               next if $dirent->{$_}->{kind} != $SVN::Node::dir;
-               $self->prop_walk($self->{path} . $p . $_, $rev, $sub);
-       }
-}
-
-sub last_rev { ($_[0]->last_rev_commit)[0] }
-sub last_commit { ($_[0]->last_rev_commit)[1] }
-
-# returns the newest SVN revision number and newest commit SHA1
-sub last_rev_commit {
-       my ($self) = @_;
-       if (defined $self->{last_rev} && defined $self->{last_commit}) {
-               return ($self->{last_rev}, $self->{last_commit});
-       }
-       my $c = ::verify_ref($self->refname.'^0');
-       if ($c && !$self->use_svm_props && !$self->no_metadata) {
-               my $rev = (::cmt_metadata($c))[1];
-               if (defined $rev) {
-                       ($self->{last_rev}, $self->{last_commit}) = ($rev, $c);
-                       return ($rev, $c);
-               }
-       }
-       my $map_path = $self->map_path;
-       unless (-e $map_path) {
-               ($self->{last_rev}, $self->{last_commit}) = (undef, undef);
-               return (undef, undef);
-       }
-       my ($rev, $commit) = $self->rev_map_max(1);
-       ($self->{last_rev}, $self->{last_commit}) = ($rev, $commit);
-       return ($rev, $commit);
-}
-
-sub get_fetch_range {
-       my ($self, $min, $max) = @_;
-       $max ||= $self->ra->get_latest_revnum;
-       $min ||= $self->rev_map_max;
-       (++$min, $max);
-}
-
-sub tmp_config {
-       my (@args) = @_;
-       my $old_def_config = "$ENV{GIT_DIR}/svn/config";
-       my $config = "$ENV{GIT_DIR}/svn/.metadata";
-       if (! -f $config && -f $old_def_config) {
-               rename $old_def_config, $config or
-                      die "Failed rename $old_def_config => $config: $!\n";
-       }
-       my $old_config = $ENV{GIT_CONFIG};
-       $ENV{GIT_CONFIG} = $config;
-       $@ = undef;
-       my @ret = eval {
-               unless (-f $config) {
-                       mkfile($config);
-                       open my $fh, '>', $config or
-                           die "Can't open $config: $!\n";
-                       print $fh "; This file is used internally by ",
-                                 "git-svn\n" or die
-                                 "Couldn't write to $config: $!\n";
-                       print $fh "; You should not have to edit it\n" or
-                             die "Couldn't write to $config: $!\n";
-                       close $fh or die "Couldn't close $config: $!\n";
-               }
-               command('config', @args);
-       };
-       my $err = $@;
-       if (defined $old_config) {
-               $ENV{GIT_CONFIG} = $old_config;
-       } else {
-               delete $ENV{GIT_CONFIG};
-       }
-       die $err if $err;
-       wantarray ? @ret : $ret[0];
-}
-
-sub tmp_index_do {
-       my ($self, $sub) = @_;
-       my $old_index = $ENV{GIT_INDEX_FILE};
-       $ENV{GIT_INDEX_FILE} = $self->{index};
-       $@ = undef;
-       my @ret = eval {
-               my ($dir, $base) = ($self->{index} =~ m#^(.*?)/?([^/]+)$#);
-               mkpath([$dir]) unless -d $dir;
-               &$sub;
-       };
-       my $err = $@;
-       if (defined $old_index) {
-               $ENV{GIT_INDEX_FILE} = $old_index;
-       } else {
-               delete $ENV{GIT_INDEX_FILE};
-       }
-       die $err if $err;
-       wantarray ? @ret : $ret[0];
-}
-
-sub assert_index_clean {
-       my ($self, $treeish) = @_;
-
-       $self->tmp_index_do(sub {
-               command_noisy('read-tree', $treeish) unless -e $self->{index};
-               my $x = command_oneline('write-tree');
-               my ($y) = (command(qw/cat-file commit/, $treeish) =~
-                          /^tree ($::sha1)/mo);
-               return if $y eq $x;
-
-               warn "Index mismatch: $y != $x\nrereading $treeish\n";
-               unlink $self->{index} or die "unlink $self->{index}: $!\n";
-               command_noisy('read-tree', $treeish);
-               $x = command_oneline('write-tree');
-               if ($y ne $x) {
-                       ::fatal "trees ($treeish) $y != $x\n",
-                               "Something is seriously wrong...";
-               }
-       });
-}
-
-sub get_commit_parents {
-       my ($self, $log_entry) = @_;
-       my (%seen, @ret, @tmp);
-       # legacy support for 'set-tree'; this is only used by set_tree_cb:
-       if (my $ip = $self->{inject_parents}) {
-               if (my $commit = delete $ip->{$log_entry->{revision}}) {
-                       push @tmp, $commit;
-               }
-       }
-       if (my $cur = ::verify_ref($self->refname.'^0')) {
-               push @tmp, $cur;
-       }
-       if (my $ipd = $self->{inject_parents_dcommit}) {
-               if (my $commit = delete $ipd->{$log_entry->{revision}}) {
-                       push @tmp, @$commit;
-               }
-       }
-       push @tmp, $_ foreach (@{$log_entry->{parents}}, @tmp);
-       while (my $p = shift @tmp) {
-               next if $seen{$p};
-               $seen{$p} = 1;
-               push @ret, $p;
-       }
-       @ret;
-}
-
-sub rewrite_root {
-       my ($self) = @_;
-       return $self->{-rewrite_root} if exists $self->{-rewrite_root};
-       my $k = "svn-remote.$self->{repo_id}.rewriteRoot";
-       my $rwr = eval { command_oneline(qw/config --get/, $k) };
-       if ($rwr) {
-               $rwr =~ s#/+$##;
-               if ($rwr !~ m#^[a-z\+]+://#) {
-                       die "$rwr is not a valid URL (key: $k)\n";
-               }
-       }
-       $self->{-rewrite_root} = $rwr;
-}
-
-sub rewrite_uuid {
-       my ($self) = @_;
-       return $self->{-rewrite_uuid} if exists $self->{-rewrite_uuid};
-       my $k = "svn-remote.$self->{repo_id}.rewriteUUID";
-       my $rwid = eval { command_oneline(qw/config --get/, $k) };
-       if ($rwid) {
-               $rwid =~ s#/+$##;
-               if ($rwid !~ m#^[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$#) {
-                       die "$rwid is not a valid UUID (key: $k)\n";
-               }
-       }
-       $self->{-rewrite_uuid} = $rwid;
-}
-
-sub metadata_url {
-       my ($self) = @_;
-       ($self->rewrite_root || $self->{url}) .
-          (length $self->{path} ? '/' . $self->{path} : '');
-}
-
-sub full_url {
-       my ($self) = @_;
-       $self->{url} . (length $self->{path} ? '/' . $self->{path} : '');
-}
-
-sub full_pushurl {
-       my ($self) = @_;
-       if ($self->{pushurl}) {
-               return $self->{pushurl} . (length $self->{path} ? '/' .
-                      $self->{path} : '');
-       } else {
-               return $self->full_url;
-       }
-}
-
-sub set_commit_header_env {
-       my ($log_entry) = @_;
-       my %env;
-       foreach my $ned (qw/NAME EMAIL DATE/) {
-               foreach my $ac (qw/AUTHOR COMMITTER/) {
-                       $env{"GIT_${ac}_${ned}"} = $ENV{"GIT_${ac}_${ned}"};
-               }
-       }
-
-       $ENV{GIT_AUTHOR_NAME} = $log_entry->{name};
-       $ENV{GIT_AUTHOR_EMAIL} = $log_entry->{email};
-       $ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = $log_entry->{date};
-
-       $ENV{GIT_COMMITTER_NAME} = (defined $log_entry->{commit_name})
-                                               ? $log_entry->{commit_name}
-                                               : $log_entry->{name};
-       $ENV{GIT_COMMITTER_EMAIL} = (defined $log_entry->{commit_email})
-                                               ? $log_entry->{commit_email}
-                                               : $log_entry->{email};
-       \%env;
-}
-
-sub restore_commit_header_env {
-       my ($env) = @_;
-       foreach my $ned (qw/NAME EMAIL DATE/) {
-               foreach my $ac (qw/AUTHOR COMMITTER/) {
-                       my $k = "GIT_${ac}_${ned}";
-                       if (defined $env->{$k}) {
-                               $ENV{$k} = $env->{$k};
-                       } else {
-                               delete $ENV{$k};
-                       }
-               }
-       }
-}
-
-sub gc {
-       command_noisy('gc', '--auto');
-};
-
-sub do_git_commit {
-       my ($self, $log_entry) = @_;
-       my $lr = $self->last_rev;
-       if (defined $lr && $lr >= $log_entry->{revision}) {
-               die "Last fetched revision of ", $self->refname,
-                   " was r$lr, but we are about to fetch: ",
-                   "r$log_entry->{revision}!\n";
-       }
-       if (my $c = $self->rev_map_get($log_entry->{revision})) {
-               croak "$log_entry->{revision} = $c already exists! ",
-                     "Why are we refetching it?\n";
-       }
-       my $old_env = set_commit_header_env($log_entry);
-       my $tree = $log_entry->{tree};
-       if (!defined $tree) {
-               $tree = $self->tmp_index_do(sub {
-                                           command_oneline('write-tree') });
-       }
-       die "Tree is not a valid sha1: $tree\n" if $tree !~ /^$::sha1$/o;
-
-       my @exec = ('git', 'commit-tree', $tree);
-       foreach ($self->get_commit_parents($log_entry)) {
-               push @exec, '-p', $_;
-       }
-       defined(my $pid = open3(my $msg_fh, my $out_fh, '>&STDERR', @exec))
-                                                                  or croak $!;
-       binmode $msg_fh;
-
-       # we always get UTF-8 from SVN, but we may want our commits in
-       # a different encoding.
-       if (my $enc = Git::config('i18n.commitencoding')) {
-               require Encode;
-               Encode::from_to($log_entry->{log}, 'UTF-8', $enc);
-       }
-       print $msg_fh $log_entry->{log} or croak $!;
-       restore_commit_header_env($old_env);
-       unless ($self->no_metadata) {
-               print $msg_fh "\ngit-svn-id: $log_entry->{metadata}\n"
-                             or croak $!;
-       }
-       $msg_fh->flush == 0 or croak $!;
-       close $msg_fh or croak $!;
-       chomp(my $commit = do { local $/; <$out_fh> });
-       close $out_fh or croak $!;
-       waitpid $pid, 0;
-       croak $? if $?;
-       if ($commit !~ /^$::sha1$/o) {
-               die "Failed to commit, invalid sha1: $commit\n";
-       }
-
-       $self->rev_map_set($log_entry->{revision}, $commit, 1);
-
-       $self->{last_rev} = $log_entry->{revision};
-       $self->{last_commit} = $commit;
-       print "r$log_entry->{revision}" unless $::_q > 1;
-       if (defined $log_entry->{svm_revision}) {
-                print " (\@$log_entry->{svm_revision})" unless $::_q > 1;
-                $self->rev_map_set($log_entry->{svm_revision}, $commit,
-                                  0, $self->svm_uuid);
-       }
-       print " = $commit ($self->{ref_id})\n" unless $::_q > 1;
-       if (--$_gc_nr == 0) {
-               $_gc_nr = $_gc_period;
-               gc();
-       }
-       return $commit;
-}
-
-sub match_paths {
-       my ($self, $paths, $r) = @_;
-       return 1 if $self->{path} eq '';
-       if (my $path = $paths->{"/$self->{path}"}) {
-               return ($path->{action} eq 'D') ? 0 : 1;
-       }
-       $self->{path_regex} ||= qr/^\/\Q$self->{path}\E\//;
-       if (grep /$self->{path_regex}/, keys %$paths) {
-               return 1;
-       }
-       my $c = '';
-       foreach (split m#/#, $self->{path}) {
-               $c .= "/$_";
-               next unless ($paths->{$c} &&
-                            ($paths->{$c}->{action} =~ /^[AR]$/));
-               if ($self->ra->check_path($self->{path}, $r) ==
-                   $SVN::Node::dir) {
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-sub find_parent_branch {
-       my ($self, $paths, $rev) = @_;
-       return undef unless $self->follow_parent;
-       unless (defined $paths) {
-               my $err_handler = $SVN::Error::handler;
-               $SVN::Error::handler = \&Git::SVN::Ra::skip_unknown_revs;
-               $self->ra->get_log([$self->{path}], $rev, $rev, 0, 1, 1,
-                                  sub { $paths = $_[0] });
-               $SVN::Error::handler = $err_handler;
-       }
-       return undef unless defined $paths;
-
-       # look for a parent from another branch:
-       my @b_path_components = split m#/#, $self->{path};
-       my @a_path_components;
-       my $i;
-       while (@b_path_components) {
-               $i = $paths->{'/'.join('/', @b_path_components)};
-               last if $i && defined $i->{copyfrom_path};
-               unshift(@a_path_components, pop(@b_path_components));
-       }
-       return undef unless defined $i && defined $i->{copyfrom_path};
-       my $branch_from = $i->{copyfrom_path};
-       if (@a_path_components) {
-               print STDERR "branch_from: $branch_from => ";
-               $branch_from .= '/'.join('/', @a_path_components);
-               print STDERR $branch_from, "\n";
-       }
-       my $r = $i->{copyfrom_rev};
-       my $repos_root = $self->ra->{repos_root};
-       my $url = $self->ra->{url};
-       my $new_url = $url . $branch_from;
-       print STDERR  "Found possible branch point: ",
-                     "$new_url => ", $self->full_url, ", $r\n"
-                     unless $::_q > 1;
-       $branch_from =~ s#^/##;
-       my $gs = $self->other_gs($new_url, $url,
-                                $branch_from, $r, $self->{ref_id});
-       my ($r0, $parent) = $gs->find_rev_before($r, 1);
-       {
-               my ($base, $head);
-               if (!defined $r0 || !defined $parent) {
-                       ($base, $head) = parse_revision_argument(0, $r);
-               } else {
-                       if ($r0 < $r) {
-                               $gs->ra->get_log([$gs->{path}], $r0 + 1, $r, 1,
-                                       0, 1, sub { $base = $_[1] - 1 });
-                       }
-               }
-               if (defined $base && $base <= $r) {
-                       $gs->fetch($base, $r);
-               }
-               ($r0, $parent) = $gs->find_rev_before($r, 1);
-       }
-       if (defined $r0 && defined $parent) {
-               print STDERR "Found branch parent: ($self->{ref_id}) $parent\n"
-                            unless $::_q > 1;
-               my $ed;
-               if ($self->ra->can_do_switch) {
-                       $self->assert_index_clean($parent);
-                       print STDERR "Following parent with do_switch\n"
-                                    unless $::_q > 1;
-                       # do_switch works with svn/trunk >= r22312, but that
-                       # is not included with SVN 1.4.3 (the latest version
-                       # at the moment), so we can't rely on it
-                       $self->{last_rev} = $r0;
-                       $self->{last_commit} = $parent;
-                       $ed = Git::SVN::Fetcher->new($self, $gs->{path});
-                       $gs->ra->gs_do_switch($r0, $rev, $gs,
-                                             $self->full_url, $ed)
-                         or die "SVN connection failed somewhere...\n";
-               } elsif ($self->ra->trees_match($new_url, $r0,
-                                               $self->full_url, $rev)) {
-                       print STDERR "Trees match:\n",
-                                    "  $new_url\@$r0\n",
-                                    "  ${\$self->full_url}\@$rev\n",
-                                    "Following parent with no changes\n"
-                                    unless $::_q > 1;
-                       $self->tmp_index_do(sub {
-                           command_noisy('read-tree', $parent);
-                       });
-                       $self->{last_commit} = $parent;
-               } else {
-                       print STDERR "Following parent with do_update\n"
-                                    unless $::_q > 1;
-                       $ed = Git::SVN::Fetcher->new($self);
-                       $self->ra->gs_do_update($rev, $rev, $self, $ed)
-                         or die "SVN connection failed somewhere...\n";
-               }
-               print STDERR "Successfully followed parent\n" unless $::_q > 1;
-               return $self->make_log_entry($rev, [$parent], $ed);
-       }
-       return undef;
-}
-
-sub do_fetch {
-       my ($self, $paths, $rev) = @_;
-       my $ed;
-       my ($last_rev, @parents);
-       if (my $lc = $self->last_commit) {
-               # we can have a branch that was deleted, then re-added
-               # under the same name but copied from another path, in
-               # which case we'll have multiple parents (we don't
-               # want to break the original ref, nor lose copypath info):
-               if (my $log_entry = $self->find_parent_branch($paths, $rev)) {
-                       push @{$log_entry->{parents}}, $lc;
-                       return $log_entry;
-               }
-               $ed = Git::SVN::Fetcher->new($self);
-               $last_rev = $self->{last_rev};
-               $ed->{c} = $lc;
-               @parents = ($lc);
-       } else {
-               $last_rev = $rev;
-               if (my $log_entry = $self->find_parent_branch($paths, $rev)) {
-                       return $log_entry;
-               }
-               $ed = Git::SVN::Fetcher->new($self);
-       }
-       unless ($self->ra->gs_do_update($last_rev, $rev, $self, $ed)) {
-               die "SVN connection failed somewhere...\n";
-       }
-       $self->make_log_entry($rev, \@parents, $ed);
-}
-
-sub mkemptydirs {
-       my ($self, $r) = @_;
-
-       sub scan {
-               my ($r, $empty_dirs, $line) = @_;
-               if (defined $r && $line =~ /^r(\d+)$/) {
-                       return 0 if $1 > $r;
-               } elsif ($line =~ /^  \+empty_dir: (.+)$/) {
-                       $empty_dirs->{$1} = 1;
-               } elsif ($line =~ /^  \-empty_dir: (.+)$/) {
-                       my @d = grep {m[^\Q$1\E(/|$)]} (keys %$empty_dirs);
-                       delete @$empty_dirs{@d};
-               }
-               1; # continue
-       };
-
-       my %empty_dirs = ();
-       my $gz_file = "$self->{dir}/unhandled.log.gz";
-       if (-f $gz_file) {
-               if (!$can_compress) {
-                       warn "Compress::Zlib could not be found; ",
-                            "empty directories in $gz_file will not be read\n";
-               } else {
-                       my $gz = Compress::Zlib::gzopen($gz_file, "rb") or
-                               die "Unable to open $gz_file: $!\n";
-                       my $line;
-                       while ($gz->gzreadline($line) > 0) {
-                               scan($r, \%empty_dirs, $line) or last;
-                       }
-                       $gz->gzclose;
-               }
-       }
-
-       if (open my $fh, '<', "$self->{dir}/unhandled.log") {
-               binmode $fh or croak "binmode: $!";
-               while (<$fh>) {
-                       scan($r, \%empty_dirs, $_) or last;
-               }
-               close $fh;
-       }
-
-       my $strip = qr/\A\Q$self->{path}\E(?:\/|$)/;
-       foreach my $d (sort keys %empty_dirs) {
-               $d = uri_decode($d);
-               $d =~ s/$strip//;
-               next unless length($d);
-               next if -d $d;
-               if (-e $d) {
-                       warn "$d exists but is not a directory\n";
-               } else {
-                       print "creating empty directory: $d\n";
-                       mkpath([$d]);
-               }
-       }
-}
-
-sub get_untracked {
-       my ($self, $ed) = @_;
-       my @out;
-       my $h = $ed->{empty};
-       foreach (sort keys %$h) {
-               my $act = $h->{$_} ? '+empty_dir' : '-empty_dir';
-               push @out, "  $act: " . uri_encode($_);
-               warn "W: $act: $_\n";
-       }
-       foreach my $t (qw/dir_prop file_prop/) {
-               $h = $ed->{$t} or next;
-               foreach my $path (sort keys %$h) {
-                       my $ppath = $path eq '' ? '.' : $path;
-                       foreach my $prop (sort keys %{$h->{$path}}) {
-                               next if $SKIP_PROP{$prop};
-                               my $v = $h->{$path}->{$prop};
-                               my $t_ppath_prop = "$t: " .
-                                                   uri_encode($ppath) . ' ' .
-                                                   uri_encode($prop);
-                               if (defined $v) {
-                                       push @out, "  +$t_ppath_prop " .
-                                                  uri_encode($v);
-                               } else {
-                                       push @out, "  -$t_ppath_prop";
-                               }
-                       }
-               }
-       }
-       foreach my $t (qw/absent_file absent_directory/) {
-               $h = $ed->{$t} or next;
-               foreach my $parent (sort keys %$h) {
-                       foreach my $path (sort @{$h->{$parent}}) {
-                               push @out, "  $t: " .
-                                          uri_encode("$parent/$path");
-                               warn "W: $t: $parent/$path ",
-                                    "Insufficient permissions?\n";
-                       }
-               }
-       }
-       \@out;
-}
-
-sub get_tz {
-       # some systmes don't handle or mishandle %z, so be creative.
-       my $t = shift || time;
-       my $gm = timelocal(gmtime($t));
-       my $sign = qw( + + - )[ $t <=> $gm ];
-       return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
-}
-
-# parse_svn_date(DATE)
-# --------------------
-# Given a date (in UTC) from Subversion, return a string in the format
-# "<TZ Offset> <local date/time>" that Git will use.
-#
-# By default the parsed date will be in UTC; if $Git::SVN::_localtime
-# is true we'll convert it to the local timezone instead.
-sub parse_svn_date {
-       my $date = shift || return '+0000 1970-01-01 00:00:00';
-       my ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\d{4})\-(\d\d)\-(\d\d)T
-                                           (\d\d)\:(\d\d)\:(\d\d)\.\d*Z$/x) or
-                                        croak "Unable to parse date: $date\n";
-       my $parsed_date;    # Set next.
-
-       if ($Git::SVN::_localtime) {
-               # Translate the Subversion datetime to an epoch time.
-               # Begin by switching ourselves to $date's timezone, UTC.
-               my $old_env_TZ = $ENV{TZ};
-               $ENV{TZ} = 'UTC';
-
-               my $epoch_in_UTC =
-                   POSIX::strftime('%s', $S, $M, $H, $d, $m - 1, $Y - 1900);
-
-               # Determine our local timezone (including DST) at the
-               # time of $epoch_in_UTC.  $Git::SVN::Log::TZ stored the
-               # value of TZ, if any, at the time we were run.
-               if (defined $Git::SVN::Log::TZ) {
-                       $ENV{TZ} = $Git::SVN::Log::TZ;
-               } else {
-                       delete $ENV{TZ};
-               }
-
-               my $our_TZ = get_tz();
-
-               # This converts $epoch_in_UTC into our local timezone.
-               my ($sec, $min, $hour, $mday, $mon, $year,
-                   $wday, $yday, $isdst) = localtime($epoch_in_UTC);
-
-               $parsed_date = sprintf('%s %04d-%02d-%02d %02d:%02d:%02d',
-                                      $our_TZ, $year + 1900, $mon + 1,
-                                      $mday, $hour, $min, $sec);
-
-               # Reset us to the timezone in effect when we entered
-               # this routine.
-               if (defined $old_env_TZ) {
-                       $ENV{TZ} = $old_env_TZ;
-               } else {
-                       delete $ENV{TZ};
-               }
-       } else {
-               $parsed_date = "+0000 $Y-$m-$d $H:$M:$S";
-       }
-
-       return $parsed_date;
-}
-
-sub other_gs {
-       my ($self, $new_url, $url,
-           $branch_from, $r, $old_ref_id) = @_;
-       my $gs = Git::SVN->find_by_url($new_url, $url, $branch_from);
-       unless ($gs) {
-               my $ref_id = $old_ref_id;
-               $ref_id =~ s/\@\d+-*$//;
-               $ref_id .= "\@$r";
-               # just grow a tail if we're not unique enough :x
-               $ref_id .= '-' while find_ref($ref_id);
-               my ($u, $p, $repo_id) = ($new_url, '', $ref_id);
-               if ($u =~ s#^\Q$url\E(/|$)##) {
-                       $p = $u;
-                       $u = $url;
-                       $repo_id = $self->{repo_id};
-               }
-               while (1) {
-                       # It is possible to tag two different subdirectories at
-                       # the same revision.  If the url for an existing ref
-                       # does not match, we must either find a ref with a
-                       # matching url or create a new ref by growing a tail.
-                       $gs = Git::SVN->init($u, $p, $repo_id, $ref_id, 1);
-                       my (undef, $max_commit) = $gs->rev_map_max(1);
-                       last if (!$max_commit);
-                       my ($url) = ::cmt_metadata($max_commit);
-                       last if ($url eq $gs->metadata_url);
-                       $ref_id .= '-';
-               }
-               print STDERR "Initializing parent: $ref_id\n" unless $::_q > 1;
-       }
-       $gs
-}
-
-sub call_authors_prog {
-       my ($orig_author) = @_;
-       $orig_author = command_oneline('rev-parse', '--sq-quote', $orig_author);
-       my $author = `$::_authors_prog $orig_author`;
-       if ($? != 0) {
-               die "$::_authors_prog failed with exit code $?\n"
-       }
-       if ($author =~ /^\s*(.+?)\s*<(.*)>\s*$/) {
-               my ($name, $email) = ($1, $2);
-               $email = undef if length $2 == 0;
-               return [$name, $email];
-       } else {
-               die "Author: $orig_author: $::_authors_prog returned "
-                       . "invalid author format: $author\n";
-       }
-}
-
-sub check_author {
-       my ($author) = @_;
-       if (!defined $author || length $author == 0) {
-               $author = '(no author)';
-       }
-       if (!defined $::users{$author}) {
-               if (defined $::_authors_prog) {
-                       $::users{$author} = call_authors_prog($author);
-               } elsif (defined $::_authors) {
-                       die "Author: $author not defined in $::_authors file\n";
-               }
-       }
-       $author;
-}
-
-sub find_extra_svk_parents {
-       my ($self, $ed, $tickets, $parents) = @_;
-       # aha!  svk:merge property changed...
-       my @tickets = split "\n", $tickets;
-       my @known_parents;
-       for my $ticket ( @tickets ) {
-               my ($uuid, $path, $rev) = split /:/, $ticket;
-               if ( $uuid eq $self->ra_uuid ) {
-                       my $url = $self->{url};
-                       my $repos_root = $url;
-                       my $branch_from = $path;
-                       $branch_from =~ s{^/}{};
-                       my $gs = $self->other_gs($repos_root."/".$branch_from,
-                                                $url,
-                                                $branch_from,
-                                                $rev,
-                                                $self->{ref_id});
-                       if ( my $commit = $gs->rev_map_get($rev, $uuid) ) {
-                               # wahey!  we found it, but it might be
-                               # an old one (!)
-                               push @known_parents, [ $rev, $commit ];
-                       }
-               }
-       }
-       # Ordering matters; highest-numbered commit merge tickets
-       # first, as they may account for later merge ticket additions
-       # or changes.
-       @known_parents = map {$_->[1]} sort {$b->[0] <=> $a->[0]} @known_parents;
-       for my $parent ( @known_parents ) {
-               my @cmd = ('rev-list', $parent, map { "^$_" } @$parents );
-               my ($msg_fh, $ctx) = command_output_pipe(@cmd);
-               my $new;
-               while ( <$msg_fh> ) {
-                       $new=1;last;
-               }
-               command_close_pipe($msg_fh, $ctx);
-               if ( $new ) {
-                       print STDERR
-                           "Found merge parent (svk:merge ticket): $parent\n";
-                       push @$parents, $parent;
-               }
-       }
-}
-
-sub lookup_svn_merge {
-       my $uuid = shift;
-       my $url = shift;
-       my $merge = shift;
-
-       my ($source, $revs) = split ":", $merge;
-       my $path = $source;
-       $path =~ s{^/}{};
-       my $gs = Git::SVN->find_by_url($url.$source, $url, $path);
-       if ( !$gs ) {
-               warn "Couldn't find revmap for $url$source\n";
-               return;
-       }
-       my @ranges = split ",", $revs;
-       my ($tip, $tip_commit);
-       my @merged_commit_ranges;
-       # find the tip
-       for my $range ( @ranges ) {
-               my ($bottom, $top) = split "-", $range;
-               $top ||= $bottom;
-               my $bottom_commit = $gs->find_rev_after( $bottom, 1, $top );
-               my $top_commit = $gs->find_rev_before( $top, 1, $bottom );
-
-               unless ($top_commit and $bottom_commit) {
-                       warn "W:unknown path/rev in svn:mergeinfo "
-                               ."dirprop: $source:$range\n";
-                       next;
-               }
-
-               if (scalar(command('rev-parse', "$bottom_commit^@"))) {
-                       push @merged_commit_ranges,
-                            "$bottom_commit^..$top_commit";
-               } else {
-                       push @merged_commit_ranges, "$top_commit";
-               }
-
-               if ( !defined $tip or $top > $tip ) {
-                       $tip = $top;
-                       $tip_commit = $top_commit;
-               }
-       }
-       return ($tip_commit, @merged_commit_ranges);
-}
-
-sub _rev_list {
-       my ($msg_fh, $ctx) = command_output_pipe(
-               "rev-list", @_,
-              );
-       my @rv;
-       while ( <$msg_fh> ) {
-               chomp;
-               push @rv, $_;
-       }
-       command_close_pipe($msg_fh, $ctx);
-       @rv;
-}
-
-sub check_cherry_pick {
-       my $base = shift;
-       my $tip = shift;
-       my $parents = shift;
-       my @ranges = @_;
-       my %commits = map { $_ => 1 }
-               _rev_list("--no-merges", $tip, "--not", $base, @$parents, "--");
-       for my $range ( @ranges ) {
-               delete @commits{_rev_list($range, "--")};
-       }
-       for my $commit (keys %commits) {
-               if (has_no_changes($commit)) {
-                       delete $commits{$commit};
-               }
-       }
-       return (keys %commits);
-}
-
-sub has_no_changes {
-       my $commit = shift;
-
-       my @revs = split / /, command_oneline(
-               qw(rev-list --parents -1 -m), $commit);
-
-       # Commits with no parents, e.g. the start of a partial branch,
-       # have changes by definition.
-       return 1 if (@revs < 2);
-
-       # Commits with multiple parents, e.g a merge, have no changes
-       # by definition.
-       return 0 if (@revs > 2);
-
-       return (command_oneline("rev-parse", "$commit^{tree}") eq
-               command_oneline("rev-parse", "$commit~1^{tree}"));
-}
-
-sub tie_for_persistent_memoization {
-       my $hash = shift;
-       my $path = shift;
-
-       if ($can_use_yaml) {
-               tie %$hash => 'Git::SVN::Memoize::YAML', "$path.yaml";
-       } else {
-               tie %$hash => 'Memoize::Storable', "$path.db", 'nstore';
-       }
-}
-
-# The GIT_DIR environment variable is not always set until after the command
-# line arguments are processed, so we can't memoize in a BEGIN block.
-{
-       my $memoized = 0;
-
-       sub memoize_svn_mergeinfo_functions {
-               return if $memoized;
-               $memoized = 1;
-
-               my $cache_path = "$ENV{GIT_DIR}/svn/.caches/";
-               mkpath([$cache_path]) unless -d $cache_path;
-
-               my %lookup_svn_merge_cache;
-               my %check_cherry_pick_cache;
-               my %has_no_changes_cache;
-
-               tie_for_persistent_memoization(\%lookup_svn_merge_cache,
-                   "$cache_path/lookup_svn_merge");
-               memoize 'lookup_svn_merge',
-                       SCALAR_CACHE => 'FAULT',
-                       LIST_CACHE => ['HASH' => \%lookup_svn_merge_cache],
-               ;
-
-               tie_for_persistent_memoization(\%check_cherry_pick_cache,
-                   "$cache_path/check_cherry_pick");
-               memoize 'check_cherry_pick',
-                       SCALAR_CACHE => 'FAULT',
-                       LIST_CACHE => ['HASH' => \%check_cherry_pick_cache],
-               ;
-
-               tie_for_persistent_memoization(\%has_no_changes_cache,
-                   "$cache_path/has_no_changes");
-               memoize 'has_no_changes',
-                       SCALAR_CACHE => ['HASH' => \%has_no_changes_cache],
-                       LIST_CACHE => 'FAULT',
-               ;
-       }
-
-       sub unmemoize_svn_mergeinfo_functions {
-               return if not $memoized;
-               $memoized = 0;
-
-               Memoize::unmemoize 'lookup_svn_merge';
-               Memoize::unmemoize 'check_cherry_pick';
-               Memoize::unmemoize 'has_no_changes';
-       }
-
-       Memoize::memoize 'Git::SVN::repos_root';
-}
-
-END {
-       # Force cache writeout explicitly instead of waiting for
-       # global destruction to avoid segfault in Storable:
-       # http://rt.cpan.org/Public/Bug/Display.html?id=36087
-       unmemoize_svn_mergeinfo_functions();
-}
-
-sub parents_exclude {
-       my $parents = shift;
-       my @commits = @_;
-       return unless @commits;
-
-       my @excluded;
-       my $excluded;
-       do {
-               my @cmd = ('rev-list', "-1", @commits, "--not", @$parents );
-               $excluded = command_oneline(@cmd);
-               if ( $excluded ) {
-                       my @new;
-                       my $found;
-                       for my $commit ( @commits ) {
-                               if ( $commit eq $excluded ) {
-                                       push @excluded, $commit;
-                                       $found++;
-                                       last;
-                               }
-                               else {
-                                       push @new, $commit;
-                               }
-                       }
-                       die "saw commit '$excluded' in rev-list output, "
-                               ."but we didn't ask for that commit (wanted: @commits --not @$parents)"
-                                       unless $found;
-                       @commits = @new;
-               }
-       }
-               while ($excluded and @commits);
-
-       return @excluded;
-}
-
-
-# note: this function should only be called if the various dirprops
-# have actually changed
-sub find_extra_svn_parents {
-       my ($self, $ed, $mergeinfo, $parents) = @_;
-       # aha!  svk:merge property changed...
-
-       memoize_svn_mergeinfo_functions();
-
-       # We first search for merged tips which are not in our
-       # history.  Then, we figure out which git revisions are in
-       # that tip, but not this revision.  If all of those revisions
-       # are now marked as merge, we can add the tip as a parent.
-       my @merges = split "\n", $mergeinfo;
-       my @merge_tips;
-       my $url = $self->{url};
-       my $uuid = $self->ra_uuid;
-       my %ranges;
-       for my $merge ( @merges ) {
-               my ($tip_commit, @ranges) =
-                       lookup_svn_merge( $uuid, $url, $merge );
-               unless (!$tip_commit or
-                               grep { $_ eq $tip_commit } @$parents ) {
-                       push @merge_tips, $tip_commit;
-                       $ranges{$tip_commit} = \@ranges;
-               } else {
-                       push @merge_tips, undef;
-               }
-       }
-
-       my %excluded = map { $_ => 1 }
-               parents_exclude($parents, grep { defined } @merge_tips);
-
-       # check merge tips for new parents
-       my @new_parents;
-       for my $merge_tip ( @merge_tips ) {
-               my $spec = shift @merges;
-               next unless $merge_tip and $excluded{$merge_tip};
-
-               my $ranges = $ranges{$merge_tip};
-
-               # check out 'new' tips
-               my $merge_base;
-               eval {
-                       $merge_base = command_oneline(
-                               "merge-base",
-                               @$parents, $merge_tip,
-                       );
-               };
-               if ($@) {
-                       die "An error occurred during merge-base"
-                               unless $@->isa("Git::Error::Command");
-
-                       warn "W: Cannot find common ancestor between ".
-                            "@$parents and $merge_tip. Ignoring merge info.\n";
-                       next;
-               }
-
-               # double check that there are no missing non-merge commits
-               my (@incomplete) = check_cherry_pick(
-                       $merge_base, $merge_tip,
-                       $parents,
-                       @$ranges,
-                      );
-
-               if ( @incomplete ) {
-                       warn "W:svn cherry-pick ignored ($spec) - missing "
-                               .@incomplete." commit(s) (eg $incomplete[0])\n";
-               } else {
-                       warn
-                               "Found merge parent (svn:mergeinfo prop): ",
-                                       $merge_tip, "\n";
-                       push @new_parents, $merge_tip;
-               }
-       }
-
-       # cater for merges which merge commits from multiple branches
-       if ( @new_parents > 1 ) {
-               for ( my $i = 0; $i <= $#new_parents; $i++ ) {
-                       for ( my $j = 0; $j <= $#new_parents; $j++ ) {
-                               next if $i == $j;
-                               next unless $new_parents[$i];
-                               next unless $new_parents[$j];
-                               my $revs = command_oneline(
-                                       "rev-list", "-1",
-                                       "$new_parents[$i]..$new_parents[$j]",
-                                      );
-                               if ( !$revs ) {
-                                       undef($new_parents[$j]);
-                               }
-                       }
-               }
-       }
-       push @$parents, grep { defined } @new_parents;
-}
-
-sub make_log_entry {
-       my ($self, $rev, $parents, $ed) = @_;
-       my $untracked = $self->get_untracked($ed);
-
-       my @parents = @$parents;
-       my $ps = $ed->{path_strip} || "";
-       for my $path ( grep { m/$ps/ } %{$ed->{dir_prop}} ) {
-               my $props = $ed->{dir_prop}{$path};
-               if ( $props->{"svk:merge"} ) {
-                       $self->find_extra_svk_parents
-                               ($ed, $props->{"svk:merge"}, \@parents);
-               }
-               if ( $props->{"svn:mergeinfo"} ) {
-                       $self->find_extra_svn_parents
-                               ($ed,
-                                $props->{"svn:mergeinfo"},
-                                \@parents);
-               }
-       }
-
-       open my $un, '>>', "$self->{dir}/unhandled.log" or croak $!;
-       print $un "r$rev\n" or croak $!;
-       print $un $_, "\n" foreach @$untracked;
-       my %log_entry = ( parents => \@parents, revision => $rev,
-                         log => '');
-
-       my $headrev;
-       my $logged = delete $self->{logged_rev_props};
-       if (!$logged || $self->{-want_revprops}) {
-               my $rp = $self->ra->rev_proplist($rev);
-               foreach (sort keys %$rp) {
-                       my $v = $rp->{$_};
-                       if (/^svn:(author|date|log)$/) {
-                               $log_entry{$1} = $v;
-                       } elsif ($_ eq 'svm:headrev') {
-                               $headrev = $v;
-                       } else {
-                               print $un "  rev_prop: ", uri_encode($_), ' ',
-                                         uri_encode($v), "\n";
-                       }
-               }
-       } else {
-               map { $log_entry{$_} = $logged->{$_} } keys %$logged;
-       }
-       close $un or croak $!;
-
-       $log_entry{date} = parse_svn_date($log_entry{date});
-       $log_entry{log} .= "\n";
-       my $author = $log_entry{author} = check_author($log_entry{author});
-       my ($name, $email) = defined $::users{$author} ? @{$::users{$author}}
-                                                      : ($author, undef);
-
-       my ($commit_name, $commit_email) = ($name, $email);
-       if ($_use_log_author) {
-               my $name_field;
-               if ($log_entry{log} =~ /From:\s+(.*\S)\s*\n/i) {
-                       $name_field = $1;
-               } elsif ($log_entry{log} =~ /Signed-off-by:\s+(.*\S)\s*\n/i) {
-                       $name_field = $1;
-               }
-               if (!defined $name_field) {
-                       if (!defined $email) {
-                               $email = $name;
-                       }
-               } elsif ($name_field =~ /(.*?)\s+<(.*)>/) {
-                       ($name, $email) = ($1, $2);
-               } elsif ($name_field =~ /(.*)@/) {
-                       ($name, $email) = ($1, $name_field);
-               } else {
-                       ($name, $email) = ($name_field, $name_field);
-               }
-       }
-       if (defined $headrev && $self->use_svm_props) {
-               if ($self->rewrite_root) {
-                       die "Can't have both 'useSvmProps' and 'rewriteRoot' ",
-                           "options set!\n";
-               }
-               if ($self->rewrite_uuid) {
-                       die "Can't have both 'useSvmProps' and 'rewriteUUID' ",
-                           "options set!\n";
-               }
-               my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$}i;
-               # we don't want "SVM: initializing mirror for junk" ...
-               return undef if $r == 0;
-               my $svm = $self->svm;
-               if ($uuid ne $svm->{uuid}) {
-                       die "UUID mismatch on SVM path:\n",
-                           "expected: $svm->{uuid}\n",
-                           "     got: $uuid\n";
-               }
-               my $full_url = $self->full_url;
-               $full_url =~ s#^\Q$svm->{replace}\E(/|$)#$svm->{source}$1# or
-                            die "Failed to replace '$svm->{replace}' with ",
-                                "'$svm->{source}' in $full_url\n";
-               # throw away username for storing in records
-               remove_username($full_url);
-               $log_entry{metadata} = "$full_url\@$r $uuid";
-               $log_entry{svm_revision} = $r;
-               $email ||= "$author\@$uuid";
-               $commit_email ||= "$author\@$uuid";
-       } elsif ($self->use_svnsync_props) {
-               my $full_url = $self->svnsync->{url};
-               $full_url .= "/$self->{path}" if length $self->{path};
-               remove_username($full_url);
-               my $uuid = $self->svnsync->{uuid};
-               $log_entry{metadata} = "$full_url\@$rev $uuid";
-               $email ||= "$author\@$uuid";
-               $commit_email ||= "$author\@$uuid";
-       } else {
-               my $url = $self->metadata_url;
-               remove_username($url);
-               my $uuid = $self->rewrite_uuid || $self->ra->get_uuid;
-               $log_entry{metadata} = "$url\@$rev " . $uuid;
-               $email ||= "$author\@" . $uuid;
-               $commit_email ||= "$author\@" . $uuid;
-       }
-       $log_entry{name} = $name;
-       $log_entry{email} = $email;
-       $log_entry{commit_name} = $commit_name;
-       $log_entry{commit_email} = $commit_email;
-       \%log_entry;
-}
-
-sub fetch {
-       my ($self, $min_rev, $max_rev, @parents) = @_;
-       my ($last_rev, $last_commit) = $self->last_rev_commit;
-       my ($base, $head) = $self->get_fetch_range($min_rev, $max_rev);
-       $self->ra->gs_fetch_loop_common($base, $head, [$self]);
-}
-
-sub set_tree_cb {
-       my ($self, $log_entry, $tree, $rev, $date, $author) = @_;
-       $self->{inject_parents} = { $rev => $tree };
-       $self->fetch(undef, undef);
-}
-
-sub set_tree {
-       my ($self, $tree) = (shift, shift);
-       my $log_entry = ::get_commit_entry($tree);
-       unless ($self->{last_rev}) {
-               ::fatal("Must have an existing revision to commit");
-       }
-       my %ed_opts = ( r => $self->{last_rev},
-                       log => $log_entry->{log},
-                       ra => $self->ra,
-                       tree_a => $self->{last_commit},
-                       tree_b => $tree,
-                       editor_cb => sub {
-                              $self->set_tree_cb($log_entry, $tree, @_) },
-                       svn_path => $self->{path} );
-       if (!Git::SVN::Editor->new(\%ed_opts)->apply_diff) {
-               print "No changes\nr$self->{last_rev} = $tree\n";
-       }
-}
-
-sub rebuild_from_rev_db {
-       my ($self, $path) = @_;
-       my $r = -1;
-       open my $fh, '<', $path or croak "open: $!";
-       binmode $fh or croak "binmode: $!";
-       while (<$fh>) {
-               length($_) == 41 or croak "inconsistent size in ($_) != 41";
-               chomp($_);
-               ++$r;
-               next if $_ eq ('0' x 40);
-               $self->rev_map_set($r, $_);
-               print "r$r = $_\n";
-       }
-       close $fh or croak "close: $!";
-       unlink $path or croak "unlink: $!";
-}
-
-sub rebuild {
-       my ($self) = @_;
-       my $map_path = $self->map_path;
-       my $partial = (-e $map_path && ! -z $map_path);
-       return unless ::verify_ref($self->refname.'^0');
-       if (!$partial && ($self->use_svm_props || $self->no_metadata)) {
-               my $rev_db = $self->rev_db_path;
-               $self->rebuild_from_rev_db($rev_db);
-               if ($self->use_svm_props) {
-                       my $svm_rev_db = $self->rev_db_path($self->svm_uuid);
-                       $self->rebuild_from_rev_db($svm_rev_db);
-               }
-               $self->unlink_rev_db_symlink;
-               return;
-       }
-       print "Rebuilding $map_path ...\n" if (!$partial);
-       my ($base_rev, $head) = ($partial ? $self->rev_map_max_norebuild(1) :
-               (undef, undef));
-       my ($log, $ctx) =
-           command_output_pipe(qw/rev-list --pretty=raw --reverse/,
-                               ($head ? "$head.." : "") . $self->refname,
-                               '--');
-       my $metadata_url = $self->metadata_url;
-       remove_username($metadata_url);
-       my $svn_uuid = $self->rewrite_uuid || $self->ra_uuid;
-       my $c;
-       while (<$log>) {
-               if ( m{^commit ($::sha1)$} ) {
-                       $c = $1;
-                       next;
-               }
-               next unless s{^\s*(git-svn-id:)}{$1};
-               my ($url, $rev, $uuid) = ::extract_metadata($_);
-               remove_username($url);
-
-               # ignore merges (from set-tree)
-               next if (!defined $rev || !$uuid);
-
-               # if we merged or otherwise started elsewhere, this is
-               # how we break out of it
-               if (($uuid ne $svn_uuid) ||
-                   ($metadata_url && $url && ($url ne $metadata_url))) {
-                       next;
-               }
-               if ($partial && $head) {
-                       print "Partial-rebuilding $map_path ...\n";
-                       print "Currently at $base_rev = $head\n";
-                       $head = undef;
-               }
-
-               $self->rev_map_set($rev, $c);
-               print "r$rev = $c\n";
-       }
-       command_close_pipe($log, $ctx);
-       print "Done rebuilding $map_path\n" if (!$partial || !$head);
-       my $rev_db_path = $self->rev_db_path;
-       if (-f $self->rev_db_path) {
-               unlink $self->rev_db_path or croak "unlink: $!";
-       }
-       $self->unlink_rev_db_symlink;
-}
-
-# rev_map:
-# Tie::File seems to be prone to offset errors if revisions get sparse,
-# it's not that fast, either.  Tie::File is also not in Perl 5.6.  So
-# one of my favorite modules is out :<  Next up would be one of the DBM
-# modules, but I'm not sure which is most portable...
-#
-# This is the replacement for the rev_db format, which was too big
-# and inefficient for large repositories with a lot of sparse history
-# (mainly tags)
-#
-# The format is this:
-#   - 24 bytes for every record,
-#     * 4 bytes for the integer representing an SVN revision number
-#     * 20 bytes representing the sha1 of a git commit
-#   - No empty padding records like the old format
-#     (except the last record, which can be overwritten)
-#   - new records are written append-only since SVN revision numbers
-#     increase monotonically
-#   - lookups on SVN revision number are done via a binary search
-#   - Piping the file to xxd -c24 is a good way of dumping it for
-#     viewing or editing (piped back through xxd -r), should the need
-#     ever arise.
-#   - The last record can be padding revision with an all-zero sha1
-#     This is used to optimize fetch performance when using multiple
-#     "fetch" directives in .git/config
-#
-# These files are disposable unless noMetadata or useSvmProps is set
-
-sub _rev_map_set {
-       my ($fh, $rev, $commit) = @_;
-
-       binmode $fh or croak "binmode: $!";
-       my $size = (stat($fh))[7];
-       ($size % 24) == 0 or croak "inconsistent size: $size";
-
-       my $wr_offset = 0;
-       if ($size > 0) {
-               sysseek($fh, -24, SEEK_END) or croak "seek: $!";
-               my $read = sysread($fh, my $buf, 24) or croak "read: $!";
-               $read == 24 or croak "read only $read bytes (!= 24)";
-               my ($last_rev, $last_commit) = unpack(rev_map_fmt, $buf);
-               if ($last_commit eq ('0' x40)) {
-                       if ($size >= 48) {
-                               sysseek($fh, -48, SEEK_END) or croak "seek: $!";
-                               $read = sysread($fh, $buf, 24) or
-                                   croak "read: $!";
-                               $read == 24 or
-                                   croak "read only $read bytes (!= 24)";
-                               ($last_rev, $last_commit) =
-                                   unpack(rev_map_fmt, $buf);
-                               if ($last_commit eq ('0' x40)) {
-                                       croak "inconsistent .rev_map\n";
-                               }
-                       }
-                       if ($last_rev >= $rev) {
-                               croak "last_rev is higher!: $last_rev >= $rev";
-                       }
-                       $wr_offset = -24;
-               }
-       }
-       sysseek($fh, $wr_offset, SEEK_END) or croak "seek: $!";
-       syswrite($fh, pack(rev_map_fmt, $rev, $commit), 24) == 24 or
-         croak "write: $!";
-}
-
-sub _rev_map_reset {
-       my ($fh, $rev, $commit) = @_;
-       my $c = _rev_map_get($fh, $rev);
-       $c eq $commit or die "_rev_map_reset(@_) commit $c does not match!\n";
-       my $offset = sysseek($fh, 0, SEEK_CUR) or croak "seek: $!";
-       truncate $fh, $offset or croak "truncate: $!";
-}
-
-sub mkfile {
-       my ($path) = @_;
-       unless (-e $path) {
-               my ($dir, $base) = ($path =~ m#^(.*?)/?([^/]+)$#);
-               mkpath([$dir]) unless -d $dir;
-               open my $fh, '>>', $path or die "Couldn't create $path: $!\n";
-               close $fh or die "Couldn't close (create) $path: $!\n";
-       }
-}
-
-sub rev_map_set {
-       my ($self, $rev, $commit, $update_ref, $uuid) = @_;
-       defined $commit or die "missing arg3\n";
-       length $commit == 40 or die "arg3 must be a full SHA1 hexsum\n";
-       my $db = $self->map_path($uuid);
-       my $db_lock = "$db.lock";
-       my $sigmask;
-       $update_ref ||= 0;
-       if ($update_ref) {
-               $sigmask = POSIX::SigSet->new();
-               my $signew = POSIX::SigSet->new(SIGINT, SIGHUP, SIGTERM,
-                       SIGALRM, SIGUSR1, SIGUSR2);
-               sigprocmask(SIG_BLOCK, $signew, $sigmask) or
-                       croak "Can't block signals: $!";
-       }
-       mkfile($db);
-
-       $LOCKFILES{$db_lock} = 1;
-       my $sync;
-       # both of these options make our .rev_db file very, very important
-       # and we can't afford to lose it because rebuild() won't work
-       if ($self->use_svm_props || $self->no_metadata) {
-               $sync = 1;
-               copy($db, $db_lock) or die "rev_map_set(@_): ",
-                                          "Failed to copy: ",
-                                          "$db => $db_lock ($!)\n";
-       } else {
-               rename $db, $db_lock or die "rev_map_set(@_): ",
-                                           "Failed to rename: ",
-                                           "$db => $db_lock ($!)\n";
-       }
-
-       sysopen(my $fh, $db_lock, O_RDWR | O_CREAT)
-            or croak "Couldn't open $db_lock: $!\n";
-       $update_ref eq 'reset' ? _rev_map_reset($fh, $rev, $commit) :
-                                _rev_map_set($fh, $rev, $commit);
-       if ($sync) {
-               $fh->flush or die "Couldn't flush $db_lock: $!\n";
-               $fh->sync or die "Couldn't sync $db_lock: $!\n";
-       }
-       close $fh or croak $!;
-       if ($update_ref) {
-               $_head = $self;
-               my $note = "";
-               $note = " ($update_ref)" if ($update_ref !~ /^\d*$/);
-               command_noisy('update-ref', '-m', "r$rev$note",
-                             $self->refname, $commit);
-       }
-       rename $db_lock, $db or die "rev_map_set(@_): ", "Failed to rename: ",
-                                   "$db_lock => $db ($!)\n";
-       delete $LOCKFILES{$db_lock};
-       if ($update_ref) {
-               sigprocmask(SIG_SETMASK, $sigmask) or
-                       croak "Can't restore signal mask: $!";
-       }
-}
-
-# If want_commit, this will return an array of (rev, commit) where
-# commit _must_ be a valid commit in the archive.
-# Otherwise, it'll return the max revision (whether or not the
-# commit is valid or just a 0x40 placeholder).
-sub rev_map_max {
-       my ($self, $want_commit) = @_;
-       $self->rebuild;
-       my ($r, $c) = $self->rev_map_max_norebuild($want_commit);
-       $want_commit ? ($r, $c) : $r;
-}
-
-sub rev_map_max_norebuild {
-       my ($self, $want_commit) = @_;
-       my $map_path = $self->map_path;
-       stat $map_path or return $want_commit ? (0, undef) : 0;
-       sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
-       binmode $fh or croak "binmode: $!";
-       my $size = (stat($fh))[7];
-       ($size % 24) == 0 or croak "inconsistent size: $size";
-
-       if ($size == 0) {
-               close $fh or croak "close: $!";
-               return $want_commit ? (0, undef) : 0;
-       }
-
-       sysseek($fh, -24, SEEK_END) or croak "seek: $!";
-       sysread($fh, my $buf, 24) == 24 or croak "read: $!";
-       my ($r, $c) = unpack(rev_map_fmt, $buf);
-       if ($want_commit && $c eq ('0' x40)) {
-               if ($size < 48) {
-                       return $want_commit ? (0, undef) : 0;
-               }
-               sysseek($fh, -48, SEEK_END) or croak "seek: $!";
-               sysread($fh, $buf, 24) == 24 or croak "read: $!";
-               ($r, $c) = unpack(rev_map_fmt, $buf);
-               if ($c eq ('0'x40)) {
-                       croak "Penultimate record is all-zeroes in $map_path";
-               }
-       }
-       close $fh or croak "close: $!";
-       $want_commit ? ($r, $c) : $r;
-}
-
-sub rev_map_get {
-       my ($self, $rev, $uuid) = @_;
-       my $map_path = $self->map_path($uuid);
-       return undef unless -e $map_path;
-
-       sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
-       my $c = _rev_map_get($fh, $rev);
-       close($fh) or croak "close: $!";
-       $c
-}
-
-sub _rev_map_get {
-       my ($fh, $rev) = @_;
-
-       binmode $fh or croak "binmode: $!";
-       my $size = (stat($fh))[7];
-       ($size % 24) == 0 or croak "inconsistent size: $size";
-
-       if ($size == 0) {
-               return undef;
-       }
-
-       my ($l, $u) = (0, $size - 24);
-       my ($r, $c, $buf);
-
-       while ($l <= $u) {
-               my $i = int(($l/24 + $u/24) / 2) * 24;
-               sysseek($fh, $i, SEEK_SET) or croak "seek: $!";
-               sysread($fh, my $buf, 24) == 24 or croak "read: $!";
-               my ($r, $c) = unpack(rev_map_fmt, $buf);
-
-               if ($r < $rev) {
-                       $l = $i + 24;
-               } elsif ($r > $rev) {
-                       $u = $i - 24;
-               } else { # $r == $rev
-                       return $c eq ('0' x 40) ? undef : $c;
-               }
-       }
-       undef;
-}
-
-# Finds the first svn revision that exists on (if $eq_ok is true) or
-# before $rev for the current branch.  It will not search any lower
-# than $min_rev.  Returns the git commit hash and svn revision number
-# if found, else (undef, undef).
-sub find_rev_before {
-       my ($self, $rev, $eq_ok, $min_rev) = @_;
-       --$rev unless $eq_ok;
-       $min_rev ||= 1;
-       my $max_rev = $self->rev_map_max;
-       $rev = $max_rev if ($rev > $max_rev);
-       while ($rev >= $min_rev) {
-               if (my $c = $self->rev_map_get($rev)) {
-                       return ($rev, $c);
-               }
-               --$rev;
-       }
-       return (undef, undef);
-}
-
-# Finds the first svn revision that exists on (if $eq_ok is true) or
-# after $rev for the current branch.  It will not search any higher
-# than $max_rev.  Returns the git commit hash and svn revision number
-# if found, else (undef, undef).
-sub find_rev_after {
-       my ($self, $rev, $eq_ok, $max_rev) = @_;
-       ++$rev unless $eq_ok;
-       $max_rev ||= $self->rev_map_max;
-       while ($rev <= $max_rev) {
-               if (my $c = $self->rev_map_get($rev)) {
-                       return ($rev, $c);
-               }
-               ++$rev;
-       }
-       return (undef, undef);
-}
-
-sub _new {
-       my ($class, $repo_id, $ref_id, $path) = @_;
-       unless (defined $repo_id && length $repo_id) {
-               $repo_id = $Git::SVN::default_repo_id;
-       }
-       unless (defined $ref_id && length $ref_id) {
-               $_prefix = '' unless defined($_prefix);
-               $_[2] = $ref_id =
-                            "refs/remotes/$_prefix$Git::SVN::default_ref_id";
-       }
-       $_[1] = $repo_id;
-       my $dir = "$ENV{GIT_DIR}/svn/$ref_id";
-
-       # Older repos imported by us used $GIT_DIR/svn/foo instead of
-       # $GIT_DIR/svn/refs/remotes/foo when tracking refs/remotes/foo
-       if ($ref_id =~ m{^refs/remotes/(.*)}) {
-               my $old_dir = "$ENV{GIT_DIR}/svn/$1";
-               if (-d $old_dir && ! -d $dir) {
-                       $dir = $old_dir;
-               }
-       }
-
-       $_[3] = $path = '' unless (defined $path);
-       mkpath([$dir]);
-       bless {
-               ref_id => $ref_id, dir => $dir, index => "$dir/index",
-               path => $path, config => "$ENV{GIT_DIR}/svn/config",
-               map_root => "$dir/.rev_map", repo_id => $repo_id }, $class;
-}
-
-# for read-only access of old .rev_db formats
-sub unlink_rev_db_symlink {
-       my ($self) = @_;
-       my $link = $self->rev_db_path;
-       $link =~ s/\.[\w-]+$// or croak "missing UUID at the end of $link";
-       if (-l $link) {
-               unlink $link or croak "unlink: $link failed!";
-       }
-}
-
-sub rev_db_path {
-       my ($self, $uuid) = @_;
-       my $db_path = $self->map_path($uuid);
-       $db_path =~ s{/\.rev_map\.}{/\.rev_db\.}
-           or croak "map_path: $db_path does not contain '/.rev_map.' !";
-       $db_path;
-}
-
-# the new replacement for .rev_db
-sub map_path {
-       my ($self, $uuid) = @_;
-       $uuid ||= $self->ra_uuid;
-       "$self->{map_root}.$uuid";
-}
-
-sub uri_encode {
-       my ($f) = @_;
-       $f =~ s#([^a-zA-Z0-9\*!\:_\./\-])#uc sprintf("%%%02x",ord($1))#eg;
-       $f
-}
-
-sub uri_decode {
-       my ($f) = @_;
-       $f =~ s#%([0-9a-fA-F]{2})#chr(hex($1))#eg;
-       $f
-}
-
-sub remove_username {
-       $_[0] =~ s{^([^:]*://)[^@]+@}{$1};
-}
-
-package Git::SVN::Log;
-use strict;
-use warnings;
-use POSIX qw/strftime/;
-use constant commit_log_separator => ('-' x 72) . "\n";
-use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
-            %rusers $show_commit $incremental/;
-my $l_fmt;
-
-sub cmt_showable {
-       my ($c) = @_;
-       return 1 if defined $c->{r};
-
-       # big commit message got truncated by the 16k pretty buffer in rev-list
-       if ($c->{l} && $c->{l}->[-1] eq "...\n" &&
-                               $c->{a_raw} =~ /\@([a-f\d\-]+)>$/) {
-               @{$c->{l}} = ();
-               my @log = command(qw/cat-file commit/, $c->{c});
-
-               # shift off the headers
-               shift @log while ($log[0] ne '');
-               shift @log;
-
-               # TODO: make $c->{l} not have a trailing newline in the future
-               @{$c->{l}} = map { "$_\n" } grep !/^git-svn-id: /, @log;
-
-               (undef, $c->{r}, undef) = ::extract_metadata(
-                               (grep(/^git-svn-id: /, @log))[-1]);
-       }
-       return defined $c->{r};
-}
-
-sub log_use_color {
-       return $color || Git->repository->get_colorbool('color.diff');
-}
-
-sub git_svn_log_cmd {
-       my ($r_min, $r_max, @args) = @_;
-       my $head = 'HEAD';
-       my (@files, @log_opts);
-       foreach my $x (@args) {
-               if ($x eq '--' || @files) {
-                       push @files, $x;
-               } else {
-                       if (::verify_ref("$x^0")) {
-                               $head = $x;
-                       } else {
-                               push @log_opts, $x;
-                       }
-               }
-       }
-
-       my ($url, $rev, $uuid, $gs) = ::working_head_info($head);
-       $gs ||= Git::SVN->_new;
-       my @cmd = (qw/log --abbrev-commit --pretty=raw --default/,
-                  $gs->refname);
-       push @cmd, '-r' unless $non_recursive;
-       push @cmd, qw/--raw --name-status/ if $verbose;
-       push @cmd, '--color' if log_use_color();
-       push @cmd, @log_opts;
-       if (defined $r_max && $r_max == $r_min) {
-               push @cmd, '--max-count=1';
-               if (my $c = $gs->rev_map_get($r_max)) {
-                       push @cmd, $c;
-               }
-       } elsif (defined $r_max) {
-               if ($r_max < $r_min) {
-                       ($r_min, $r_max) = ($r_max, $r_min);
-               }
-               my (undef, $c_max) = $gs->find_rev_before($r_max, 1, $r_min);
-               my (undef, $c_min) = $gs->find_rev_after($r_min, 1, $r_max);
-               # If there are no commits in the range, both $c_max and $c_min
-               # will be undefined.  If there is at least 1 commit in the
-               # range, both will be defined.
-               return () if !defined $c_min || !defined $c_max;
-               if ($c_min eq $c_max) {
-                       push @cmd, '--max-count=1', $c_min;
-               } else {
-                       push @cmd, '--boundary', "$c_min..$c_max";
-               }
-       }
-       return (@cmd, @files);
-}
-
-# adapted from pager.c
-sub config_pager {
-       if (! -t *STDOUT) {
-               $ENV{GIT_PAGER_IN_USE} = 'false';
-               $pager = undef;
-               return;
-       }
-       chomp($pager = command_oneline(qw(var GIT_PAGER)));
-       if ($pager eq 'cat') {
-               $pager = undef;
-       }
-       $ENV{GIT_PAGER_IN_USE} = defined($pager);
-}
-
-sub run_pager {
-       return unless defined $pager;
-       pipe my ($rfd, $wfd) or return;
-       defined(my $pid = fork) or ::fatal "Can't fork: $!";
-       if (!$pid) {
-               open STDOUT, '>&', $wfd or
-                                    ::fatal "Can't redirect to stdout: $!";
-               return;
-       }
-       open STDIN, '<&', $rfd or ::fatal "Can't redirect stdin: $!";
-       $ENV{LESS} ||= 'FRSX';
-       exec $pager or ::fatal "Can't run pager: $! ($pager)";
-}
-
-sub format_svn_date {
-       my $t = shift || time;
-       my $gmoff = Git::SVN::get_tz($t);
-       return strftime("%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)", localtime($t));
-}
-
-sub parse_git_date {
-       my ($t, $tz) = @_;
-       # Date::Parse isn't in the standard Perl distro :(
-       if ($tz =~ s/^\+//) {
-               $t += tz_to_s_offset($tz);
-       } elsif ($tz =~ s/^\-//) {
-               $t -= tz_to_s_offset($tz);
-       }
-       return $t;
-}
-
-sub set_local_timezone {
-       if (defined $TZ) {
-               $ENV{TZ} = $TZ;
-       } else {
-               delete $ENV{TZ};
-       }
-}
-
-sub tz_to_s_offset {
-       my ($tz) = @_;
-       $tz =~ s/(\d\d)$//;
-       return ($1 * 60) + ($tz * 3600);
-}
-
-sub get_author_info {
-       my ($dest, $author, $t, $tz) = @_;
-       $author =~ s/(?:^\s*|\s*$)//g;
-       $dest->{a_raw} = $author;
-       my $au;
-       if ($::_authors) {
-               $au = $rusers{$author} || undef;
-       }
-       if (!$au) {
-               ($au) = ($author =~ /<([^>]+)\@[^>]+>$/);
-       }
-       $dest->{t} = $t;
-       $dest->{tz} = $tz;
-       $dest->{a} = $au;
-       $dest->{t_utc} = parse_git_date($t, $tz);
-}
-
-sub process_commit {
-       my ($c, $r_min, $r_max, $defer) = @_;
-       if (defined $r_min && defined $r_max) {
-               if ($r_min == $c->{r} && $r_min == $r_max) {
-                       show_commit($c);
-                       return 0;
-               }
-               return 1 if $r_min == $r_max;
-               if ($r_min < $r_max) {
-                       # we need to reverse the print order
-                       return 0 if (defined $limit && --$limit < 0);
-                       push @$defer, $c;
-                       return 1;
-               }
-               if ($r_min != $r_max) {
-                       return 1 if ($r_min < $c->{r});
-                       return 1 if ($r_max > $c->{r});
-               }
-       }
-       return 0 if (defined $limit && --$limit < 0);
-       show_commit($c);
-       return 1;
-}
-
-sub show_commit {
-       my $c = shift;
-       if ($oneline) {
-               my $x = "\n";
-               if (my $l = $c->{l}) {
-                       while ($l->[0] =~ /^\s*$/) { shift @$l }
-                       $x = $l->[0];
-               }
-               $l_fmt ||= 'A' . length($c->{r});
-               print 'r',pack($l_fmt, $c->{r}),' | ';
-               print "$c->{c} | " if $show_commit;
-               print $x;
-       } else {
-               show_commit_normal($c);
-       }
-}
-
-sub show_commit_changed_paths {
-       my ($c) = @_;
-       return unless $c->{changed};
-       print "Changed paths:\n", @{$c->{changed}};
-}
-
-sub show_commit_normal {
-       my ($c) = @_;
-       print commit_log_separator, "r$c->{r} | ";
-       print "$c->{c} | " if $show_commit;
-       print "$c->{a} | ", format_svn_date($c->{t_utc}), ' | ';
-       my $nr_line = 0;
-
-       if (my $l = $c->{l}) {
-               while ($l->[$#$l] eq "\n" && $#$l > 0
-                                         && $l->[($#$l - 1)] eq "\n") {
-                       pop @$l;
-               }
-               $nr_line = scalar @$l;
-               if (!$nr_line) {
-                       print "1 line\n\n\n";
-               } else {
-                       if ($nr_line == 1) {
-                               $nr_line = '1 line';
-                       } else {
-                               $nr_line .= ' lines';
-                       }
-                       print $nr_line, "\n";
-                       show_commit_changed_paths($c);
-                       print "\n";
-                       print $_ foreach @$l;
-               }
-       } else {
-               print "1 line\n";
-               show_commit_changed_paths($c);
-               print "\n";
-
-       }
-       foreach my $x (qw/raw stat diff/) {
-               if ($c->{$x}) {
-                       print "\n";
-                       print $_ foreach @{$c->{$x}}
-               }
-       }
-}
-
-sub cmd_show_log {
-       my (@args) = @_;
-       my ($r_min, $r_max);
-       my $r_last = -1; # prevent dupes
-       set_local_timezone();
-       if (defined $::_revision) {
-               if ($::_revision =~ /^(\d+):(\d+)$/) {
-                       ($r_min, $r_max) = ($1, $2);
-               } elsif ($::_revision =~ /^\d+$/) {
-                       $r_min = $r_max = $::_revision;
-               } else {
-                       ::fatal "-r$::_revision is not supported, use ",
-                               "standard 'git log' arguments instead";
-               }
-       }
-
-       config_pager();
-       @args = git_svn_log_cmd($r_min, $r_max, @args);
-       if (!@args) {
-               print commit_log_separator unless $incremental || $oneline;
-               return;
-       }
-       my $log = command_output_pipe(@args);
-       run_pager();
-       my (@k, $c, $d, $stat);
-       my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
-       while (<$log>) {
-               if (/^${esc_color}commit (?:- )?($::sha1_short)/o) {
-                       my $cmt = $1;
-                       if ($c && cmt_showable($c) && $c->{r} != $r_last) {
-                               $r_last = $c->{r};
-                               process_commit($c, $r_min, $r_max, \@k) or
-                                                               goto out;
-                       }
-                       $d = undef;
-                       $c = { c => $cmt };
-               } elsif (/^${esc_color}author (.+) (\d+) ([\-\+]?\d+)$/o) {
-                       get_author_info($c, $1, $2, $3);
-               } elsif (/^${esc_color}(?:tree|parent|committer) /o) {
-                       # ignore
-               } elsif (/^${esc_color}:\d{6} \d{6} $::sha1_short/o) {
-                       push @{$c->{raw}}, $_;
-               } elsif (/^${esc_color}[ACRMDT]\t/) {
-                       # we could add $SVN->{svn_path} here, but that requires
-                       # remote access at the moment (repo_path_split)...
-                       s#^(${esc_color})([ACRMDT])\t#$1   $2 #o;
-                       push @{$c->{changed}}, $_;
-               } elsif (/^${esc_color}diff /o) {
-                       $d = 1;
-                       push @{$c->{diff}}, $_;
-               } elsif ($d) {
-                       push @{$c->{diff}}, $_;
-               } elsif (/^\ .+\ \|\s*\d+\ $esc_color[\+\-]*
-                         $esc_color*[\+\-]*$esc_color$/x) {
-                       $stat = 1;
-                       push @{$c->{stat}}, $_;
-               } elsif ($stat && /^ \d+ files changed, \d+ insertions/) {
-                       push @{$c->{stat}}, $_;
-                       $stat = undef;
-               } elsif (/^${esc_color}    (git-svn-id:.+)$/o) {
-                       ($c->{url}, $c->{r}, undef) = ::extract_metadata($1);
-               } elsif (s/^${esc_color}    //o) {
-                       push @{$c->{l}}, $_;
-               }
-       }
-       if ($c && defined $c->{r} && $c->{r} != $r_last) {
-               $r_last = $c->{r};
-               process_commit($c, $r_min, $r_max, \@k);
-       }
-       if (@k) {
-               ($r_min, $r_max) = ($r_max, $r_min);
-               process_commit($_, $r_min, $r_max) foreach reverse @k;
-       }
-out:
-       close $log;
-       print commit_log_separator unless $incremental || $oneline;
-}
-
-sub cmd_blame {
-       my $path = pop;
-
-       config_pager();
-       run_pager();
-
-       my ($fh, $ctx, $rev);
-
-       if ($_git_format) {
-               ($fh, $ctx) = command_output_pipe('blame', @_, $path);
-               while (my $line = <$fh>) {
-                       if ($line =~ /^\^?([[:xdigit:]]+)\s/) {
-                               # Uncommitted edits show up as a rev ID of
-                               # all zeros, which we can't look up with
-                               # cmt_metadata
-                               if ($1 !~ /^0+$/) {
-                                       (undef, $rev, undef) =
-                                               ::cmt_metadata($1);
-                                       $rev = '0' if (!$rev);
-                               } else {
-                                       $rev = '0';
-                               }
-                               $rev = sprintf('%-10s', $rev);
-                               $line =~ s/^\^?[[:xdigit:]]+(\s)/$rev$1/;
-                       }
-                       print $line;
-               }
-       } else {
-               ($fh, $ctx) = command_output_pipe('blame', '-p', @_, 'HEAD',
-                                                 '--', $path);
-               my ($sha1);
-               my %authors;
-               my @buffer;
-               my %dsha; #distinct sha keys
-
-               while (my $line = <$fh>) {
-                       push @buffer, $line;
-                       if ($line =~ /^([[:xdigit:]]{40})\s\d+\s\d+/) {
-                               $dsha{$1} = 1;
-                       }
-               }
-
-               my $s2r = ::cmt_sha2rev_batch([keys %dsha]);
-
-               foreach my $line (@buffer) {
-                       if ($line =~ /^([[:xdigit:]]{40})\s\d+\s\d+/) {
-                               $rev = $s2r->{$1};
-                               $rev = '0' if (!$rev)
-                       }
-                       elsif ($line =~ /^author (.*)/) {
-                               $authors{$rev} = $1;
-                               $authors{$rev} =~ s/\s/_/g;
-                       }
-                       elsif ($line =~ /^\t(.*)$/) {
-                               printf("%6s %10s %s\n", $rev, $authors{$rev}, $1);
-                       }
-               }
-       }
-       command_close_pipe($fh, $ctx);
-}
-
-package Git::SVN::Migration;
-# these version numbers do NOT correspond to actual version numbers
-# of git nor git-svn.  They are just relative.
-#
-# v0 layout: .git/$id/info/url, refs/heads/$id-HEAD
-#
-# v1 layout: .git/$id/info/url, refs/remotes/$id
-#
-# v2 layout: .git/svn/$id/info/url, refs/remotes/$id
-#
-# v3 layout: .git/svn/$id, refs/remotes/$id
-#            - info/url may remain for backwards compatibility
-#            - this is what we migrate up to this layout automatically,
-#            - this will be used by git svn init on single branches
-# v3.1 layout (auto migrated):
-#            - .rev_db => .rev_db.$UUID, .rev_db will remain as a symlink
-#              for backwards compatibility
-#
-# v4 layout: .git/svn/$repo_id/$id, refs/remotes/$repo_id/$id
-#            - this is only created for newly multi-init-ed
-#              repositories.  Similar in spirit to the
-#              --use-separate-remotes option in git-clone (now default)
-#            - we do not automatically migrate to this (following
-#              the example set by core git)
-#
-# v5 layout: .rev_db.$UUID => .rev_map.$UUID
-#            - newer, more-efficient format that uses 24-bytes per record
-#              with no filler space.
-#            - use xxd -c24 < .rev_map.$UUID to view and debug
-#            - This is a one-way migration, repositories updated to the
-#              new format will not be able to use old git-svn without
-#              rebuilding the .rev_db.  Rebuilding the rev_db is not
-#              possible if noMetadata or useSvmProps are set; but should
-#              be no problem for users that use the (sensible) defaults.
-use strict;
-use warnings;
-use Carp qw/croak/;
-use File::Path qw/mkpath/;
-use File::Basename qw/dirname basename/;
-use vars qw/$_minimize/;
-
-sub migrate_from_v0 {
-       my $git_dir = $ENV{GIT_DIR};
-       return undef unless -d $git_dir;
-       my ($fh, $ctx) = command_output_pipe(qw/rev-parse --symbolic --all/);
-       my $migrated = 0;
-       while (<$fh>) {
-               chomp;
-               my ($id, $orig_ref) = ($_, $_);
-               next unless $id =~ s#^refs/heads/(.+)-HEAD$#$1#;
-               next unless -f "$git_dir/$id/info/url";
-               my $new_ref = "refs/remotes/$id";
-               if (::verify_ref("$new_ref^0")) {
-                       print STDERR "W: $orig_ref is probably an old ",
-                                    "branch used by an ancient version of ",
-                                    "git-svn.\n",
-                                    "However, $new_ref also exists.\n",
-                                    "We will not be able ",
-                                    "to use this branch until this ",
-                                    "ambiguity is resolved.\n";
-                       next;
-               }
-               print STDERR "Migrating from v0 layout...\n" if !$migrated;
-               print STDERR "Renaming ref: $orig_ref => $new_ref\n";
-               command_noisy('update-ref', $new_ref, $orig_ref);
-               command_noisy('update-ref', '-d', $orig_ref, $orig_ref);
-               $migrated++;
-       }
-       command_close_pipe($fh, $ctx);
-       print STDERR "Done migrating from v0 layout...\n" if $migrated;
-       $migrated;
-}
-
-sub migrate_from_v1 {
-       my $git_dir = $ENV{GIT_DIR};
-       my $migrated = 0;
-       return $migrated unless -d $git_dir;
-       my $svn_dir = "$git_dir/svn";
-
-       # just in case somebody used 'svn' as their $id at some point...
-       return $migrated if -d $svn_dir && ! -f "$svn_dir/info/url";
-
-       print STDERR "Migrating from a git-svn v1 layout...\n";
-       mkpath([$svn_dir]);
-       print STDERR "Data from a previous version of git-svn exists, but\n\t",
-                    "$svn_dir\n\t(required for this version ",
-                    "($::VERSION) of git-svn) does not exist.\n";
-       my ($fh, $ctx) = command_output_pipe(qw/rev-parse --symbolic --all/);
-       while (<$fh>) {
-               my $x = $_;
-               next unless $x =~ s#^refs/remotes/##;
-               chomp $x;
-               next unless -f "$git_dir/$x/info/url";
-               my $u = eval { ::file_to_s("$git_dir/$x/info/url") };
-               next unless $u;
-               my $dn = dirname("$git_dir/svn/$x");
-               mkpath([$dn]) unless -d $dn;
-               if ($x eq 'svn') { # they used 'svn' as GIT_SVN_ID:
-                       mkpath(["$git_dir/svn/svn"]);
-                       print STDERR " - $git_dir/$x/info => ",
-                                       "$git_dir/svn/$x/info\n";
-                       rename "$git_dir/$x/info", "$git_dir/svn/$x/info" or
-                              croak "$!: $x";
-                       # don't worry too much about these, they probably
-                       # don't exist with repos this old (save for index,
-                       # and we can easily regenerate that)
-                       foreach my $f (qw/unhandled.log index .rev_db/) {
-                               rename "$git_dir/$x/$f", "$git_dir/svn/$x/$f";
-                       }
-               } else {
-                       print STDERR " - $git_dir/$x => $git_dir/svn/$x\n";
-                       rename "$git_dir/$x", "$git_dir/svn/$x" or
-                              croak "$!: $x";
-               }
-               $migrated++;
-       }
-       command_close_pipe($fh, $ctx);
-       print STDERR "Done migrating from a git-svn v1 layout\n";
-       $migrated;
-}
-
-sub read_old_urls {
-       my ($l_map, $pfx, $path) = @_;
-       my @dir;
-       foreach (<$path/*>) {
-               if (-r "$_/info/url") {
-                       $pfx .= '/' if $pfx && $pfx !~ m!/$!;
-                       my $ref_id = $pfx . basename $_;
-                       my $url = ::file_to_s("$_/info/url");
-                       $l_map->{$ref_id} = $url;
-               } elsif (-d $_) {
-                       push @dir, $_;
-               }
-       }
-       foreach (@dir) {
-               my $x = $_;
-               $x =~ s!^\Q$ENV{GIT_DIR}\E/svn/!!o;
-               read_old_urls($l_map, $x, $_);
-       }
-}
-
-sub migrate_from_v2 {
-       my @cfg = command(qw/config -l/);
-       return if grep /^svn-remote\..+\.url=/, @cfg;
-       my %l_map;
-       read_old_urls(\%l_map, '', "$ENV{GIT_DIR}/svn");
-       my $migrated = 0;
-
-       foreach my $ref_id (sort keys %l_map) {
-               eval { Git::SVN->init($l_map{$ref_id}, '', undef, $ref_id) };
-               if ($@) {
-                       Git::SVN->init($l_map{$ref_id}, '', $ref_id, $ref_id);
-               }
-               $migrated++;
-       }
-       $migrated;
-}
-
-sub minimize_connections {
-       my $r = Git::SVN::read_all_remotes();
-       my $new_urls = {};
-       my $root_repos = {};
-       foreach my $repo_id (keys %$r) {
-               my $url = $r->{$repo_id}->{url} or next;
-               my $fetch = $r->{$repo_id}->{fetch} or next;
-               my $ra = Git::SVN::Ra->new($url);
-
-               # skip existing cases where we already connect to the root
-               if (($ra->{url} eq $ra->{repos_root}) ||
-                   ($ra->{repos_root} eq $repo_id)) {
-                       $root_repos->{$ra->{url}} = $repo_id;
-                       next;
-               }
-
-               my $root_ra = Git::SVN::Ra->new($ra->{repos_root});
-               my $root_path = $ra->{url};
-               $root_path =~ s#^\Q$ra->{repos_root}\E(/|$)##;
-               foreach my $path (keys %$fetch) {
-                       my $ref_id = $fetch->{$path};
-                       my $gs = Git::SVN->new($ref_id, $repo_id, $path);
-
-                       # make sure we can read when connecting to
-                       # a higher level of a repository
-                       my ($last_rev, undef) = $gs->last_rev_commit;
-                       if (!defined $last_rev) {
-                               $last_rev = eval {
-                                       $root_ra->get_latest_revnum;
-                               };
-                               next if $@;
-                       }
-                       my $new = $root_path;
-                       $new .= length $path ? "/$path" : '';
-                       eval {
-                               $root_ra->get_log([$new], $last_rev, $last_rev,
-                                                 0, 0, 1, sub { });
-                       };
-                       next if $@;
-                       $new_urls->{$ra->{repos_root}}->{$new} =
-                               { ref_id => $ref_id,
-                                 old_repo_id => $repo_id,
-                                 old_path => $path };
-               }
-       }
-
-       my @emptied;
-       foreach my $url (keys %$new_urls) {
-               # see if we can re-use an existing [svn-remote "repo_id"]
-               # instead of creating a(n ugly) new section:
-               my $repo_id = $root_repos->{$url} || $url;
-
-               my $fetch = $new_urls->{$url};
-               foreach my $path (keys %$fetch) {
-                       my $x = $fetch->{$path};
-                       Git::SVN->init($url, $path, $repo_id, $x->{ref_id});
-                       my $pfx = "svn-remote.$x->{old_repo_id}";
-
-                       my $old_fetch = quotemeta("$x->{old_path}:".
-                                                 "$x->{ref_id}");
-                       command_noisy(qw/config --unset/,
-                                     "$pfx.fetch", '^'. $old_fetch . '$');
-                       delete $r->{$x->{old_repo_id}}->
-                              {fetch}->{$x->{old_path}};
-                       if (!keys %{$r->{$x->{old_repo_id}}->{fetch}}) {
-                               command_noisy(qw/config --unset/,
-                                             "$pfx.url");
-                               push @emptied, $x->{old_repo_id}
-                       }
-               }
-       }
-       if (@emptied) {
-               my $file = $ENV{GIT_CONFIG} || "$ENV{GIT_DIR}/config";
-               print STDERR <<EOF;
-The following [svn-remote] sections in your config file ($file) are empty
-and can be safely removed:
-EOF
-               print STDERR "[svn-remote \"$_\"]\n" foreach @emptied;
-       }
-}
-
-sub migration_check {
-       migrate_from_v0();
-       migrate_from_v1();
-       migrate_from_v2();
-       minimize_connections() if $_minimize;
-}
-
-package Git::IndexInfo;
-use strict;
-use warnings;
-use Git qw/command_input_pipe command_close_pipe/;
-
-sub new {
-       my ($class) = @_;
-       my ($gui, $ctx) = command_input_pipe(qw/update-index -z --index-info/);
-       bless { gui => $gui, ctx => $ctx, nr => 0}, $class;
-}
-
-sub remove {
-       my ($self, $path) = @_;
-       if (print { $self->{gui} } '0 ', 0 x 40, "\t", $path, "\0") {
-               return ++$self->{nr};
-       }
-       undef;
-}
-
-sub update {
-       my ($self, $mode, $hash, $path) = @_;
-       if (print { $self->{gui} } $mode, ' ', $hash, "\t", $path, "\0") {
-               return ++$self->{nr};
-       }
-       undef;
-}
-
-sub DESTROY {
-       my ($self) = @_;
-       command_close_pipe($self->{gui}, $self->{ctx});
-}
-
-package Git::SVN::GlobSpec;
-use strict;
-use warnings;
-
-sub new {
-       my ($class, $glob, $pattern_ok) = @_;
-       my $re = $glob;
-       $re =~ s!/+$!!g; # no need for trailing slashes
-       my (@left, @right, @patterns);
-       my $state = "left";
-       my $die_msg = "Only one set of wildcard directories " .
-                               "(e.g. '*' or '*/*/*') is supported: '$glob'\n";
-       for my $part (split(m|/|, $glob)) {
-               if ($part =~ /\*/ && $part ne "*") {
-                       die "Invalid pattern in '$glob': $part\n";
-               } elsif ($pattern_ok && $part =~ /[{}]/ &&
-                        $part !~ /^\{[^{}]+\}/) {
-                       die "Invalid pattern in '$glob': $part\n";
-               }
-               if ($part eq "*") {
-                       die $die_msg if $state eq "right";
-                       $state = "pattern";
-                       push(@patterns, "[^/]*");
-               } elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
-                       die $die_msg if $state eq "right";
-                       $state = "pattern";
-                       my $p = quotemeta($1);
-                       $p =~ s/\\,/|/g;
-                       push(@patterns, "(?:$p)");
-               } else {
-                       if ($state eq "left") {
-                               push(@left, $part);
-                       } else {
-                               push(@right, $part);
-                               $state = "right";
-                       }
-               }
-       }
-       my $depth = @patterns;
-       if ($depth == 0) {
-               die "One '*' is needed in glob: '$glob'\n";
-       }
-       my $left = join('/', @left);
-       my $right = join('/', @right);
-       $re = join('/', @patterns);
-       $re = join('\/',
-                  grep(length, quotemeta($left), "($re)", quotemeta($right)));
-       my $left_re = qr/^\/\Q$left\E(\/|$)/;
-       bless { left => $left, right => $right, left_regex => $left_re,
-               regex => qr/$re/, glob => $glob, depth => $depth }, $class;
-}
-
-sub full_path {
-       my ($self, $path) = @_;
-       return (length $self->{left} ? "$self->{left}/" : '') .
-              $path . (length $self->{right} ? "/$self->{right}" : '');
-}
-
 __END__
 
 Data structures:
diff --git a/help.c b/help.c
index 662349dd56fd31d2ea2635657887640f43ce947c..2a42ec6d1f312b573d7b1da1a15471d21efc5b4d 100644 (file)
--- a/help.c
+++ b/help.c
@@ -44,9 +44,12 @@ static void uniq(struct cmdnames *cmds)
        if (!cmds->cnt)
                return;
 
-       for (i = j = 1; i < cmds->cnt; i++)
-               if (strcmp(cmds->names[i]->name, cmds->names[i-1]->name))
+       for (i = j = 1; i < cmds->cnt; i++) {
+               if (!strcmp(cmds->names[i]->name, cmds->names[j-1]->name))
+                       free(cmds->names[i]);
+               else
                        cmds->names[j++] = cmds->names[i];
+       }
 
        cmds->cnt = j;
 }
@@ -61,9 +64,10 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
                cmp = strcmp(cmds->names[ci]->name, excludes->names[ei]->name);
                if (cmp < 0)
                        cmds->names[cj++] = cmds->names[ci++];
-               else if (cmp == 0)
-                       ci++, ei++;
-               else if (cmp > 0)
+               else if (cmp == 0) {
+                       ei++;
+                       free(cmds->names[ci++]);
+               } else if (cmp > 0)
                        ei++;
        }
 
index 680937c39e2dacb7aaa008ee77b34eb9f7c208cb..39b2e165e05472daf38cd6f458541b6db4abc9a8 100644 (file)
@@ -187,7 +187,7 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
        else {
                printf("%s ", find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
                if (parse_commit(commit) != 0)
-                       printf("(bad commit)\n");
+                       printf(_("(bad commit)\n"));
                else {
                        const char *title;
                        int len = find_commit_subject(commit->buffer, &title);
@@ -203,7 +203,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,
        struct cache_entry *ce;
        ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, refresh);
        if (!ce)
-               return error("addinfo_cache failed for path '%s'", path);
+               return error(_("addinfo_cache failed for path '%s'"), path);
        return add_cache_entry(ce, options);
 }
 
@@ -265,7 +265,7 @@ struct tree *write_tree_from_memory(struct merge_options *o)
        if (!cache_tree_fully_valid(active_cache_tree) &&
            cache_tree_update(active_cache_tree,
                              active_cache, active_nr, 0) < 0)
-               die("error building trees");
+               die(_("error building trees"));
 
        result = lookup_tree(active_cache_tree->sha1);
 
@@ -494,7 +494,7 @@ static struct string_list *get_renames(struct merge_options *o,
        opts.show_rename_progress = o->show_rename_progress;
        opts.output_format = DIFF_FORMAT_NO_OUTPUT;
        if (diff_setup_done(&opts) < 0)
-               die("diff setup failed");
+               die(_("diff setup failed"));
        diff_tree_sha1(o_tree->object.sha1, tree->object.sha1, "", &opts);
        diffcore_std(&opts);
        if (opts.needed_rename_limit > o->needed_rename_limit)
@@ -624,7 +624,7 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
                                break;
                        die_errno("merge-recursive");
                } else if (!ret) {
-                       die("merge-recursive: disk full?");
+                       die(_("merge-recursive: disk full?"));
                }
                size -= ret;
                buf += ret;
@@ -687,7 +687,7 @@ static int would_lose_untracked(const char *path)
 static int make_room_for_path(struct merge_options *o, const char *path)
 {
        int status, i;
-       const char *msg = "failed to create path '%s'%s";
+       const char *msg = _("failed to create path '%s'%s");
 
        /* Unlink any D/F conflict files that are in the way */
        for (i = 0; i < o->df_conflict_file_set.nr; i++) {
@@ -698,7 +698,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
                    path[df_pathlen] == '/' &&
                    strncmp(path, df_path, df_pathlen) == 0) {
                        output(o, 3,
-                              "Removing %s to make room for subdirectory\n",
+                              _("Removing %s to make room for subdirectory\n"),
                               df_path);
                        unlink(df_path);
                        unsorted_string_list_delete_item(&o->df_conflict_file_set,
@@ -712,7 +712,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
        if (status) {
                if (status == -3) {
                        /* something else exists */
-                       error(msg, path, ": perhaps a D/F conflict?");
+                       error(msg, path, _(": perhaps a D/F conflict?"));
                        return -1;
                }
                die(msg, path, "");
@@ -723,7 +723,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
         * tracking it.
         */
        if (would_lose_untracked(path))
-               return error("refusing to lose untracked file at '%s'",
+               return error(_("refusing to lose untracked file at '%s'"),
                             path);
 
        /* Successful unlink is good.. */
@@ -733,7 +733,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
        if (errno == ENOENT)
                return 0;
        /* .. but not some other error (who really cares what?) */
-       return error(msg, path, ": perhaps a D/F conflict?");
+       return error(msg, path, _(": perhaps a D/F conflict?"));
 }
 
 static void update_file_flags(struct merge_options *o,
@@ -763,9 +763,9 @@ static void update_file_flags(struct merge_options *o,
 
                buf = read_sha1_file(sha, &type, &size);
                if (!buf)
-                       die("cannot read object %s '%s'", sha1_to_hex(sha), path);
+                       die(_("cannot read object %s '%s'"), sha1_to_hex(sha), path);
                if (type != OBJ_BLOB)
-                       die("blob expected for %s '%s'", sha1_to_hex(sha), path);
+                       die(_("blob expected for %s '%s'"), sha1_to_hex(sha), path);
                if (S_ISREG(mode)) {
                        struct strbuf strbuf = STRBUF_INIT;
                        if (convert_to_working_tree(path, buf, size, &strbuf)) {
@@ -788,7 +788,7 @@ static void update_file_flags(struct merge_options *o,
                                mode = 0666;
                        fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
                        if (fd < 0)
-                               die_errno("failed to open '%s'", path);
+                               die_errno(_("failed to open '%s'"), path);
                        flush_buffer(fd, buf, size);
                        close(fd);
                } else if (S_ISLNK(mode)) {
@@ -796,10 +796,10 @@ static void update_file_flags(struct merge_options *o,
                        safe_create_leading_directories_const(path);
                        unlink(path);
                        if (symlink(lnk, path))
-                               die_errno("failed to symlink '%s'", path);
+                               die_errno(_("failed to symlink '%s'"), path);
                        free(lnk);
                } else
-                       die("do not know what to do with %06o %s '%s'",
+                       die(_("do not know what to do with %06o %s '%s'"),
                            mode, sha1_to_hex(sha), path);
                free(buf);
        }
@@ -936,11 +936,11 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
                                                  branch1, branch2);
 
                        if ((merge_status < 0) || !result_buf.ptr)
-                               die("Failed to execute internal merge");
+                               die(_("Failed to execute internal merge"));
 
                        if (write_sha1_file(result_buf.ptr, result_buf.size,
                                            blob_type, result.sha))
-                               die("Unable to add %s to database",
+                               die(_("Unable to add %s to database"),
                                    a->path);
 
                        free(result_buf.ptr);
@@ -956,7 +956,7 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
                        if (!sha_eq(a->sha1, b->sha1))
                                result.clean = 0;
                } else {
-                       die("unsupported object type in the tree");
+                       die(_("unsupported object type in the tree"));
                }
        }
 
@@ -1034,22 +1034,32 @@ static void handle_change_delete(struct merge_options *o,
                remove_file_from_cache(path);
                update_file(o, 0, o_sha, o_mode, renamed ? renamed : path);
        } else if (!a_sha) {
-               output(o, 1, "CONFLICT (%s/delete): %s deleted in %s "
-                      "and %s in %s. Version %s of %s left in tree%s%s.",
-                      change, path, o->branch1,
-                      change_past, o->branch2, o->branch2, path,
-                      NULL == renamed ? "" : " at ",
-                      NULL == renamed ? "" : renamed);
-               update_file(o, 0, b_sha, b_mode, renamed ? renamed : path);
+               if (!renamed) {
+                       output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s "
+                              "and %s in %s. Version %s of %s left in tree."),
+                              change, path, o->branch1, change_past,
+                              o->branch2, o->branch2, path);
+                       update_file(o, 0, b_sha, b_mode, path);
+               } else {
+                       output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s "
+                              "and %s in %s. Version %s of %s left in tree at %s."),
+                              change, path, o->branch1, change_past,
+                              o->branch2, o->branch2, path, renamed);
+                       update_file(o, 0, b_sha, b_mode, renamed);
+               }
        } else {
-               output(o, 1, "CONFLICT (%s/delete): %s deleted in %s "
-                      "and %s in %s. Version %s of %s left in tree%s%s.",
-                      change, path, o->branch2,
-                      change_past, o->branch1, o->branch1, path,
-                      NULL == renamed ? "" : " at ",
-                      NULL == renamed ? "" : renamed);
-               if (renamed)
+               if (!renamed) {
+                       output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s "
+                              "and %s in %s. Version %s of %s left in tree."),
+                              change, path, o->branch2, change_past,
+                              o->branch1, o->branch1, path);
+               } else {
+                       output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s "
+                              "and %s in %s. Version %s of %s left in tree at %s."),
+                              change, path, o->branch2, change_past,
+                              o->branch1, o->branch1, path, renamed);
                        update_file(o, 0, a_sha, a_mode, renamed);
+               }
                /*
                 * No need to call update_file() on path when !renamed, since
                 * that would needlessly touch path.  We could call
@@ -1085,7 +1095,7 @@ static void conflict_rename_delete(struct merge_options *o,
                             orig->sha1, orig->mode,
                             a_sha, a_mode,
                             b_sha, b_mode,
-                            "rename", "renamed");
+                            _("rename"), _("renamed"));
 
        if (o->call_depth) {
                remove_file_from_cache(dest->path);
@@ -1141,7 +1151,7 @@ static void handle_file(struct merge_options *o,
        } else {
                if (dir_in_way(rename->path, !o->call_depth)) {
                        dst_name = unique_path(o, rename->path, cur_branch);
-                       output(o, 1, "%s is a directory in %s adding as %s instead",
+                       output(o, 1, _("%s is a directory in %s adding as %s instead"),
                               rename->path, other_branch, dst_name);
                }
        }
@@ -1163,12 +1173,12 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
        struct diff_filespec *a = ci->pair1->two;
        struct diff_filespec *b = ci->pair2->two;
 
-       output(o, 1, "CONFLICT (rename/rename): "
+       output(o, 1, _("CONFLICT (rename/rename): "
               "Rename \"%s\"->\"%s\" in branch \"%s\" "
-              "rename \"%s\"->\"%s\" in \"%s\"%s",
+              "rename \"%s\"->\"%s\" in \"%s\"%s"),
               one->path, a->path, ci->branch1,
               one->path, b->path, ci->branch2,
-              o->call_depth ? " (left unresolved)" : "");
+              o->call_depth ? _(" (left unresolved)") : "");
        if (o->call_depth) {
                struct merge_file_info mfi;
                struct diff_filespec other;
@@ -1222,9 +1232,9 @@ static void conflict_rename_rename_2to1(struct merge_options *o,
        struct merge_file_info mfi_c1;
        struct merge_file_info mfi_c2;
 
-       output(o, 1, "CONFLICT (rename/rename): "
+       output(o, 1, _("CONFLICT (rename/rename): "
               "Rename %s->%s in %s. "
-              "Rename %s->%s in %s",
+              "Rename %s->%s in %s"),
               a->path, c1->path, ci->branch1,
               b->path, c2->path, ci->branch2);
 
@@ -1252,7 +1262,7 @@ static void conflict_rename_rename_2to1(struct merge_options *o,
        } else {
                char *new_path1 = unique_path(o, path, ci->branch1);
                char *new_path2 = unique_path(o, path, ci->branch2);
-               output(o, 1, "Renaming %s to %s and %s to %s instead",
+               output(o, 1, _("Renaming %s to %s and %s to %s instead"),
                       a->path, new_path1, b->path, new_path2);
                remove_file(o, 0, path, 0);
                update_file(o, 0, mfi_c1.sha, mfi_c1.mode, new_path1);
@@ -1451,8 +1461,8 @@ static int process_renames(struct merge_options *o,
                        } else if (!sha_eq(dst_other.sha1, null_sha1)) {
                                clean_merge = 0;
                                try_merge = 1;
-                               output(o, 1, "CONFLICT (rename/add): Rename %s->%s in %s. "
-                                      "%s added in %s",
+                               output(o, 1, _("CONFLICT (rename/add): Rename %s->%s in %s. "
+                                      "%s added in %s"),
                                       ren1_src, ren1_dst, branch1,
                                       ren1_dst, branch2);
                                if (o->call_depth) {
@@ -1461,12 +1471,12 @@ static int process_renames(struct merge_options *o,
                                                         ren1->pair->two->sha1, ren1->pair->two->mode,
                                                         dst_other.sha1, dst_other.mode,
                                                         branch1, branch2);
-                                       output(o, 1, "Adding merged %s", ren1_dst);
+                                       output(o, 1, _("Adding merged %s"), ren1_dst);
                                        update_file(o, 0, mfi.sha, mfi.mode, ren1_dst);
                                        try_merge = 0;
                                } else {
                                        char *new_path = unique_path(o, ren1_dst, branch2);
-                                       output(o, 1, "Adding as %s instead", new_path);
+                                       output(o, 1, _("Adding as %s instead"), new_path);
                                        update_file(o, 0, dst_other.sha1, dst_other.mode, new_path);
                                        free(new_path);
                                }
@@ -1517,10 +1527,10 @@ static int read_sha1_strbuf(const unsigned char *sha1, struct strbuf *dst)
        unsigned long size;
        buf = read_sha1_file(sha1, &type, &size);
        if (!buf)
-               return error("cannot read object %s", sha1_to_hex(sha1));
+               return error(_("cannot read object %s"), sha1_to_hex(sha1));
        if (type != OBJ_BLOB) {
                free(buf);
-               return error("object %s is not a blob", sha1_to_hex(sha1));
+               return error(_("object %s is not a blob"), sha1_to_hex(sha1));
        }
        strbuf_attach(dst, buf, size, size + 1);
        return 0;
@@ -1568,7 +1578,7 @@ static void handle_modify_delete(struct merge_options *o,
                             o_sha, o_mode,
                             a_sha, a_mode,
                             b_sha, b_mode,
-                            "modify", "modified");
+                            _("modify"), _("modified"));
 }
 
 static int merge_content(struct merge_options *o,
@@ -1578,14 +1588,14 @@ static int merge_content(struct merge_options *o,
                         unsigned char *b_sha, int b_mode,
                         struct rename_conflict_info *rename_conflict_info)
 {
-       const char *reason = "content";
+       const char *reason = _("content");
        const char *path1 = NULL, *path2 = NULL;
        struct merge_file_info mfi;
        struct diff_filespec one, a, b;
        unsigned df_conflict_remains = 0;
 
        if (!o_sha) {
-               reason = "add/add";
+               reason = _("add/add");
                o_sha = (unsigned char *)null_sha1;
        }
        one.path = a.path = b.path = (char *)path;
@@ -1619,7 +1629,7 @@ static int merge_content(struct merge_options *o,
        if (mfi.clean && !df_conflict_remains &&
            sha_eq(mfi.sha, a_sha) && mfi.mode == a_mode) {
                int path_renamed_outside_HEAD;
-               output(o, 3, "Skipped %s (merged same as existing)", path);
+               output(o, 3, _("Skipped %s (merged same as existing)"), path);
                /*
                 * The content merge resulted in the same file contents we
                 * already had.  We can return early if those file contents
@@ -1633,12 +1643,12 @@ static int merge_content(struct merge_options *o,
                        return mfi.clean;
                }
        } else
-               output(o, 2, "Auto-merging %s", path);
+               output(o, 2, _("Auto-merging %s"), path);
 
        if (!mfi.clean) {
                if (S_ISGITLINK(mfi.mode))
-                       reason = "submodule";
-               output(o, 1, "CONFLICT (%s): Merge conflict in %s",
+                       reason = _("submodule");
+               output(o, 1, _("CONFLICT (%s): Merge conflict in %s"),
                                reason, path);
                if (rename_conflict_info && !df_conflict_remains)
                        update_stages(path, &one, &a, &b);
@@ -1664,7 +1674,7 @@ static int merge_content(struct merge_options *o,
 
                }
                new_path = unique_path(o, path, rename_conflict_info->branch1);
-               output(o, 1, "Adding as %s instead", new_path);
+               output(o, 1, _("Adding as %s instead"), new_path);
                update_file(o, 0, mfi.sha, mfi.mode, new_path);
                free(new_path);
                mfi.clean = 0;
@@ -1728,7 +1738,7 @@ static int process_entry(struct merge_options *o,
                        /* Deleted in both or deleted in one and
                         * unchanged in the other */
                        if (a_sha)
-                               output(o, 2, "Removing %s", path);
+                               output(o, 2, _("Removing %s"), path);
                        /* do not touch working file if it did not exist */
                        remove_file(o, 1, path, !a_sha);
                } else {
@@ -1753,19 +1763,19 @@ static int process_entry(struct merge_options *o,
                        other_branch = o->branch2;
                        mode = a_mode;
                        sha = a_sha;
-                       conf = "file/directory";
+                       conf = _("file/directory");
                } else {
                        add_branch = o->branch2;
                        other_branch = o->branch1;
                        mode = b_mode;
                        sha = b_sha;
-                       conf = "directory/file";
+                       conf = _("directory/file");
                }
                if (dir_in_way(path, !o->call_depth)) {
                        char *new_path = unique_path(o, path, add_branch);
                        clean_merge = 0;
-                       output(o, 1, "CONFLICT (%s): There is a directory with name %s in %s. "
-                              "Adding %s as %s",
+                       output(o, 1, _("CONFLICT (%s): There is a directory with name %s in %s. "
+                              "Adding %s as %s"),
                               conf, path, other_branch, path, new_path);
                        if (o->call_depth)
                                remove_file_from_cache(path);
@@ -1774,7 +1784,7 @@ static int process_entry(struct merge_options *o,
                                remove_file_from_cache(path);
                        free(new_path);
                } else {
-                       output(o, 2, "Adding %s", path);
+                       output(o, 2, _("Adding %s"), path);
                        /* do not overwrite file if already present */
                        update_file_flags(o, sha, mode, path, 1, !a_sha);
                }
@@ -1791,7 +1801,7 @@ static int process_entry(struct merge_options *o,
                 */
                remove_file(o, 1, path, !a_mode);
        } else
-               die("Fatal merge failure, shouldn't happen.");
+               die(_("Fatal merge failure, shouldn't happen."));
 
        return clean_merge;
 }
@@ -1810,7 +1820,7 @@ int merge_trees(struct merge_options *o,
        }
 
        if (sha_eq(common->object.sha1, merge->object.sha1)) {
-               output(o, 0, "Already up-to-date!");
+               output(o, 0, _("Already up-to-date!"));
                *result = head;
                return 1;
        }
@@ -1819,7 +1829,7 @@ int merge_trees(struct merge_options *o,
 
        if (code != 0) {
                if (show(o, 4) || o->call_depth)
-                       die("merging of trees %s and %s failed",
+                       die(_("merging of trees %s and %s failed"),
                            sha1_to_hex(head->object.sha1),
                            sha1_to_hex(merge->object.sha1));
                else
@@ -1849,7 +1859,7 @@ int merge_trees(struct merge_options *o,
                for (i = 0; i < entries->nr; i++) {
                        struct stage_data *e = entries->items[i].util;
                        if (!e->processed)
-                               die("Unprocessed path??? %s",
+                               die(_("Unprocessed path??? %s"),
                                    entries->items[i].string);
                }
 
@@ -1894,7 +1904,7 @@ int merge_recursive(struct merge_options *o,
        int clean;
 
        if (show(o, 4)) {
-               output(o, 4, "Merging:");
+               output(o, 4, _("Merging:"));
                output_commit_title(o, h1);
                output_commit_title(o, h2);
        }
@@ -1905,7 +1915,10 @@ int merge_recursive(struct merge_options *o,
        }
 
        if (show(o, 5)) {
-               output(o, 5, "found %u common ancestor(s):", commit_list_count(ca));
+               unsigned cnt = commit_list_count(ca);
+
+               output(o, 5, Q_("found %u common ancestor:",
+                               "found %u common ancestors:", cnt), cnt);
                for (iter = ca; iter; iter = iter->next)
                        output_commit_title(o, iter->item);
        }
@@ -1941,7 +1954,7 @@ int merge_recursive(struct merge_options *o,
                o->call_depth--;
 
                if (!merged_common_ancestors)
-                       die("merge returned no commit");
+                       die(_("merge returned no commit"));
        }
 
        discard_cache();
@@ -1998,7 +2011,7 @@ int merge_recursive_generic(struct merge_options *o,
                for (i = 0; i < num_base_list; ++i) {
                        struct commit *base;
                        if (!(base = get_ref(base_list[i], sha1_to_hex(base_list[i]))))
-                               return error("Could not parse object '%s'",
+                               return error(_("Could not parse object '%s'"),
                                        sha1_to_hex(base_list[i]));
                        commit_list_insert(base, &ca);
                }
@@ -2010,7 +2023,7 @@ int merge_recursive_generic(struct merge_options *o,
        if (active_cache_changed &&
                        (write_cache(index_fd, active_cache, active_nr) ||
                         commit_locked_index(lock)))
-               return error("Unable to write index.");
+               return error(_("Unable to write index."));
 
        return clean ? 0 : 1;
 }
index d5c6e22d0f74e075a49dd50cde6cbee5049a336c..0f1fc27f862f61015db843f272e61b29c14223af 100644 (file)
@@ -5,3 +5,4 @@ MYMETA.yml
 blib
 blibdirs
 pm_to_blib
+PM.stamp
diff --git a/perl/Git/IndexInfo.pm b/perl/Git/IndexInfo.pm
new file mode 100644 (file)
index 0000000..a43108c
--- /dev/null
@@ -0,0 +1,33 @@
+package Git::IndexInfo;
+use strict;
+use warnings;
+use Git qw/command_input_pipe command_close_pipe/;
+
+sub new {
+       my ($class) = @_;
+       my ($gui, $ctx) = command_input_pipe(qw/update-index -z --index-info/);
+       bless { gui => $gui, ctx => $ctx, nr => 0}, $class;
+}
+
+sub remove {
+       my ($self, $path) = @_;
+       if (print { $self->{gui} } '0 ', 0 x 40, "\t", $path, "\0") {
+               return ++$self->{nr};
+       }
+       undef;
+}
+
+sub update {
+       my ($self, $mode, $hash, $path) = @_;
+       if (print { $self->{gui} } $mode, ' ', $hash, "\t", $path, "\0") {
+               return ++$self->{nr};
+       }
+       undef;
+}
+
+sub DESTROY {
+       my ($self) = @_;
+       command_close_pipe($self->{gui}, $self->{ctx});
+}
+
+1;
diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm
new file mode 100644 (file)
index 0000000..acb2539
--- /dev/null
@@ -0,0 +1,2397 @@
+package Git::SVN;
+use strict;
+use warnings;
+use Fcntl qw/:DEFAULT :seek/;
+use constant rev_map_fmt => 'NH40';
+use vars qw/$_no_metadata
+            $_repack $_repack_flags $_use_svm_props $_head
+            $_use_svnsync_props $no_reuse_existing
+           $_use_log_author $_add_author_from $_localtime/;
+use Carp qw/croak/;
+use File::Path qw/mkpath/;
+use File::Copy qw/copy/;
+use IPC::Open3;
+use Time::Local;
+use Memoize;  # core since 5.8.0, Jul 2002
+use Memoize::Storable;
+use POSIX qw(:signal_h);
+
+use Git qw(
+    command
+    command_oneline
+    command_noisy
+    command_output_pipe
+    command_close_pipe
+);
+use Git::SVN::Utils qw(
+       fatal
+       can_compress
+       join_paths
+       canonicalize_path
+       canonicalize_url
+       add_path_to_url
+);
+
+my $can_use_yaml;
+BEGIN {
+       $can_use_yaml = eval { require Git::SVN::Memoize::YAML; 1};
+}
+
+our $_follow_parent  = 1;
+our $_minimize_url   = 'unset';
+our $default_repo_id = 'svn';
+our $default_ref_id  = $ENV{GIT_SVN_ID} || 'git-svn';
+
+my ($_gc_nr, $_gc_period);
+
+# properties that we do not log:
+my %SKIP_PROP;
+BEGIN {
+       %SKIP_PROP = map { $_ => 1 } qw/svn:wc:ra_dav:version-url
+                                       svn:special svn:executable
+                                       svn:entry:committed-rev
+                                       svn:entry:last-author
+                                       svn:entry:uuid
+                                       svn:entry:committed-date/;
+
+       # some options are read globally, but can be overridden locally
+       # per [svn-remote "..."] section.  Command-line options will *NOT*
+       # override options set in an [svn-remote "..."] section
+       no strict 'refs';
+       for my $option (qw/follow_parent no_metadata use_svm_props
+                          use_svnsync_props/) {
+               my $key = $option;
+               $key =~ tr/_//d;
+               my $prop = "-$option";
+               *$option = sub {
+                       my ($self) = @_;
+                       return $self->{$prop} if exists $self->{$prop};
+                       my $k = "svn-remote.$self->{repo_id}.$key";
+                       eval { command_oneline(qw/config --get/, $k) };
+                       if ($@) {
+                               $self->{$prop} = ${"Git::SVN::_$option"};
+                       } else {
+                               my $v = command_oneline(qw/config --bool/,$k);
+                               $self->{$prop} = $v eq 'false' ? 0 : 1;
+                       }
+                       return $self->{$prop};
+               }
+       }
+}
+
+
+my (%LOCKFILES, %INDEX_FILES);
+END {
+       unlink keys %LOCKFILES if %LOCKFILES;
+       unlink keys %INDEX_FILES if %INDEX_FILES;
+}
+
+sub resolve_local_globs {
+       my ($url, $fetch, $glob_spec) = @_;
+       return unless defined $glob_spec;
+       my $ref = $glob_spec->{ref};
+       my $path = $glob_spec->{path};
+       foreach (command(qw#for-each-ref --format=%(refname) refs/#)) {
+               next unless m#^$ref->{regex}$#;
+               my $p = $1;
+               my $pathname = desanitize_refname($path->full_path($p));
+               my $refname = desanitize_refname($ref->full_path($p));
+               if (my $existing = $fetch->{$pathname}) {
+                       if ($existing ne $refname) {
+                               die "Refspec conflict:\n",
+                                   "existing: $existing\n",
+                                   " globbed: $refname\n";
+                       }
+                       my $u = (::cmt_metadata("$refname"))[0];
+                       $u =~ s!^\Q$url\E(/|$)!! or die
+                         "$refname: '$url' not found in '$u'\n";
+                       if ($pathname ne $u) {
+                               warn "W: Refspec glob conflict ",
+                                    "(ref: $refname):\n",
+                                    "expected path: $pathname\n",
+                                    "    real path: $u\n",
+                                    "Continuing ahead with $u\n";
+                               next;
+                       }
+               } else {
+                       $fetch->{$pathname} = $refname;
+               }
+       }
+}
+
+sub parse_revision_argument {
+       my ($base, $head) = @_;
+       if (!defined $::_revision || $::_revision eq 'BASE:HEAD') {
+               return ($base, $head);
+       }
+       return ($1, $2) if ($::_revision =~ /^(\d+):(\d+)$/);
+       return ($::_revision, $::_revision) if ($::_revision =~ /^\d+$/);
+       return ($head, $head) if ($::_revision eq 'HEAD');
+       return ($base, $1) if ($::_revision =~ /^BASE:(\d+)$/);
+       return ($1, $head) if ($::_revision =~ /^(\d+):HEAD$/);
+       die "revision argument: $::_revision not understood by git-svn\n";
+}
+
+sub fetch_all {
+       my ($repo_id, $remotes) = @_;
+       if (ref $repo_id) {
+               my $gs = $repo_id;
+               $repo_id = undef;
+               $repo_id = $gs->{repo_id};
+       }
+       $remotes ||= read_all_remotes();
+       my $remote = $remotes->{$repo_id} or
+                    die "[svn-remote \"$repo_id\"] unknown\n";
+       my $fetch = $remote->{fetch};
+       my $url = $remote->{url} or die "svn-remote.$repo_id.url not defined\n";
+       my (@gs, @globs);
+       my $ra = Git::SVN::Ra->new($url);
+       my $uuid = $ra->get_uuid;
+       my $head = $ra->get_latest_revnum;
+
+       # ignore errors, $head revision may not even exist anymore
+       eval { $ra->get_log("", $head, 0, 1, 0, 1, sub { $head = $_[1] }) };
+       warn "W: $@\n" if $@;
+
+       my $base = defined $fetch ? $head : 0;
+
+       # read the max revs for wildcard expansion (branches/*, tags/*)
+       foreach my $t (qw/branches tags/) {
+               defined $remote->{$t} or next;
+               push @globs, @{$remote->{$t}};
+
+               my $max_rev = eval { tmp_config(qw/--int --get/,
+                                        "svn-remote.$repo_id.${t}-maxRev") };
+               if (defined $max_rev && ($max_rev < $base)) {
+                       $base = $max_rev;
+               } elsif (!defined $max_rev) {
+                       $base = 0;
+               }
+       }
+
+       if ($fetch) {
+               foreach my $p (sort keys %$fetch) {
+                       my $gs = Git::SVN->new($fetch->{$p}, $repo_id, $p);
+                       my $lr = $gs->rev_map_max;
+                       if (defined $lr) {
+                               $base = $lr if ($lr < $base);
+                       }
+                       push @gs, $gs;
+               }
+       }
+
+       ($base, $head) = parse_revision_argument($base, $head);
+       $ra->gs_fetch_loop_common($base, $head, \@gs, \@globs);
+}
+
+sub read_all_remotes {
+       my $r = {};
+       my $use_svm_props = eval { command_oneline(qw/config --bool
+           svn.useSvmProps/) };
+       $use_svm_props = $use_svm_props eq 'true' if $use_svm_props;
+       my $svn_refspec = qr{\s*(.*?)\s*:\s*(.+?)\s*};
+       foreach (grep { s/^svn-remote\.// } command(qw/config -l/)) {
+               if (m!^(.+)\.fetch=$svn_refspec$!) {
+                       my ($remote, $local_ref, $remote_ref) = ($1, $2, $3);
+                       die("svn-remote.$remote: remote ref '$remote_ref' "
+                           . "must start with 'refs/'\n")
+                               unless $remote_ref =~ m{^refs/};
+                       $local_ref = uri_decode($local_ref);
+                       $r->{$remote}->{fetch}->{$local_ref} = $remote_ref;
+                       $r->{$remote}->{svm} = {} if $use_svm_props;
+               } elsif (m!^(.+)\.usesvmprops=\s*(.*)\s*$!) {
+                       $r->{$1}->{svm} = {};
+               } elsif (m!^(.+)\.url=\s*(.*)\s*$!) {
+                       $r->{$1}->{url} = canonicalize_url($2);
+               } elsif (m!^(.+)\.pushurl=\s*(.*)\s*$!) {
+                       $r->{$1}->{pushurl} = canonicalize_url($2);
+               } elsif (m!^(.+)\.ignore-refs=\s*(.*)\s*$!) {
+                       $r->{$1}->{ignore_refs_regex} = $2;
+               } elsif (m!^(.+)\.(branches|tags)=$svn_refspec$!) {
+                       my ($remote, $t, $local_ref, $remote_ref) =
+                                                            ($1, $2, $3, $4);
+                       die("svn-remote.$remote: remote ref '$remote_ref' ($t) "
+                           . "must start with 'refs/'\n")
+                               unless $remote_ref =~ m{^refs/};
+                       $local_ref = uri_decode($local_ref);
+
+                       require Git::SVN::GlobSpec;
+                       my $rs = {
+                           t => $t,
+                           remote => $remote,
+                           path => Git::SVN::GlobSpec->new($local_ref, 1),
+                           ref => Git::SVN::GlobSpec->new($remote_ref, 0) };
+                       if (length($rs->{ref}->{right}) != 0) {
+                               die "The '*' glob character must be the last ",
+                                   "character of '$remote_ref'\n";
+                       }
+                       push @{ $r->{$remote}->{$t} }, $rs;
+               }
+       }
+
+       map {
+               if (defined $r->{$_}->{svm}) {
+                       my $svm;
+                       eval {
+                               my $section = "svn-remote.$_";
+                               $svm = {
+                                       source => tmp_config('--get',
+                                           "$section.svm-source"),
+                                       replace => tmp_config('--get',
+                                           "$section.svm-replace"),
+                               }
+                       };
+                       $r->{$_}->{svm} = $svm;
+               }
+       } keys %$r;
+
+       foreach my $remote (keys %$r) {
+               foreach ( grep { defined $_ }
+                         map { $r->{$remote}->{$_} } qw(branches tags) ) {
+                       foreach my $rs ( @$_ ) {
+                               $rs->{ignore_refs_regex} =
+                                   $r->{$remote}->{ignore_refs_regex};
+                       }
+               }
+       }
+
+       $r;
+}
+
+sub init_vars {
+       $_gc_nr = $_gc_period = 1000;
+       if (defined $_repack || defined $_repack_flags) {
+              warn "Repack options are obsolete; they have no effect.\n";
+       }
+}
+
+sub verify_remotes_sanity {
+       return unless -d $ENV{GIT_DIR};
+       my %seen;
+       foreach (command(qw/config -l/)) {
+               if (m!^svn-remote\.(?:.+)\.fetch=.*:refs/remotes/(\S+)\s*$!) {
+                       if ($seen{$1}) {
+                               die "Remote ref refs/remote/$1 is tracked by",
+                                   "\n  \"$_\"\nand\n  \"$seen{$1}\"\n",
+                                   "Please resolve this ambiguity in ",
+                                   "your git configuration file before ",
+                                   "continuing\n";
+                       }
+                       $seen{$1} = $_;
+               }
+       }
+}
+
+sub find_existing_remote {
+       my ($url, $remotes) = @_;
+       return undef if $no_reuse_existing;
+       my $existing;
+       foreach my $repo_id (keys %$remotes) {
+               my $u = $remotes->{$repo_id}->{url} or next;
+               next if $u ne $url;
+               $existing = $repo_id;
+               last;
+       }
+       $existing;
+}
+
+sub init_remote_config {
+       my ($self, $url, $no_write) = @_;
+       $url = canonicalize_url($url);
+       my $r = read_all_remotes();
+       my $existing = find_existing_remote($url, $r);
+       if ($existing) {
+               unless ($no_write) {
+                       print STDERR "Using existing ",
+                                    "[svn-remote \"$existing\"]\n";
+               }
+               $self->{repo_id} = $existing;
+       } elsif ($_minimize_url) {
+               my $min_url = Git::SVN::Ra->new($url)->minimize_url;
+               $existing = find_existing_remote($min_url, $r);
+               if ($existing) {
+                       unless ($no_write) {
+                               print STDERR "Using existing ",
+                                            "[svn-remote \"$existing\"]\n";
+                       }
+                       $self->{repo_id} = $existing;
+               }
+               if ($min_url ne $url) {
+                       unless ($no_write) {
+                               print STDERR "Using higher level of URL: ",
+                                            "$url => $min_url\n";
+                       }
+                       my $old_path = $self->path;
+                       $url =~ s!^\Q$min_url\E(/|$)!!;
+                       $url = join_paths($url, $old_path);
+                       $self->path($url);
+                       $url = $min_url;
+               }
+       }
+       my $orig_url;
+       if (!$existing) {
+               # verify that we aren't overwriting anything:
+               $orig_url = eval {
+                       command_oneline('config', '--get',
+                                       "svn-remote.$self->{repo_id}.url")
+               };
+               if ($orig_url && ($orig_url ne $url)) {
+                       die "svn-remote.$self->{repo_id}.url already set: ",
+                           "$orig_url\nwanted to set to: $url\n";
+               }
+       }
+       my ($xrepo_id, $xpath) = find_ref($self->refname);
+       if (!$no_write && defined $xpath) {
+               die "svn-remote.$xrepo_id.fetch already set to track ",
+                   "$xpath:", $self->refname, "\n";
+       }
+       unless ($no_write) {
+               command_noisy('config',
+                             "svn-remote.$self->{repo_id}.url", $url);
+               my $path = $self->path;
+               $path =~ s{^/}{};
+               $path =~ s{%([0-9A-F]{2})}{chr hex($1)}ieg;
+               $self->path($path);
+               command_noisy('config', '--add',
+                             "svn-remote.$self->{repo_id}.fetch",
+                             $self->path.":".$self->refname);
+       }
+       $self->url($url);
+}
+
+sub find_by_url { # repos_root and, path are optional
+       my ($class, $full_url, $repos_root, $path) = @_;
+
+       $full_url = canonicalize_url($full_url);
+
+       return undef unless defined $full_url;
+       remove_username($full_url);
+       remove_username($repos_root) if defined $repos_root;
+       my $remotes = read_all_remotes();
+       if (defined $full_url && defined $repos_root && !defined $path) {
+               $path = $full_url;
+               $path =~ s#^\Q$repos_root\E(?:/|$)##;
+       }
+       foreach my $repo_id (keys %$remotes) {
+               my $u = $remotes->{$repo_id}->{url} or next;
+               remove_username($u);
+               next if defined $repos_root && $repos_root ne $u;
+
+               my $fetch = $remotes->{$repo_id}->{fetch} || {};
+               foreach my $t (qw/branches tags/) {
+                       foreach my $globspec (@{$remotes->{$repo_id}->{$t}}) {
+                               resolve_local_globs($u, $fetch, $globspec);
+                       }
+               }
+               my $p = $path;
+               my $rwr = rewrite_root({repo_id => $repo_id});
+               my $svm = $remotes->{$repo_id}->{svm}
+                       if defined $remotes->{$repo_id}->{svm};
+               unless (defined $p) {
+                       $p = $full_url;
+                       my $z = $u;
+                       my $prefix = '';
+                       if ($rwr) {
+                               $z = $rwr;
+                               remove_username($z);
+                       } elsif (defined $svm) {
+                               $z = $svm->{source};
+                               $prefix = $svm->{replace};
+                               $prefix =~ s#^\Q$u\E(?:/|$)##;
+                               $prefix =~ s#/$##;
+                       }
+                       $p =~ s#^\Q$z\E(?:/|$)#$prefix# or next;
+               }
+
+               # remote fetch paths are not URI escaped.  Decode ours
+               # so they match
+               $p = uri_decode($p);
+
+               foreach my $f (keys %$fetch) {
+                       next if $f ne $p;
+                       return Git::SVN->new($fetch->{$f}, $repo_id, $f);
+               }
+       }
+       undef;
+}
+
+sub init {
+       my ($class, $url, $path, $repo_id, $ref_id, $no_write) = @_;
+       my $self = _new($class, $repo_id, $ref_id, $path);
+       if (defined $url) {
+               $self->init_remote_config($url, $no_write);
+       }
+       $self;
+}
+
+sub find_ref {
+       my ($ref_id) = @_;
+       foreach (command(qw/config -l/)) {
+               next unless m!^svn-remote\.(.+)\.fetch=
+                             \s*(.*?)\s*:\s*(.+?)\s*$!x;
+               my ($repo_id, $path, $ref) = ($1, $2, $3);
+               if ($ref eq $ref_id) {
+                       $path = '' if ($path =~ m#^\./?#);
+                       return ($repo_id, $path);
+               }
+       }
+       (undef, undef, undef);
+}
+
+sub new {
+       my ($class, $ref_id, $repo_id, $path) = @_;
+       if (defined $ref_id && !defined $repo_id && !defined $path) {
+               ($repo_id, $path) = find_ref($ref_id);
+               if (!defined $repo_id) {
+                       die "Could not find a \"svn-remote.*.fetch\" key ",
+                           "in the repository configuration matching: ",
+                           "$ref_id\n";
+               }
+       }
+       my $self = _new($class, $repo_id, $ref_id, $path);
+       if (!defined $self->path || !length $self->path) {
+               my $fetch = command_oneline('config', '--get',
+                                           "svn-remote.$repo_id.fetch",
+                                           ":$ref_id\$") or
+                    die "Failed to read \"svn-remote.$repo_id.fetch\" ",
+                        "\":$ref_id\$\" in config\n";
+               my($path) = split(/\s*:\s*/, $fetch);
+               $self->path($path);
+       }
+       {
+               my $path = $self->path;
+               $path =~ s{\A/}{};
+               $path =~ s{/\z}{};
+               $self->path($path);
+       }
+       my $url = command_oneline('config', '--get',
+                                 "svn-remote.$repo_id.url") or
+                  die "Failed to read \"svn-remote.$repo_id.url\" in config\n";
+       $self->url($url);
+       $self->{pushurl} = eval { command_oneline('config', '--get',
+                                 "svn-remote.$repo_id.pushurl") };
+       $self->rebuild;
+       $self;
+}
+
+sub refname {
+       my ($refname) = $_[0]->{ref_id} ;
+
+       # It cannot end with a slash /, we'll throw up on this because
+       # SVN can't have directories with a slash in their name, either:
+       if ($refname =~ m{/$}) {
+               die "ref: '$refname' ends with a trailing slash, this is ",
+                   "not permitted by git nor Subversion\n";
+       }
+
+       # It cannot have ASCII control character space, tilde ~, caret ^,
+       # colon :, question-mark ?, asterisk *, space, or open bracket [
+       # anywhere.
+       #
+       # Additionally, % must be escaped because it is used for escaping
+       # and we want our escaped refname to be reversible
+       $refname =~ s{([ \%~\^:\?\*\[\t])}{uc sprintf('%%%02x',ord($1))}eg;
+
+       # no slash-separated component can begin with a dot .
+       # /.* becomes /%2E*
+       $refname =~ s{/\.}{/%2E}g;
+
+       # It cannot have two consecutive dots .. anywhere
+       # .. becomes %2E%2E
+       $refname =~ s{\.\.}{%2E%2E}g;
+
+       # trailing dots and .lock are not allowed
+       # .$ becomes %2E and .lock becomes %2Elock
+       $refname =~ s{\.(?=$|lock$)}{%2E};
+
+       # the sequence @{ is used to access the reflog
+       # @{ becomes %40{
+       $refname =~ s{\@\{}{%40\{}g;
+
+       return $refname;
+}
+
+sub desanitize_refname {
+       my ($refname) = @_;
+       $refname =~ s{%(?:([0-9A-F]{2}))}{chr hex($1)}eg;
+       return $refname;
+}
+
+sub svm_uuid {
+       my ($self) = @_;
+       return $self->{svm}->{uuid} if $self->svm;
+       $self->ra;
+       unless ($self->{svm}) {
+               die "SVM UUID not cached, and reading remotely failed\n";
+       }
+       $self->{svm}->{uuid};
+}
+
+sub svm {
+       my ($self) = @_;
+       return $self->{svm} if $self->{svm};
+       my $svm;
+       # see if we have it in our config, first:
+       eval {
+               my $section = "svn-remote.$self->{repo_id}";
+               $svm = {
+                 source => tmp_config('--get', "$section.svm-source"),
+                 uuid => tmp_config('--get', "$section.svm-uuid"),
+                 replace => tmp_config('--get', "$section.svm-replace"),
+               }
+       };
+       if ($svm && $svm->{source} && $svm->{uuid} && $svm->{replace}) {
+               $self->{svm} = $svm;
+       }
+       $self->{svm};
+}
+
+sub _set_svm_vars {
+       my ($self, $ra) = @_;
+       return $ra if $self->svm;
+
+       my @err = ( "useSvmProps set, but failed to read SVM properties\n",
+                   "(svm:source, svm:uuid) ",
+                   "from the following URLs:\n" );
+       sub read_svm_props {
+               my ($self, $ra, $path, $r) = @_;
+               my $props = ($ra->get_dir($path, $r))[2];
+               my $src = $props->{'svm:source'};
+               my $uuid = $props->{'svm:uuid'};
+               return undef if (!$src || !$uuid);
+
+               chomp($src, $uuid);
+
+               $uuid =~ m{^[0-9a-f\-]{30,}$}i
+                   or die "doesn't look right - svm:uuid is '$uuid'\n";
+
+               # the '!' is used to mark the repos_root!/relative/path
+               $src =~ s{/?!/?}{/};
+               $src =~ s{/+$}{}; # no trailing slashes please
+               # username is of no interest
+               $src =~ s{(^[a-z\+]*://)[^/@]*@}{$1};
+
+               my $replace = add_path_to_url($ra->url, $path);
+
+               my $section = "svn-remote.$self->{repo_id}";
+               tmp_config("$section.svm-source", $src);
+               tmp_config("$section.svm-replace", $replace);
+               tmp_config("$section.svm-uuid", $uuid);
+               $self->{svm} = {
+                       source => $src,
+                       uuid => $uuid,
+                       replace => $replace
+               };
+       }
+
+       my $r = $ra->get_latest_revnum;
+       my $path = $self->path;
+       my %tried;
+       while (length $path) {
+               my $try = add_path_to_url($self->url, $path);
+               unless ($tried{$try}) {
+                       return $ra if $self->read_svm_props($ra, $path, $r);
+                       $tried{$try} = 1;
+               }
+               $path =~ s#/?[^/]+$##;
+       }
+       die "Path: '$path' should be ''\n" if $path ne '';
+       return $ra if $self->read_svm_props($ra, $path, $r);
+       $tried{ add_path_to_url($self->url, $path) } = 1;
+
+       if ($ra->{repos_root} eq $self->url) {
+               die @err, (map { "  $_\n" } keys %tried), "\n";
+       }
+
+       # nope, make sure we're connected to the repository root:
+       my $ok;
+       my @tried_b;
+       $path = $ra->{svn_path};
+       $ra = Git::SVN::Ra->new($ra->{repos_root});
+       while (length $path) {
+               my $try = add_path_to_url($ra->url, $path);
+               unless ($tried{$try}) {
+                       $ok = $self->read_svm_props($ra, $path, $r);
+                       last if $ok;
+                       $tried{$try} = 1;
+               }
+               $path =~ s#/?[^/]+$##;
+       }
+       die "Path: '$path' should be ''\n" if $path ne '';
+       $ok ||= $self->read_svm_props($ra, $path, $r);
+       $tried{ add_path_to_url($ra->url, $path) } = 1;
+       if (!$ok) {
+               die @err, (map { "  $_\n" } keys %tried), "\n";
+       }
+       Git::SVN::Ra->new($self->url);
+}
+
+sub svnsync {
+       my ($self) = @_;
+       return $self->{svnsync} if $self->{svnsync};
+
+       if ($self->no_metadata) {
+               die "Can't have both 'noMetadata' and ",
+                   "'useSvnsyncProps' options set!\n";
+       }
+       if ($self->rewrite_root) {
+               die "Can't have both 'useSvnsyncProps' and 'rewriteRoot' ",
+                   "options set!\n";
+       }
+       if ($self->rewrite_uuid) {
+               die "Can't have both 'useSvnsyncProps' and 'rewriteUUID' ",
+                   "options set!\n";
+       }
+
+       my $svnsync;
+       # see if we have it in our config, first:
+       eval {
+               my $section = "svn-remote.$self->{repo_id}";
+
+               my $url = tmp_config('--get', "$section.svnsync-url");
+               ($url) = ($url =~ m{^([a-z\+]+://\S+)$}) or
+                  die "doesn't look right - svn:sync-from-url is '$url'\n";
+
+               my $uuid = tmp_config('--get', "$section.svnsync-uuid");
+               ($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}i) or
+                  die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
+
+               $svnsync = { url => $url, uuid => $uuid }
+       };
+       if ($svnsync && $svnsync->{url} && $svnsync->{uuid}) {
+               return $self->{svnsync} = $svnsync;
+       }
+
+       my $err = "useSvnsyncProps set, but failed to read " .
+                 "svnsync property: svn:sync-from-";
+       my $rp = $self->ra->rev_proplist(0);
+
+       my $url = $rp->{'svn:sync-from-url'} or die $err . "url\n";
+       ($url) = ($url =~ m{^([a-z\+]+://\S+)$}) or
+                  die "doesn't look right - svn:sync-from-url is '$url'\n";
+
+       my $uuid = $rp->{'svn:sync-from-uuid'} or die $err . "uuid\n";
+       ($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}i) or
+                  die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
+
+       my $section = "svn-remote.$self->{repo_id}";
+       tmp_config('--add', "$section.svnsync-uuid", $uuid);
+       tmp_config('--add', "$section.svnsync-url", $url);
+       return $self->{svnsync} = { url => $url, uuid => $uuid };
+}
+
+# this allows us to memoize our SVN::Ra UUID locally and avoid a
+# remote lookup (useful for 'git svn log').
+sub ra_uuid {
+       my ($self) = @_;
+       unless ($self->{ra_uuid}) {
+               my $key = "svn-remote.$self->{repo_id}.uuid";
+               my $uuid = eval { tmp_config('--get', $key) };
+               if (!$@ && $uuid && $uuid =~ /^([a-f\d\-]{30,})$/i) {
+                       $self->{ra_uuid} = $uuid;
+               } else {
+                       die "ra_uuid called without URL\n" unless $self->url;
+                       $self->{ra_uuid} = $self->ra->get_uuid;
+                       tmp_config('--add', $key, $self->{ra_uuid});
+               }
+       }
+       $self->{ra_uuid};
+}
+
+sub _set_repos_root {
+       my ($self, $repos_root) = @_;
+       my $k = "svn-remote.$self->{repo_id}.reposRoot";
+       $repos_root ||= $self->ra->{repos_root};
+       tmp_config($k, $repos_root);
+       $repos_root;
+}
+
+sub repos_root {
+       my ($self) = @_;
+       my $k = "svn-remote.$self->{repo_id}.reposRoot";
+       eval { tmp_config('--get', $k) } || $self->_set_repos_root;
+}
+
+sub ra {
+       my ($self) = shift;
+       my $ra = Git::SVN::Ra->new($self->url);
+       $self->_set_repos_root($ra->{repos_root});
+       if ($self->use_svm_props && !$self->{svm}) {
+               if ($self->no_metadata) {
+                       die "Can't have both 'noMetadata' and ",
+                           "'useSvmProps' options set!\n";
+               } elsif ($self->use_svnsync_props) {
+                       die "Can't have both 'useSvnsyncProps' and ",
+                           "'useSvmProps' options set!\n";
+               }
+               $ra = $self->_set_svm_vars($ra);
+               $self->{-want_revprops} = 1;
+       }
+       $ra;
+}
+
+# prop_walk(PATH, REV, SUB)
+# -------------------------
+# Recursively traverse PATH at revision REV and invoke SUB for each
+# directory that contains a SVN property.  SUB will be invoked as
+# follows:  &SUB(gs, path, props);  where `gs' is this instance of
+# Git::SVN, `path' the path to the directory where the properties
+# `props' were found.  The `path' will be relative to point of checkout,
+# that is, if url://repo/trunk is the current Git branch, and that
+# directory contains a sub-directory `d', SUB will be invoked with `/d/'
+# as `path' (note the trailing `/').
+sub prop_walk {
+       my ($self, $path, $rev, $sub) = @_;
+
+       $path =~ s#^/##;
+       my ($dirent, undef, $props) = $self->ra->get_dir($path, $rev);
+       $path =~ s#^/*#/#g;
+       my $p = $path;
+       # Strip the irrelevant part of the path.
+       $p =~ s#^/+\Q@{[$self->path]}\E(/|$)#/#;
+       # Ensure the path is terminated by a `/'.
+       $p =~ s#/*$#/#;
+
+       # The properties contain all the internal SVN stuff nobody
+       # (usually) cares about.
+       my $interesting_props = 0;
+       foreach (keys %{$props}) {
+               # If it doesn't start with `svn:', it must be a
+               # user-defined property.
+               ++$interesting_props and next if $_ !~ /^svn:/;
+               # FIXME: Fragile, if SVN adds new public properties,
+               # this needs to be updated.
+               ++$interesting_props if /^svn:(?:ignore|keywords|executable
+                                                |eol-style|mime-type
+                                                |externals|needs-lock)$/x;
+       }
+       &$sub($self, $p, $props) if $interesting_props;
+
+       foreach (sort keys %$dirent) {
+               next if $dirent->{$_}->{kind} != $SVN::Node::dir;
+               $self->prop_walk($self->path . $p . $_, $rev, $sub);
+       }
+}
+
+sub last_rev { ($_[0]->last_rev_commit)[0] }
+sub last_commit { ($_[0]->last_rev_commit)[1] }
+
+# returns the newest SVN revision number and newest commit SHA1
+sub last_rev_commit {
+       my ($self) = @_;
+       if (defined $self->{last_rev} && defined $self->{last_commit}) {
+               return ($self->{last_rev}, $self->{last_commit});
+       }
+       my $c = ::verify_ref($self->refname.'^0');
+       if ($c && !$self->use_svm_props && !$self->no_metadata) {
+               my $rev = (::cmt_metadata($c))[1];
+               if (defined $rev) {
+                       ($self->{last_rev}, $self->{last_commit}) = ($rev, $c);
+                       return ($rev, $c);
+               }
+       }
+       my $map_path = $self->map_path;
+       unless (-e $map_path) {
+               ($self->{last_rev}, $self->{last_commit}) = (undef, undef);
+               return (undef, undef);
+       }
+       my ($rev, $commit) = $self->rev_map_max(1);
+       ($self->{last_rev}, $self->{last_commit}) = ($rev, $commit);
+       return ($rev, $commit);
+}
+
+sub get_fetch_range {
+       my ($self, $min, $max) = @_;
+       $max ||= $self->ra->get_latest_revnum;
+       $min ||= $self->rev_map_max;
+       (++$min, $max);
+}
+
+sub tmp_config {
+       my (@args) = @_;
+       my $old_def_config = "$ENV{GIT_DIR}/svn/config";
+       my $config = "$ENV{GIT_DIR}/svn/.metadata";
+       if (! -f $config && -f $old_def_config) {
+               rename $old_def_config, $config or
+                      die "Failed rename $old_def_config => $config: $!\n";
+       }
+       my $old_config = $ENV{GIT_CONFIG};
+       $ENV{GIT_CONFIG} = $config;
+       $@ = undef;
+       my @ret = eval {
+               unless (-f $config) {
+                       mkfile($config);
+                       open my $fh, '>', $config or
+                           die "Can't open $config: $!\n";
+                       print $fh "; This file is used internally by ",
+                                 "git-svn\n" or die
+                                 "Couldn't write to $config: $!\n";
+                       print $fh "; You should not have to edit it\n" or
+                             die "Couldn't write to $config: $!\n";
+                       close $fh or die "Couldn't close $config: $!\n";
+               }
+               command('config', @args);
+       };
+       my $err = $@;
+       if (defined $old_config) {
+               $ENV{GIT_CONFIG} = $old_config;
+       } else {
+               delete $ENV{GIT_CONFIG};
+       }
+       die $err if $err;
+       wantarray ? @ret : $ret[0];
+}
+
+sub tmp_index_do {
+       my ($self, $sub) = @_;
+       my $old_index = $ENV{GIT_INDEX_FILE};
+       $ENV{GIT_INDEX_FILE} = $self->{index};
+       $@ = undef;
+       my @ret = eval {
+               my ($dir, $base) = ($self->{index} =~ m#^(.*?)/?([^/]+)$#);
+               mkpath([$dir]) unless -d $dir;
+               &$sub;
+       };
+       my $err = $@;
+       if (defined $old_index) {
+               $ENV{GIT_INDEX_FILE} = $old_index;
+       } else {
+               delete $ENV{GIT_INDEX_FILE};
+       }
+       die $err if $err;
+       wantarray ? @ret : $ret[0];
+}
+
+sub assert_index_clean {
+       my ($self, $treeish) = @_;
+
+       $self->tmp_index_do(sub {
+               command_noisy('read-tree', $treeish) unless -e $self->{index};
+               my $x = command_oneline('write-tree');
+               my ($y) = (command(qw/cat-file commit/, $treeish) =~
+                          /^tree ($::sha1)/mo);
+               return if $y eq $x;
+
+               warn "Index mismatch: $y != $x\nrereading $treeish\n";
+               unlink $self->{index} or die "unlink $self->{index}: $!\n";
+               command_noisy('read-tree', $treeish);
+               $x = command_oneline('write-tree');
+               if ($y ne $x) {
+                       fatal "trees ($treeish) $y != $x\n",
+                             "Something is seriously wrong...";
+               }
+       });
+}
+
+sub get_commit_parents {
+       my ($self, $log_entry) = @_;
+       my (%seen, @ret, @tmp);
+       # legacy support for 'set-tree'; this is only used by set_tree_cb:
+       if (my $ip = $self->{inject_parents}) {
+               if (my $commit = delete $ip->{$log_entry->{revision}}) {
+                       push @tmp, $commit;
+               }
+       }
+       if (my $cur = ::verify_ref($self->refname.'^0')) {
+               push @tmp, $cur;
+       }
+       if (my $ipd = $self->{inject_parents_dcommit}) {
+               if (my $commit = delete $ipd->{$log_entry->{revision}}) {
+                       push @tmp, @$commit;
+               }
+       }
+       push @tmp, $_ foreach (@{$log_entry->{parents}}, @tmp);
+       while (my $p = shift @tmp) {
+               next if $seen{$p};
+               $seen{$p} = 1;
+               push @ret, $p;
+       }
+       @ret;
+}
+
+sub rewrite_root {
+       my ($self) = @_;
+       return $self->{-rewrite_root} if exists $self->{-rewrite_root};
+       my $k = "svn-remote.$self->{repo_id}.rewriteRoot";
+       my $rwr = eval { command_oneline(qw/config --get/, $k) };
+       if ($rwr) {
+               $rwr =~ s#/+$##;
+               if ($rwr !~ m#^[a-z\+]+://#) {
+                       die "$rwr is not a valid URL (key: $k)\n";
+               }
+       }
+       $self->{-rewrite_root} = $rwr;
+}
+
+sub rewrite_uuid {
+       my ($self) = @_;
+       return $self->{-rewrite_uuid} if exists $self->{-rewrite_uuid};
+       my $k = "svn-remote.$self->{repo_id}.rewriteUUID";
+       my $rwid = eval { command_oneline(qw/config --get/, $k) };
+       if ($rwid) {
+               $rwid =~ s#/+$##;
+               if ($rwid !~ m#^[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$#) {
+                       die "$rwid is not a valid UUID (key: $k)\n";
+               }
+       }
+       $self->{-rewrite_uuid} = $rwid;
+}
+
+sub metadata_url {
+       my ($self) = @_;
+       my $url = $self->rewrite_root || $self->url;
+       return canonicalize_url( add_path_to_url( $url, $self->path ) );
+}
+
+sub full_url {
+       my ($self) = @_;
+       return canonicalize_url( add_path_to_url( $self->url, $self->path ) );
+}
+
+sub full_pushurl {
+       my ($self) = @_;
+       if ($self->{pushurl}) {
+               return canonicalize_url( add_path_to_url( $self->{pushurl}, $self->path ) );
+       } else {
+               return $self->full_url;
+       }
+}
+
+sub set_commit_header_env {
+       my ($log_entry) = @_;
+       my %env;
+       foreach my $ned (qw/NAME EMAIL DATE/) {
+               foreach my $ac (qw/AUTHOR COMMITTER/) {
+                       $env{"GIT_${ac}_${ned}"} = $ENV{"GIT_${ac}_${ned}"};
+               }
+       }
+
+       $ENV{GIT_AUTHOR_NAME} = $log_entry->{name};
+       $ENV{GIT_AUTHOR_EMAIL} = $log_entry->{email};
+       $ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = $log_entry->{date};
+
+       $ENV{GIT_COMMITTER_NAME} = (defined $log_entry->{commit_name})
+                                               ? $log_entry->{commit_name}
+                                               : $log_entry->{name};
+       $ENV{GIT_COMMITTER_EMAIL} = (defined $log_entry->{commit_email})
+                                               ? $log_entry->{commit_email}
+                                               : $log_entry->{email};
+       \%env;
+}
+
+sub restore_commit_header_env {
+       my ($env) = @_;
+       foreach my $ned (qw/NAME EMAIL DATE/) {
+               foreach my $ac (qw/AUTHOR COMMITTER/) {
+                       my $k = "GIT_${ac}_${ned}";
+                       if (defined $env->{$k}) {
+                               $ENV{$k} = $env->{$k};
+                       } else {
+                               delete $ENV{$k};
+                       }
+               }
+       }
+}
+
+sub gc {
+       command_noisy('gc', '--auto');
+};
+
+sub do_git_commit {
+       my ($self, $log_entry) = @_;
+       my $lr = $self->last_rev;
+       if (defined $lr && $lr >= $log_entry->{revision}) {
+               die "Last fetched revision of ", $self->refname,
+                   " was r$lr, but we are about to fetch: ",
+                   "r$log_entry->{revision}!\n";
+       }
+       if (my $c = $self->rev_map_get($log_entry->{revision})) {
+               croak "$log_entry->{revision} = $c already exists! ",
+                     "Why are we refetching it?\n";
+       }
+       my $old_env = set_commit_header_env($log_entry);
+       my $tree = $log_entry->{tree};
+       if (!defined $tree) {
+               $tree = $self->tmp_index_do(sub {
+                                           command_oneline('write-tree') });
+       }
+       die "Tree is not a valid sha1: $tree\n" if $tree !~ /^$::sha1$/o;
+
+       my @exec = ('git', 'commit-tree', $tree);
+       foreach ($self->get_commit_parents($log_entry)) {
+               push @exec, '-p', $_;
+       }
+       defined(my $pid = open3(my $msg_fh, my $out_fh, '>&STDERR', @exec))
+                                                                  or croak $!;
+       binmode $msg_fh;
+
+       # we always get UTF-8 from SVN, but we may want our commits in
+       # a different encoding.
+       if (my $enc = Git::config('i18n.commitencoding')) {
+               require Encode;
+               Encode::from_to($log_entry->{log}, 'UTF-8', $enc);
+       }
+       print $msg_fh $log_entry->{log} or croak $!;
+       restore_commit_header_env($old_env);
+       unless ($self->no_metadata) {
+               print $msg_fh "\ngit-svn-id: $log_entry->{metadata}\n"
+                             or croak $!;
+       }
+       $msg_fh->flush == 0 or croak $!;
+       close $msg_fh or croak $!;
+       chomp(my $commit = do { local $/; <$out_fh> });
+       close $out_fh or croak $!;
+       waitpid $pid, 0;
+       croak $? if $?;
+       if ($commit !~ /^$::sha1$/o) {
+               die "Failed to commit, invalid sha1: $commit\n";
+       }
+
+       $self->rev_map_set($log_entry->{revision}, $commit, 1);
+
+       $self->{last_rev} = $log_entry->{revision};
+       $self->{last_commit} = $commit;
+       print "r$log_entry->{revision}" unless $::_q > 1;
+       if (defined $log_entry->{svm_revision}) {
+                print " (\@$log_entry->{svm_revision})" unless $::_q > 1;
+                $self->rev_map_set($log_entry->{svm_revision}, $commit,
+                                  0, $self->svm_uuid);
+       }
+       print " = $commit ($self->{ref_id})\n" unless $::_q > 1;
+       if (--$_gc_nr == 0) {
+               $_gc_nr = $_gc_period;
+               gc();
+       }
+       return $commit;
+}
+
+sub match_paths {
+       my ($self, $paths, $r) = @_;
+       return 1 if $self->path eq '';
+       if (my $path = $paths->{"/".$self->path}) {
+               return ($path->{action} eq 'D') ? 0 : 1;
+       }
+       $self->{path_regex} ||= qr{^/\Q@{[$self->path]}\E/};
+       if (grep /$self->{path_regex}/, keys %$paths) {
+               return 1;
+       }
+       my $c = '';
+       foreach (split m#/#, $self->path) {
+               $c .= "/$_";
+               next unless ($paths->{$c} &&
+                            ($paths->{$c}->{action} =~ /^[AR]$/));
+               if ($self->ra->check_path($self->path, $r) ==
+                   $SVN::Node::dir) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+sub find_parent_branch {
+       my ($self, $paths, $rev) = @_;
+       return undef unless $self->follow_parent;
+       unless (defined $paths) {
+               my $err_handler = $SVN::Error::handler;
+               $SVN::Error::handler = \&Git::SVN::Ra::skip_unknown_revs;
+               $self->ra->get_log([$self->path], $rev, $rev, 0, 1, 1,
+                                  sub { $paths = $_[0] });
+               $SVN::Error::handler = $err_handler;
+       }
+       return undef unless defined $paths;
+
+       # look for a parent from another branch:
+       my @b_path_components = split m#/#, $self->path;
+       my @a_path_components;
+       my $i;
+       while (@b_path_components) {
+               $i = $paths->{'/'.join('/', @b_path_components)};
+               last if $i && defined $i->{copyfrom_path};
+               unshift(@a_path_components, pop(@b_path_components));
+       }
+       return undef unless defined $i && defined $i->{copyfrom_path};
+       my $branch_from = $i->{copyfrom_path};
+       if (@a_path_components) {
+               print STDERR "branch_from: $branch_from => ";
+               $branch_from .= '/'.join('/', @a_path_components);
+               print STDERR $branch_from, "\n";
+       }
+       my $r = $i->{copyfrom_rev};
+       my $repos_root = $self->ra->{repos_root};
+       my $url = $self->ra->url;
+       my $new_url = canonicalize_url( add_path_to_url( $url, $branch_from ) );
+       print STDERR  "Found possible branch point: ",
+                     "$new_url => ", $self->full_url, ", $r\n"
+                     unless $::_q > 1;
+       $branch_from =~ s#^/##;
+       my $gs = $self->other_gs($new_url, $url,
+                                $branch_from, $r, $self->{ref_id});
+       my ($r0, $parent) = $gs->find_rev_before($r, 1);
+       {
+               my ($base, $head);
+               if (!defined $r0 || !defined $parent) {
+                       ($base, $head) = parse_revision_argument(0, $r);
+               } else {
+                       if ($r0 < $r) {
+                               $gs->ra->get_log([$gs->path], $r0 + 1, $r, 1,
+                                       0, 1, sub { $base = $_[1] - 1 });
+                       }
+               }
+               if (defined $base && $base <= $r) {
+                       $gs->fetch($base, $r);
+               }
+               ($r0, $parent) = $gs->find_rev_before($r, 1);
+       }
+       if (defined $r0 && defined $parent) {
+               print STDERR "Found branch parent: ($self->{ref_id}) $parent\n"
+                            unless $::_q > 1;
+               my $ed;
+               if ($self->ra->can_do_switch) {
+                       $self->assert_index_clean($parent);
+                       print STDERR "Following parent with do_switch\n"
+                                    unless $::_q > 1;
+                       # do_switch works with svn/trunk >= r22312, but that
+                       # is not included with SVN 1.4.3 (the latest version
+                       # at the moment), so we can't rely on it
+                       $self->{last_rev} = $r0;
+                       $self->{last_commit} = $parent;
+                       $ed = Git::SVN::Fetcher->new($self, $gs->path);
+                       $gs->ra->gs_do_switch($r0, $rev, $gs,
+                                             $self->full_url, $ed)
+                         or die "SVN connection failed somewhere...\n";
+               } elsif ($self->ra->trees_match($new_url, $r0,
+                                               $self->full_url, $rev)) {
+                       print STDERR "Trees match:\n",
+                                    "  $new_url\@$r0\n",
+                                    "  ${\$self->full_url}\@$rev\n",
+                                    "Following parent with no changes\n"
+                                    unless $::_q > 1;
+                       $self->tmp_index_do(sub {
+                           command_noisy('read-tree', $parent);
+                       });
+                       $self->{last_commit} = $parent;
+               } else {
+                       print STDERR "Following parent with do_update\n"
+                                    unless $::_q > 1;
+                       $ed = Git::SVN::Fetcher->new($self);
+                       $self->ra->gs_do_update($rev, $rev, $self, $ed)
+                         or die "SVN connection failed somewhere...\n";
+               }
+               print STDERR "Successfully followed parent\n" unless $::_q > 1;
+               return $self->make_log_entry($rev, [$parent], $ed);
+       }
+       return undef;
+}
+
+sub do_fetch {
+       my ($self, $paths, $rev) = @_;
+       my $ed;
+       my ($last_rev, @parents);
+       if (my $lc = $self->last_commit) {
+               # we can have a branch that was deleted, then re-added
+               # under the same name but copied from another path, in
+               # which case we'll have multiple parents (we don't
+               # want to break the original ref, nor lose copypath info):
+               if (my $log_entry = $self->find_parent_branch($paths, $rev)) {
+                       push @{$log_entry->{parents}}, $lc;
+                       return $log_entry;
+               }
+               $ed = Git::SVN::Fetcher->new($self);
+               $last_rev = $self->{last_rev};
+               $ed->{c} = $lc;
+               @parents = ($lc);
+       } else {
+               $last_rev = $rev;
+               if (my $log_entry = $self->find_parent_branch($paths, $rev)) {
+                       return $log_entry;
+               }
+               $ed = Git::SVN::Fetcher->new($self);
+       }
+       unless ($self->ra->gs_do_update($last_rev, $rev, $self, $ed)) {
+               die "SVN connection failed somewhere...\n";
+       }
+       $self->make_log_entry($rev, \@parents, $ed);
+}
+
+sub mkemptydirs {
+       my ($self, $r) = @_;
+
+       sub scan {
+               my ($r, $empty_dirs, $line) = @_;
+               if (defined $r && $line =~ /^r(\d+)$/) {
+                       return 0 if $1 > $r;
+               } elsif ($line =~ /^  \+empty_dir: (.+)$/) {
+                       $empty_dirs->{$1} = 1;
+               } elsif ($line =~ /^  \-empty_dir: (.+)$/) {
+                       my @d = grep {m[^\Q$1\E(/|$)]} (keys %$empty_dirs);
+                       delete @$empty_dirs{@d};
+               }
+               1; # continue
+       };
+
+       my %empty_dirs = ();
+       my $gz_file = "$self->{dir}/unhandled.log.gz";
+       if (-f $gz_file) {
+               if (!can_compress()) {
+                       warn "Compress::Zlib could not be found; ",
+                            "empty directories in $gz_file will not be read\n";
+               } else {
+                       my $gz = Compress::Zlib::gzopen($gz_file, "rb") or
+                               die "Unable to open $gz_file: $!\n";
+                       my $line;
+                       while ($gz->gzreadline($line) > 0) {
+                               scan($r, \%empty_dirs, $line) or last;
+                       }
+                       $gz->gzclose;
+               }
+       }
+
+       if (open my $fh, '<', "$self->{dir}/unhandled.log") {
+               binmode $fh or croak "binmode: $!";
+               while (<$fh>) {
+                       scan($r, \%empty_dirs, $_) or last;
+               }
+               close $fh;
+       }
+
+       my $strip = qr/\A\Q@{[$self->path]}\E(?:\/|$)/;
+       foreach my $d (sort keys %empty_dirs) {
+               $d = uri_decode($d);
+               $d =~ s/$strip//;
+               next unless length($d);
+               next if -d $d;
+               if (-e $d) {
+                       warn "$d exists but is not a directory\n";
+               } else {
+                       print "creating empty directory: $d\n";
+                       mkpath([$d]);
+               }
+       }
+}
+
+sub get_untracked {
+       my ($self, $ed) = @_;
+       my @out;
+       my $h = $ed->{empty};
+       foreach (sort keys %$h) {
+               my $act = $h->{$_} ? '+empty_dir' : '-empty_dir';
+               push @out, "  $act: " . uri_encode($_);
+               warn "W: $act: $_\n";
+       }
+       foreach my $t (qw/dir_prop file_prop/) {
+               $h = $ed->{$t} or next;
+               foreach my $path (sort keys %$h) {
+                       my $ppath = $path eq '' ? '.' : $path;
+                       foreach my $prop (sort keys %{$h->{$path}}) {
+                               next if $SKIP_PROP{$prop};
+                               my $v = $h->{$path}->{$prop};
+                               my $t_ppath_prop = "$t: " .
+                                                   uri_encode($ppath) . ' ' .
+                                                   uri_encode($prop);
+                               if (defined $v) {
+                                       push @out, "  +$t_ppath_prop " .
+                                                  uri_encode($v);
+                               } else {
+                                       push @out, "  -$t_ppath_prop";
+                               }
+                       }
+               }
+       }
+       foreach my $t (qw/absent_file absent_directory/) {
+               $h = $ed->{$t} or next;
+               foreach my $parent (sort keys %$h) {
+                       foreach my $path (sort @{$h->{$parent}}) {
+                               push @out, "  $t: " .
+                                          uri_encode("$parent/$path");
+                               warn "W: $t: $parent/$path ",
+                                    "Insufficient permissions?\n";
+                       }
+               }
+       }
+       \@out;
+}
+
+sub get_tz {
+       # some systmes don't handle or mishandle %z, so be creative.
+       my $t = shift || time;
+       my $gm = timelocal(gmtime($t));
+       my $sign = qw( + + - )[ $t <=> $gm ];
+       return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]);
+}
+
+# parse_svn_date(DATE)
+# --------------------
+# Given a date (in UTC) from Subversion, return a string in the format
+# "<TZ Offset> <local date/time>" that Git will use.
+#
+# By default the parsed date will be in UTC; if $Git::SVN::_localtime
+# is true we'll convert it to the local timezone instead.
+sub parse_svn_date {
+       my $date = shift || return '+0000 1970-01-01 00:00:00';
+       my ($Y,$m,$d,$H,$M,$S) = ($date =~ /^(\d{4})\-(\d\d)\-(\d\d)T
+                                           (\d\d)\:(\d\d)\:(\d\d)\.\d*Z$/x) or
+                                        croak "Unable to parse date: $date\n";
+       my $parsed_date;    # Set next.
+
+       if ($Git::SVN::_localtime) {
+               # Translate the Subversion datetime to an epoch time.
+               # Begin by switching ourselves to $date's timezone, UTC.
+               my $old_env_TZ = $ENV{TZ};
+               $ENV{TZ} = 'UTC';
+
+               my $epoch_in_UTC =
+                   POSIX::strftime('%s', $S, $M, $H, $d, $m - 1, $Y - 1900);
+
+               # Determine our local timezone (including DST) at the
+               # time of $epoch_in_UTC.  $Git::SVN::Log::TZ stored the
+               # value of TZ, if any, at the time we were run.
+               if (defined $Git::SVN::Log::TZ) {
+                       $ENV{TZ} = $Git::SVN::Log::TZ;
+               } else {
+                       delete $ENV{TZ};
+               }
+
+               my $our_TZ = get_tz();
+
+               # This converts $epoch_in_UTC into our local timezone.
+               my ($sec, $min, $hour, $mday, $mon, $year,
+                   $wday, $yday, $isdst) = localtime($epoch_in_UTC);
+
+               $parsed_date = sprintf('%s %04d-%02d-%02d %02d:%02d:%02d',
+                                      $our_TZ, $year + 1900, $mon + 1,
+                                      $mday, $hour, $min, $sec);
+
+               # Reset us to the timezone in effect when we entered
+               # this routine.
+               if (defined $old_env_TZ) {
+                       $ENV{TZ} = $old_env_TZ;
+               } else {
+                       delete $ENV{TZ};
+               }
+       } else {
+               $parsed_date = "+0000 $Y-$m-$d $H:$M:$S";
+       }
+
+       return $parsed_date;
+}
+
+sub other_gs {
+       my ($self, $new_url, $url,
+           $branch_from, $r, $old_ref_id) = @_;
+       my $gs = Git::SVN->find_by_url($new_url, $url, $branch_from);
+       unless ($gs) {
+               my $ref_id = $old_ref_id;
+               $ref_id =~ s/\@\d+-*$//;
+               $ref_id .= "\@$r";
+               # just grow a tail if we're not unique enough :x
+               $ref_id .= '-' while find_ref($ref_id);
+               my ($u, $p, $repo_id) = ($new_url, '', $ref_id);
+               if ($u =~ s#^\Q$url\E(/|$)##) {
+                       $p = $u;
+                       $u = $url;
+                       $repo_id = $self->{repo_id};
+               }
+               while (1) {
+                       # It is possible to tag two different subdirectories at
+                       # the same revision.  If the url for an existing ref
+                       # does not match, we must either find a ref with a
+                       # matching url or create a new ref by growing a tail.
+                       $gs = Git::SVN->init($u, $p, $repo_id, $ref_id, 1);
+                       my (undef, $max_commit) = $gs->rev_map_max(1);
+                       last if (!$max_commit);
+                       my ($url) = ::cmt_metadata($max_commit);
+                       last if ($url eq $gs->metadata_url);
+                       $ref_id .= '-';
+               }
+               print STDERR "Initializing parent: $ref_id\n" unless $::_q > 1;
+       }
+       $gs
+}
+
+sub call_authors_prog {
+       my ($orig_author) = @_;
+       $orig_author = command_oneline('rev-parse', '--sq-quote', $orig_author);
+       my $author = `$::_authors_prog $orig_author`;
+       if ($? != 0) {
+               die "$::_authors_prog failed with exit code $?\n"
+       }
+       if ($author =~ /^\s*(.+?)\s*<(.*)>\s*$/) {
+               my ($name, $email) = ($1, $2);
+               $email = undef if length $2 == 0;
+               return [$name, $email];
+       } else {
+               die "Author: $orig_author: $::_authors_prog returned "
+                       . "invalid author format: $author\n";
+       }
+}
+
+sub check_author {
+       my ($author) = @_;
+       if (!defined $author || length $author == 0) {
+               $author = '(no author)';
+       }
+       if (!defined $::users{$author}) {
+               if (defined $::_authors_prog) {
+                       $::users{$author} = call_authors_prog($author);
+               } elsif (defined $::_authors) {
+                       die "Author: $author not defined in $::_authors file\n";
+               }
+       }
+       $author;
+}
+
+sub find_extra_svk_parents {
+       my ($self, $ed, $tickets, $parents) = @_;
+       # aha!  svk:merge property changed...
+       my @tickets = split "\n", $tickets;
+       my @known_parents;
+       for my $ticket ( @tickets ) {
+               my ($uuid, $path, $rev) = split /:/, $ticket;
+               if ( $uuid eq $self->ra_uuid ) {
+                       my $repos_root = $self->url;
+                       my $branch_from = $path;
+                       $branch_from =~ s{^/}{};
+                       my $gs = $self->other_gs(add_path_to_url( $repos_root, $branch_from ),
+                                                $repos_root,
+                                                $branch_from,
+                                                $rev,
+                                                $self->{ref_id});
+                       if ( my $commit = $gs->rev_map_get($rev, $uuid) ) {
+                               # wahey!  we found it, but it might be
+                               # an old one (!)
+                               push @known_parents, [ $rev, $commit ];
+                       }
+               }
+       }
+       # Ordering matters; highest-numbered commit merge tickets
+       # first, as they may account for later merge ticket additions
+       # or changes.
+       @known_parents = map {$_->[1]} sort {$b->[0] <=> $a->[0]} @known_parents;
+       for my $parent ( @known_parents ) {
+               my @cmd = ('rev-list', $parent, map { "^$_" } @$parents );
+               my ($msg_fh, $ctx) = command_output_pipe(@cmd);
+               my $new;
+               while ( <$msg_fh> ) {
+                       $new=1;last;
+               }
+               command_close_pipe($msg_fh, $ctx);
+               if ( $new ) {
+                       print STDERR
+                           "Found merge parent (svk:merge ticket): $parent\n";
+                       push @$parents, $parent;
+               }
+       }
+}
+
+sub lookup_svn_merge {
+       my $uuid = shift;
+       my $url = shift;
+       my $merge = shift;
+
+       my ($source, $revs) = split ":", $merge;
+       my $path = $source;
+       $path =~ s{^/}{};
+       my $gs = Git::SVN->find_by_url($url.$source, $url, $path);
+       if ( !$gs ) {
+               warn "Couldn't find revmap for $url$source\n";
+               return;
+       }
+       my @ranges = split ",", $revs;
+       my ($tip, $tip_commit);
+       my @merged_commit_ranges;
+       # find the tip
+       for my $range ( @ranges ) {
+               my ($bottom, $top) = split "-", $range;
+               $top ||= $bottom;
+               my $bottom_commit = $gs->find_rev_after( $bottom, 1, $top );
+               my $top_commit = $gs->find_rev_before( $top, 1, $bottom );
+
+               unless ($top_commit and $bottom_commit) {
+                       warn "W:unknown path/rev in svn:mergeinfo "
+                               ."dirprop: $source:$range\n";
+                       next;
+               }
+
+               if (scalar(command('rev-parse', "$bottom_commit^@"))) {
+                       push @merged_commit_ranges,
+                            "$bottom_commit^..$top_commit";
+               } else {
+                       push @merged_commit_ranges, "$top_commit";
+               }
+
+               if ( !defined $tip or $top > $tip ) {
+                       $tip = $top;
+                       $tip_commit = $top_commit;
+               }
+       }
+       return ($tip_commit, @merged_commit_ranges);
+}
+
+sub _rev_list {
+       my ($msg_fh, $ctx) = command_output_pipe(
+               "rev-list", @_,
+              );
+       my @rv;
+       while ( <$msg_fh> ) {
+               chomp;
+               push @rv, $_;
+       }
+       command_close_pipe($msg_fh, $ctx);
+       @rv;
+}
+
+sub check_cherry_pick {
+       my $base = shift;
+       my $tip = shift;
+       my $parents = shift;
+       my @ranges = @_;
+       my %commits = map { $_ => 1 }
+               _rev_list("--no-merges", $tip, "--not", $base, @$parents, "--");
+       for my $range ( @ranges ) {
+               delete @commits{_rev_list($range, "--")};
+       }
+       for my $commit (keys %commits) {
+               if (has_no_changes($commit)) {
+                       delete $commits{$commit};
+               }
+       }
+       return (keys %commits);
+}
+
+sub has_no_changes {
+       my $commit = shift;
+
+       my @revs = split / /, command_oneline(
+               qw(rev-list --parents -1 -m), $commit);
+
+       # Commits with no parents, e.g. the start of a partial branch,
+       # have changes by definition.
+       return 1 if (@revs < 2);
+
+       # Commits with multiple parents, e.g a merge, have no changes
+       # by definition.
+       return 0 if (@revs > 2);
+
+       return (command_oneline("rev-parse", "$commit^{tree}") eq
+               command_oneline("rev-parse", "$commit~1^{tree}"));
+}
+
+sub tie_for_persistent_memoization {
+       my $hash = shift;
+       my $path = shift;
+
+       if ($can_use_yaml) {
+               tie %$hash => 'Git::SVN::Memoize::YAML', "$path.yaml";
+       } else {
+               tie %$hash => 'Memoize::Storable', "$path.db", 'nstore';
+       }
+}
+
+# The GIT_DIR environment variable is not always set until after the command
+# line arguments are processed, so we can't memoize in a BEGIN block.
+{
+       my $memoized = 0;
+
+       sub memoize_svn_mergeinfo_functions {
+               return if $memoized;
+               $memoized = 1;
+
+               my $cache_path = "$ENV{GIT_DIR}/svn/.caches/";
+               mkpath([$cache_path]) unless -d $cache_path;
+
+               my %lookup_svn_merge_cache;
+               my %check_cherry_pick_cache;
+               my %has_no_changes_cache;
+
+               tie_for_persistent_memoization(\%lookup_svn_merge_cache,
+                   "$cache_path/lookup_svn_merge");
+               memoize 'lookup_svn_merge',
+                       SCALAR_CACHE => 'FAULT',
+                       LIST_CACHE => ['HASH' => \%lookup_svn_merge_cache],
+               ;
+
+               tie_for_persistent_memoization(\%check_cherry_pick_cache,
+                   "$cache_path/check_cherry_pick");
+               memoize 'check_cherry_pick',
+                       SCALAR_CACHE => 'FAULT',
+                       LIST_CACHE => ['HASH' => \%check_cherry_pick_cache],
+               ;
+
+               tie_for_persistent_memoization(\%has_no_changes_cache,
+                   "$cache_path/has_no_changes");
+               memoize 'has_no_changes',
+                       SCALAR_CACHE => ['HASH' => \%has_no_changes_cache],
+                       LIST_CACHE => 'FAULT',
+               ;
+       }
+
+       sub unmemoize_svn_mergeinfo_functions {
+               return if not $memoized;
+               $memoized = 0;
+
+               Memoize::unmemoize 'lookup_svn_merge';
+               Memoize::unmemoize 'check_cherry_pick';
+               Memoize::unmemoize 'has_no_changes';
+       }
+
+       sub clear_memoized_mergeinfo_caches {
+               die "Only call this method in non-memoized context" if ($memoized);
+
+               my $cache_path = "$ENV{GIT_DIR}/svn/.caches/";
+               return unless -d $cache_path;
+
+               for my $cache_file (("$cache_path/lookup_svn_merge",
+                                    "$cache_path/check_cherry_pick",
+                                    "$cache_path/has_no_changes")) {
+                       for my $suffix (qw(yaml db)) {
+                               my $file = "$cache_file.$suffix";
+                               next unless -e $file;
+                               unlink($file) or die "unlink($file) failed: $!\n";
+                       }
+               }
+       }
+
+
+       Memoize::memoize 'Git::SVN::repos_root';
+}
+
+END {
+       # Force cache writeout explicitly instead of waiting for
+       # global destruction to avoid segfault in Storable:
+       # http://rt.cpan.org/Public/Bug/Display.html?id=36087
+       unmemoize_svn_mergeinfo_functions();
+}
+
+sub parents_exclude {
+       my $parents = shift;
+       my @commits = @_;
+       return unless @commits;
+
+       my @excluded;
+       my $excluded;
+       do {
+               my @cmd = ('rev-list', "-1", @commits, "--not", @$parents );
+               $excluded = command_oneline(@cmd);
+               if ( $excluded ) {
+                       my @new;
+                       my $found;
+                       for my $commit ( @commits ) {
+                               if ( $commit eq $excluded ) {
+                                       push @excluded, $commit;
+                                       $found++;
+                                       last;
+                               }
+                               else {
+                                       push @new, $commit;
+                               }
+                       }
+                       die "saw commit '$excluded' in rev-list output, "
+                               ."but we didn't ask for that commit (wanted: @commits --not @$parents)"
+                                       unless $found;
+                       @commits = @new;
+               }
+       }
+               while ($excluded and @commits);
+
+       return @excluded;
+}
+
+
+# note: this function should only be called if the various dirprops
+# have actually changed
+sub find_extra_svn_parents {
+       my ($self, $ed, $mergeinfo, $parents) = @_;
+       # aha!  svk:merge property changed...
+
+       memoize_svn_mergeinfo_functions();
+
+       # We first search for merged tips which are not in our
+       # history.  Then, we figure out which git revisions are in
+       # that tip, but not this revision.  If all of those revisions
+       # are now marked as merge, we can add the tip as a parent.
+       my @merges = split "\n", $mergeinfo;
+       my @merge_tips;
+       my $url = $self->url;
+       my $uuid = $self->ra_uuid;
+       my %ranges;
+       for my $merge ( @merges ) {
+               my ($tip_commit, @ranges) =
+                       lookup_svn_merge( $uuid, $url, $merge );
+               unless (!$tip_commit or
+                               grep { $_ eq $tip_commit } @$parents ) {
+                       push @merge_tips, $tip_commit;
+                       $ranges{$tip_commit} = \@ranges;
+               } else {
+                       push @merge_tips, undef;
+               }
+       }
+
+       my %excluded = map { $_ => 1 }
+               parents_exclude($parents, grep { defined } @merge_tips);
+
+       # check merge tips for new parents
+       my @new_parents;
+       for my $merge_tip ( @merge_tips ) {
+               my $spec = shift @merges;
+               next unless $merge_tip and $excluded{$merge_tip};
+
+               my $ranges = $ranges{$merge_tip};
+
+               # check out 'new' tips
+               my $merge_base;
+               eval {
+                       $merge_base = command_oneline(
+                               "merge-base",
+                               @$parents, $merge_tip,
+                       );
+               };
+               if ($@) {
+                       die "An error occurred during merge-base"
+                               unless $@->isa("Git::Error::Command");
+
+                       warn "W: Cannot find common ancestor between ".
+                            "@$parents and $merge_tip. Ignoring merge info.\n";
+                       next;
+               }
+
+               # double check that there are no missing non-merge commits
+               my (@incomplete) = check_cherry_pick(
+                       $merge_base, $merge_tip,
+                       $parents,
+                       @$ranges,
+                      );
+
+               if ( @incomplete ) {
+                       warn "W:svn cherry-pick ignored ($spec) - missing "
+                               .@incomplete." commit(s) (eg $incomplete[0])\n";
+               } else {
+                       warn
+                               "Found merge parent (svn:mergeinfo prop): ",
+                                       $merge_tip, "\n";
+                       push @new_parents, $merge_tip;
+               }
+       }
+
+       # cater for merges which merge commits from multiple branches
+       if ( @new_parents > 1 ) {
+               for ( my $i = 0; $i <= $#new_parents; $i++ ) {
+                       for ( my $j = 0; $j <= $#new_parents; $j++ ) {
+                               next if $i == $j;
+                               next unless $new_parents[$i];
+                               next unless $new_parents[$j];
+                               my $revs = command_oneline(
+                                       "rev-list", "-1",
+                                       "$new_parents[$i]..$new_parents[$j]",
+                                      );
+                               if ( !$revs ) {
+                                       undef($new_parents[$j]);
+                               }
+                       }
+               }
+       }
+       push @$parents, grep { defined } @new_parents;
+}
+
+sub make_log_entry {
+       my ($self, $rev, $parents, $ed) = @_;
+       my $untracked = $self->get_untracked($ed);
+
+       my @parents = @$parents;
+       my $ps = $ed->{path_strip} || "";
+       for my $path ( grep { m/$ps/ } %{$ed->{dir_prop}} ) {
+               my $props = $ed->{dir_prop}{$path};
+               if ( $props->{"svk:merge"} ) {
+                       $self->find_extra_svk_parents
+                               ($ed, $props->{"svk:merge"}, \@parents);
+               }
+               if ( $props->{"svn:mergeinfo"} ) {
+                       $self->find_extra_svn_parents
+                               ($ed,
+                                $props->{"svn:mergeinfo"},
+                                \@parents);
+               }
+       }
+
+       open my $un, '>>', "$self->{dir}/unhandled.log" or croak $!;
+       print $un "r$rev\n" or croak $!;
+       print $un $_, "\n" foreach @$untracked;
+       my %log_entry = ( parents => \@parents, revision => $rev,
+                         log => '');
+
+       my $headrev;
+       my $logged = delete $self->{logged_rev_props};
+       if (!$logged || $self->{-want_revprops}) {
+               my $rp = $self->ra->rev_proplist($rev);
+               foreach (sort keys %$rp) {
+                       my $v = $rp->{$_};
+                       if (/^svn:(author|date|log)$/) {
+                               $log_entry{$1} = $v;
+                       } elsif ($_ eq 'svm:headrev') {
+                               $headrev = $v;
+                       } else {
+                               print $un "  rev_prop: ", uri_encode($_), ' ',
+                                         uri_encode($v), "\n";
+                       }
+               }
+       } else {
+               map { $log_entry{$_} = $logged->{$_} } keys %$logged;
+       }
+       close $un or croak $!;
+
+       $log_entry{date} = parse_svn_date($log_entry{date});
+       $log_entry{log} .= "\n";
+       my $author = $log_entry{author} = check_author($log_entry{author});
+       my ($name, $email) = defined $::users{$author} ? @{$::users{$author}}
+                                                      : ($author, undef);
+
+       my ($commit_name, $commit_email) = ($name, $email);
+       if ($_use_log_author) {
+               my $name_field;
+               if ($log_entry{log} =~ /From:\s+(.*\S)\s*\n/i) {
+                       $name_field = $1;
+               } elsif ($log_entry{log} =~ /Signed-off-by:\s+(.*\S)\s*\n/i) {
+                       $name_field = $1;
+               }
+               if (!defined $name_field) {
+                       if (!defined $email) {
+                               $email = $name;
+                       }
+               } elsif ($name_field =~ /(.*?)\s+<(.*)>/) {
+                       ($name, $email) = ($1, $2);
+               } elsif ($name_field =~ /(.*)@/) {
+                       ($name, $email) = ($1, $name_field);
+               } else {
+                       ($name, $email) = ($name_field, $name_field);
+               }
+       }
+       if (defined $headrev && $self->use_svm_props) {
+               if ($self->rewrite_root) {
+                       die "Can't have both 'useSvmProps' and 'rewriteRoot' ",
+                           "options set!\n";
+               }
+               if ($self->rewrite_uuid) {
+                       die "Can't have both 'useSvmProps' and 'rewriteUUID' ",
+                           "options set!\n";
+               }
+               my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$}i;
+               # we don't want "SVM: initializing mirror for junk" ...
+               return undef if $r == 0;
+               my $svm = $self->svm;
+               if ($uuid ne $svm->{uuid}) {
+                       die "UUID mismatch on SVM path:\n",
+                           "expected: $svm->{uuid}\n",
+                           "     got: $uuid\n";
+               }
+               my $full_url = $self->full_url;
+               $full_url =~ s#^\Q$svm->{replace}\E(/|$)#$svm->{source}$1# or
+                            die "Failed to replace '$svm->{replace}' with ",
+                                "'$svm->{source}' in $full_url\n";
+               # throw away username for storing in records
+               remove_username($full_url);
+               $log_entry{metadata} = "$full_url\@$r $uuid";
+               $log_entry{svm_revision} = $r;
+               $email ||= "$author\@$uuid";
+               $commit_email ||= "$author\@$uuid";
+       } elsif ($self->use_svnsync_props) {
+               my $full_url = canonicalize_url(
+                       add_path_to_url( $self->svnsync->{url}, $self->path )
+               );
+               remove_username($full_url);
+               my $uuid = $self->svnsync->{uuid};
+               $log_entry{metadata} = "$full_url\@$rev $uuid";
+               $email ||= "$author\@$uuid";
+               $commit_email ||= "$author\@$uuid";
+       } else {
+               my $url = $self->metadata_url;
+               remove_username($url);
+               my $uuid = $self->rewrite_uuid || $self->ra->get_uuid;
+               $log_entry{metadata} = "$url\@$rev " . $uuid;
+               $email ||= "$author\@" . $uuid;
+               $commit_email ||= "$author\@" . $uuid;
+       }
+       $log_entry{name} = $name;
+       $log_entry{email} = $email;
+       $log_entry{commit_name} = $commit_name;
+       $log_entry{commit_email} = $commit_email;
+       \%log_entry;
+}
+
+sub fetch {
+       my ($self, $min_rev, $max_rev, @parents) = @_;
+       my ($last_rev, $last_commit) = $self->last_rev_commit;
+       my ($base, $head) = $self->get_fetch_range($min_rev, $max_rev);
+       $self->ra->gs_fetch_loop_common($base, $head, [$self]);
+}
+
+sub set_tree_cb {
+       my ($self, $log_entry, $tree, $rev, $date, $author) = @_;
+       $self->{inject_parents} = { $rev => $tree };
+       $self->fetch(undef, undef);
+}
+
+sub set_tree {
+       my ($self, $tree) = (shift, shift);
+       my $log_entry = ::get_commit_entry($tree);
+       unless ($self->{last_rev}) {
+               fatal("Must have an existing revision to commit");
+       }
+       my %ed_opts = ( r => $self->{last_rev},
+                       log => $log_entry->{log},
+                       ra => $self->ra,
+                       tree_a => $self->{last_commit},
+                       tree_b => $tree,
+                       editor_cb => sub {
+                              $self->set_tree_cb($log_entry, $tree, @_) },
+                       svn_path => $self->path );
+       if (!Git::SVN::Editor->new(\%ed_opts)->apply_diff) {
+               print "No changes\nr$self->{last_rev} = $tree\n";
+       }
+}
+
+sub rebuild_from_rev_db {
+       my ($self, $path) = @_;
+       my $r = -1;
+       open my $fh, '<', $path or croak "open: $!";
+       binmode $fh or croak "binmode: $!";
+       while (<$fh>) {
+               length($_) == 41 or croak "inconsistent size in ($_) != 41";
+               chomp($_);
+               ++$r;
+               next if $_ eq ('0' x 40);
+               $self->rev_map_set($r, $_);
+               print "r$r = $_\n";
+       }
+       close $fh or croak "close: $!";
+       unlink $path or croak "unlink: $!";
+}
+
+sub rebuild {
+       my ($self) = @_;
+       my $map_path = $self->map_path;
+       my $partial = (-e $map_path && ! -z $map_path);
+       return unless ::verify_ref($self->refname.'^0');
+       if (!$partial && ($self->use_svm_props || $self->no_metadata)) {
+               my $rev_db = $self->rev_db_path;
+               $self->rebuild_from_rev_db($rev_db);
+               if ($self->use_svm_props) {
+                       my $svm_rev_db = $self->rev_db_path($self->svm_uuid);
+                       $self->rebuild_from_rev_db($svm_rev_db);
+               }
+               $self->unlink_rev_db_symlink;
+               return;
+       }
+       print "Rebuilding $map_path ...\n" if (!$partial);
+       my ($base_rev, $head) = ($partial ? $self->rev_map_max_norebuild(1) :
+               (undef, undef));
+       my ($log, $ctx) =
+           command_output_pipe(qw/rev-list --pretty=raw --reverse/,
+                               ($head ? "$head.." : "") . $self->refname,
+                               '--');
+       my $metadata_url = $self->metadata_url;
+       remove_username($metadata_url);
+       my $svn_uuid = $self->rewrite_uuid || $self->ra_uuid;
+       my $c;
+       while (<$log>) {
+               if ( m{^commit ($::sha1)$} ) {
+                       $c = $1;
+                       next;
+               }
+               next unless s{^\s*(git-svn-id:)}{$1};
+               my ($url, $rev, $uuid) = ::extract_metadata($_);
+               remove_username($url);
+
+               # ignore merges (from set-tree)
+               next if (!defined $rev || !$uuid);
+
+               # if we merged or otherwise started elsewhere, this is
+               # how we break out of it
+               if (($uuid ne $svn_uuid) ||
+                   ($metadata_url && $url && ($url ne $metadata_url))) {
+                       next;
+               }
+               if ($partial && $head) {
+                       print "Partial-rebuilding $map_path ...\n";
+                       print "Currently at $base_rev = $head\n";
+                       $head = undef;
+               }
+
+               $self->rev_map_set($rev, $c);
+               print "r$rev = $c\n";
+       }
+       command_close_pipe($log, $ctx);
+       print "Done rebuilding $map_path\n" if (!$partial || !$head);
+       my $rev_db_path = $self->rev_db_path;
+       if (-f $self->rev_db_path) {
+               unlink $self->rev_db_path or croak "unlink: $!";
+       }
+       $self->unlink_rev_db_symlink;
+}
+
+# rev_map:
+# Tie::File seems to be prone to offset errors if revisions get sparse,
+# it's not that fast, either.  Tie::File is also not in Perl 5.6.  So
+# one of my favorite modules is out :<  Next up would be one of the DBM
+# modules, but I'm not sure which is most portable...
+#
+# This is the replacement for the rev_db format, which was too big
+# and inefficient for large repositories with a lot of sparse history
+# (mainly tags)
+#
+# The format is this:
+#   - 24 bytes for every record,
+#     * 4 bytes for the integer representing an SVN revision number
+#     * 20 bytes representing the sha1 of a git commit
+#   - No empty padding records like the old format
+#     (except the last record, which can be overwritten)
+#   - new records are written append-only since SVN revision numbers
+#     increase monotonically
+#   - lookups on SVN revision number are done via a binary search
+#   - Piping the file to xxd -c24 is a good way of dumping it for
+#     viewing or editing (piped back through xxd -r), should the need
+#     ever arise.
+#   - The last record can be padding revision with an all-zero sha1
+#     This is used to optimize fetch performance when using multiple
+#     "fetch" directives in .git/config
+#
+# These files are disposable unless noMetadata or useSvmProps is set
+
+sub _rev_map_set {
+       my ($fh, $rev, $commit) = @_;
+
+       binmode $fh or croak "binmode: $!";
+       my $size = (stat($fh))[7];
+       ($size % 24) == 0 or croak "inconsistent size: $size";
+
+       my $wr_offset = 0;
+       if ($size > 0) {
+               sysseek($fh, -24, SEEK_END) or croak "seek: $!";
+               my $read = sysread($fh, my $buf, 24) or croak "read: $!";
+               $read == 24 or croak "read only $read bytes (!= 24)";
+               my ($last_rev, $last_commit) = unpack(rev_map_fmt, $buf);
+               if ($last_commit eq ('0' x40)) {
+                       if ($size >= 48) {
+                               sysseek($fh, -48, SEEK_END) or croak "seek: $!";
+                               $read = sysread($fh, $buf, 24) or
+                                   croak "read: $!";
+                               $read == 24 or
+                                   croak "read only $read bytes (!= 24)";
+                               ($last_rev, $last_commit) =
+                                   unpack(rev_map_fmt, $buf);
+                               if ($last_commit eq ('0' x40)) {
+                                       croak "inconsistent .rev_map\n";
+                               }
+                       }
+                       if ($last_rev >= $rev) {
+                               croak "last_rev is higher!: $last_rev >= $rev";
+                       }
+                       $wr_offset = -24;
+               }
+       }
+       sysseek($fh, $wr_offset, SEEK_END) or croak "seek: $!";
+       syswrite($fh, pack(rev_map_fmt, $rev, $commit), 24) == 24 or
+         croak "write: $!";
+}
+
+sub _rev_map_reset {
+       my ($fh, $rev, $commit) = @_;
+       my $c = _rev_map_get($fh, $rev);
+       $c eq $commit or die "_rev_map_reset(@_) commit $c does not match!\n";
+       my $offset = sysseek($fh, 0, SEEK_CUR) or croak "seek: $!";
+       truncate $fh, $offset or croak "truncate: $!";
+}
+
+sub mkfile {
+       my ($path) = @_;
+       unless (-e $path) {
+               my ($dir, $base) = ($path =~ m#^(.*?)/?([^/]+)$#);
+               mkpath([$dir]) unless -d $dir;
+               open my $fh, '>>', $path or die "Couldn't create $path: $!\n";
+               close $fh or die "Couldn't close (create) $path: $!\n";
+       }
+}
+
+sub rev_map_set {
+       my ($self, $rev, $commit, $update_ref, $uuid) = @_;
+       defined $commit or die "missing arg3\n";
+       length $commit == 40 or die "arg3 must be a full SHA1 hexsum\n";
+       my $db = $self->map_path($uuid);
+       my $db_lock = "$db.lock";
+       my $sigmask;
+       $update_ref ||= 0;
+       if ($update_ref) {
+               $sigmask = POSIX::SigSet->new();
+               my $signew = POSIX::SigSet->new(SIGINT, SIGHUP, SIGTERM,
+                       SIGALRM, SIGUSR1, SIGUSR2);
+               sigprocmask(SIG_BLOCK, $signew, $sigmask) or
+                       croak "Can't block signals: $!";
+       }
+       mkfile($db);
+
+       $LOCKFILES{$db_lock} = 1;
+       my $sync;
+       # both of these options make our .rev_db file very, very important
+       # and we can't afford to lose it because rebuild() won't work
+       if ($self->use_svm_props || $self->no_metadata) {
+               $sync = 1;
+               copy($db, $db_lock) or die "rev_map_set(@_): ",
+                                          "Failed to copy: ",
+                                          "$db => $db_lock ($!)\n";
+       } else {
+               rename $db, $db_lock or die "rev_map_set(@_): ",
+                                           "Failed to rename: ",
+                                           "$db => $db_lock ($!)\n";
+       }
+
+       sysopen(my $fh, $db_lock, O_RDWR | O_CREAT)
+            or croak "Couldn't open $db_lock: $!\n";
+       if ($update_ref eq 'reset') {
+               clear_memoized_mergeinfo_caches();
+               _rev_map_reset($fh, $rev, $commit);
+       } else {
+               _rev_map_set($fh, $rev, $commit);
+       }
+
+       if ($sync) {
+               $fh->flush or die "Couldn't flush $db_lock: $!\n";
+               $fh->sync or die "Couldn't sync $db_lock: $!\n";
+       }
+       close $fh or croak $!;
+       if ($update_ref) {
+               $_head = $self;
+               my $note = "";
+               $note = " ($update_ref)" if ($update_ref !~ /^\d*$/);
+               command_noisy('update-ref', '-m', "r$rev$note",
+                             $self->refname, $commit);
+       }
+       rename $db_lock, $db or die "rev_map_set(@_): ", "Failed to rename: ",
+                                   "$db_lock => $db ($!)\n";
+       delete $LOCKFILES{$db_lock};
+       if ($update_ref) {
+               sigprocmask(SIG_SETMASK, $sigmask) or
+                       croak "Can't restore signal mask: $!";
+       }
+}
+
+# If want_commit, this will return an array of (rev, commit) where
+# commit _must_ be a valid commit in the archive.
+# Otherwise, it'll return the max revision (whether or not the
+# commit is valid or just a 0x40 placeholder).
+sub rev_map_max {
+       my ($self, $want_commit) = @_;
+       $self->rebuild;
+       my ($r, $c) = $self->rev_map_max_norebuild($want_commit);
+       $want_commit ? ($r, $c) : $r;
+}
+
+sub rev_map_max_norebuild {
+       my ($self, $want_commit) = @_;
+       my $map_path = $self->map_path;
+       stat $map_path or return $want_commit ? (0, undef) : 0;
+       sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
+       binmode $fh or croak "binmode: $!";
+       my $size = (stat($fh))[7];
+       ($size % 24) == 0 or croak "inconsistent size: $size";
+
+       if ($size == 0) {
+               close $fh or croak "close: $!";
+               return $want_commit ? (0, undef) : 0;
+       }
+
+       sysseek($fh, -24, SEEK_END) or croak "seek: $!";
+       sysread($fh, my $buf, 24) == 24 or croak "read: $!";
+       my ($r, $c) = unpack(rev_map_fmt, $buf);
+       if ($want_commit && $c eq ('0' x40)) {
+               if ($size < 48) {
+                       return $want_commit ? (0, undef) : 0;
+               }
+               sysseek($fh, -48, SEEK_END) or croak "seek: $!";
+               sysread($fh, $buf, 24) == 24 or croak "read: $!";
+               ($r, $c) = unpack(rev_map_fmt, $buf);
+               if ($c eq ('0'x40)) {
+                       croak "Penultimate record is all-zeroes in $map_path";
+               }
+       }
+       close $fh or croak "close: $!";
+       $want_commit ? ($r, $c) : $r;
+}
+
+sub rev_map_get {
+       my ($self, $rev, $uuid) = @_;
+       my $map_path = $self->map_path($uuid);
+       return undef unless -e $map_path;
+
+       sysopen(my $fh, $map_path, O_RDONLY) or croak "open: $!";
+       my $c = _rev_map_get($fh, $rev);
+       close($fh) or croak "close: $!";
+       $c
+}
+
+sub _rev_map_get {
+       my ($fh, $rev) = @_;
+
+       binmode $fh or croak "binmode: $!";
+       my $size = (stat($fh))[7];
+       ($size % 24) == 0 or croak "inconsistent size: $size";
+
+       if ($size == 0) {
+               return undef;
+       }
+
+       my ($l, $u) = (0, $size - 24);
+       my ($r, $c, $buf);
+
+       while ($l <= $u) {
+               my $i = int(($l/24 + $u/24) / 2) * 24;
+               sysseek($fh, $i, SEEK_SET) or croak "seek: $!";
+               sysread($fh, my $buf, 24) == 24 or croak "read: $!";
+               my ($r, $c) = unpack(rev_map_fmt, $buf);
+
+               if ($r < $rev) {
+                       $l = $i + 24;
+               } elsif ($r > $rev) {
+                       $u = $i - 24;
+               } else { # $r == $rev
+                       return $c eq ('0' x 40) ? undef : $c;
+               }
+       }
+       undef;
+}
+
+# Finds the first svn revision that exists on (if $eq_ok is true) or
+# before $rev for the current branch.  It will not search any lower
+# than $min_rev.  Returns the git commit hash and svn revision number
+# if found, else (undef, undef).
+sub find_rev_before {
+       my ($self, $rev, $eq_ok, $min_rev) = @_;
+       --$rev unless $eq_ok;
+       $min_rev ||= 1;
+       my $max_rev = $self->rev_map_max;
+       $rev = $max_rev if ($rev > $max_rev);
+       while ($rev >= $min_rev) {
+               if (my $c = $self->rev_map_get($rev)) {
+                       return ($rev, $c);
+               }
+               --$rev;
+       }
+       return (undef, undef);
+}
+
+# Finds the first svn revision that exists on (if $eq_ok is true) or
+# after $rev for the current branch.  It will not search any higher
+# than $max_rev.  Returns the git commit hash and svn revision number
+# if found, else (undef, undef).
+sub find_rev_after {
+       my ($self, $rev, $eq_ok, $max_rev) = @_;
+       ++$rev unless $eq_ok;
+       $max_rev ||= $self->rev_map_max;
+       while ($rev <= $max_rev) {
+               if (my $c = $self->rev_map_get($rev)) {
+                       return ($rev, $c);
+               }
+               ++$rev;
+       }
+       return (undef, undef);
+}
+
+sub _new {
+       my ($class, $repo_id, $ref_id, $path) = @_;
+       unless (defined $repo_id && length $repo_id) {
+               $repo_id = $default_repo_id;
+       }
+       unless (defined $ref_id && length $ref_id) {
+               # Access the prefix option from the git-svn main program if it's loaded.
+               my $prefix = defined &::opt_prefix ? ::opt_prefix() : "";
+               $_[2] = $ref_id =
+                            "refs/remotes/$prefix$default_ref_id";
+       }
+       $_[1] = $repo_id;
+       my $dir = "$ENV{GIT_DIR}/svn/$ref_id";
+
+       # Older repos imported by us used $GIT_DIR/svn/foo instead of
+       # $GIT_DIR/svn/refs/remotes/foo when tracking refs/remotes/foo
+       if ($ref_id =~ m{^refs/remotes/(.*)}) {
+               my $old_dir = "$ENV{GIT_DIR}/svn/$1";
+               if (-d $old_dir && ! -d $dir) {
+                       $dir = $old_dir;
+               }
+       }
+
+       $_[3] = $path = '' unless (defined $path);
+       mkpath([$dir]);
+       my $obj = bless {
+               ref_id => $ref_id, dir => $dir, index => "$dir/index",
+               config => "$ENV{GIT_DIR}/svn/config",
+               map_root => "$dir/.rev_map", repo_id => $repo_id }, $class;
+
+       # Ensure it gets canonicalized
+       $obj->path($path);
+
+       return $obj;
+}
+
+sub path {
+       my $self = shift;
+
+       if (@_) {
+               my $path = shift;
+               $self->{path} = canonicalize_path($path);
+               return;
+       }
+
+       return $self->{path};
+}
+
+sub url {
+       my $self = shift;
+
+       if (@_) {
+               my $url = shift;
+               $self->{url} = canonicalize_url($url);
+               return;
+       }
+
+       return $self->{url};
+}
+
+# for read-only access of old .rev_db formats
+sub unlink_rev_db_symlink {
+       my ($self) = @_;
+       my $link = $self->rev_db_path;
+       $link =~ s/\.[\w-]+$// or croak "missing UUID at the end of $link";
+       if (-l $link) {
+               unlink $link or croak "unlink: $link failed!";
+       }
+}
+
+sub rev_db_path {
+       my ($self, $uuid) = @_;
+       my $db_path = $self->map_path($uuid);
+       $db_path =~ s{/\.rev_map\.}{/\.rev_db\.}
+           or croak "map_path: $db_path does not contain '/.rev_map.' !";
+       $db_path;
+}
+
+# the new replacement for .rev_db
+sub map_path {
+       my ($self, $uuid) = @_;
+       $uuid ||= $self->ra_uuid;
+       "$self->{map_root}.$uuid";
+}
+
+sub uri_encode {
+       my ($f) = @_;
+       $f =~ s#([^a-zA-Z0-9\*!\:_\./\-])#uc sprintf("%%%02x",ord($1))#eg;
+       $f
+}
+
+sub uri_decode {
+       my ($f) = @_;
+       $f =~ s#%([0-9a-fA-F]{2})#chr(hex($1))#eg;
+       $f
+}
+
+sub remove_username {
+       $_[0] =~ s{^([^:]*://)[^@]+@}{$1};
+}
+
+1;
index ef8e9ed2a5bf52ba5c14cdfba722bf252ecde6dd..046a7a2f31cf923f634bd8b516b3da38ff989a46 100644 (file)
@@ -57,6 +57,7 @@ sub new {
        $self->{file_prop} = {};
        $self->{absent_dir} = {};
        $self->{absent_file} = {};
+       require Git::IndexInfo;
        $self->{gii} = $git_svn->tmp_index_do(sub { Git::IndexInfo->new });
        $self->{pathnameencoding} = Git::config('svn.pathnameencoding');
        $self;
@@ -82,7 +83,7 @@ sub _mark_empty_symlinks {
        chomp(my $empty_blob = `git hash-object -t blob --stdin < /dev/null`);
        my ($ls, $ctx) = command_output_pipe(qw/ls-tree -r -z/, $cmt);
        local $/ = "\0";
-       my $pfx = defined($switch_path) ? $switch_path : $git_svn->{path};
+       my $pfx = defined($switch_path) ? $switch_path : $git_svn->path;
        $pfx .= '/' if length($pfx);
        while (<$ls>) {
                chomp;
diff --git a/perl/Git/SVN/GlobSpec.pm b/perl/Git/SVN/GlobSpec.pm
new file mode 100644 (file)
index 0000000..96cfd98
--- /dev/null
@@ -0,0 +1,59 @@
+package Git::SVN::GlobSpec;
+use strict;
+use warnings;
+
+sub new {
+       my ($class, $glob, $pattern_ok) = @_;
+       my $re = $glob;
+       $re =~ s!/+$!!g; # no need for trailing slashes
+       my (@left, @right, @patterns);
+       my $state = "left";
+       my $die_msg = "Only one set of wildcard directories " .
+                               "(e.g. '*' or '*/*/*') is supported: '$glob'\n";
+       for my $part (split(m|/|, $glob)) {
+               if ($part =~ /\*/ && $part ne "*") {
+                       die "Invalid pattern in '$glob': $part\n";
+               } elsif ($pattern_ok && $part =~ /[{}]/ &&
+                        $part !~ /^\{[^{}]+\}/) {
+                       die "Invalid pattern in '$glob': $part\n";
+               }
+               if ($part eq "*") {
+                       die $die_msg if $state eq "right";
+                       $state = "pattern";
+                       push(@patterns, "[^/]*");
+               } elsif ($pattern_ok && $part =~ /^\{(.*)\}$/) {
+                       die $die_msg if $state eq "right";
+                       $state = "pattern";
+                       my $p = quotemeta($1);
+                       $p =~ s/\\,/|/g;
+                       push(@patterns, "(?:$p)");
+               } else {
+                       if ($state eq "left") {
+                               push(@left, $part);
+                       } else {
+                               push(@right, $part);
+                               $state = "right";
+                       }
+               }
+       }
+       my $depth = @patterns;
+       if ($depth == 0) {
+               die "One '*' is needed in glob: '$glob'\n";
+       }
+       my $left = join('/', @left);
+       my $right = join('/', @right);
+       $re = join('/', @patterns);
+       $re = join('\/',
+                  grep(length, quotemeta($left), "($re)", quotemeta($right)));
+       my $left_re = qr/^\/\Q$left\E(\/|$)/;
+       bless { left => $left, right => $right, left_regex => $left_re,
+               regex => qr/$re/, glob => $glob, depth => $depth }, $class;
+}
+
+sub full_path {
+       my ($self, $path) = @_;
+       return (length $self->{left} ? "$self->{left}/" : '') .
+              $path . (length $self->{right} ? "/$self->{right}" : '');
+}
+
+1;
diff --git a/perl/Git/SVN/Log.pm b/perl/Git/SVN/Log.pm
new file mode 100644 (file)
index 0000000..3cc1c6f
--- /dev/null
@@ -0,0 +1,395 @@
+package Git::SVN::Log;
+use strict;
+use warnings;
+use Git::SVN::Utils qw(fatal);
+use Git qw(command command_oneline command_output_pipe command_close_pipe);
+use POSIX qw/strftime/;
+use constant commit_log_separator => ('-' x 72) . "\n";
+use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
+            %rusers $show_commit $incremental/;
+
+# Option set in git-svn
+our $_git_format;
+
+sub cmt_showable {
+       my ($c) = @_;
+       return 1 if defined $c->{r};
+
+       # big commit message got truncated by the 16k pretty buffer in rev-list
+       if ($c->{l} && $c->{l}->[-1] eq "...\n" &&
+                               $c->{a_raw} =~ /\@([a-f\d\-]+)>$/) {
+               @{$c->{l}} = ();
+               my @log = command(qw/cat-file commit/, $c->{c});
+
+               # shift off the headers
+               shift @log while ($log[0] ne '');
+               shift @log;
+
+               # TODO: make $c->{l} not have a trailing newline in the future
+               @{$c->{l}} = map { "$_\n" } grep !/^git-svn-id: /, @log;
+
+               (undef, $c->{r}, undef) = ::extract_metadata(
+                               (grep(/^git-svn-id: /, @log))[-1]);
+       }
+       return defined $c->{r};
+}
+
+sub log_use_color {
+       return $color || Git->repository->get_colorbool('color.diff');
+}
+
+sub git_svn_log_cmd {
+       my ($r_min, $r_max, @args) = @_;
+       my $head = 'HEAD';
+       my (@files, @log_opts);
+       foreach my $x (@args) {
+               if ($x eq '--' || @files) {
+                       push @files, $x;
+               } else {
+                       if (::verify_ref("$x^0")) {
+                               $head = $x;
+                       } else {
+                               push @log_opts, $x;
+                       }
+               }
+       }
+
+       my ($url, $rev, $uuid, $gs) = ::working_head_info($head);
+
+       require Git::SVN;
+       $gs ||= Git::SVN->_new;
+       my @cmd = (qw/log --abbrev-commit --pretty=raw --default/,
+                  $gs->refname);
+       push @cmd, '-r' unless $non_recursive;
+       push @cmd, qw/--raw --name-status/ if $verbose;
+       push @cmd, '--color' if log_use_color();
+       push @cmd, @log_opts;
+       if (defined $r_max && $r_max == $r_min) {
+               push @cmd, '--max-count=1';
+               if (my $c = $gs->rev_map_get($r_max)) {
+                       push @cmd, $c;
+               }
+       } elsif (defined $r_max) {
+               if ($r_max < $r_min) {
+                       ($r_min, $r_max) = ($r_max, $r_min);
+               }
+               my (undef, $c_max) = $gs->find_rev_before($r_max, 1, $r_min);
+               my (undef, $c_min) = $gs->find_rev_after($r_min, 1, $r_max);
+               # If there are no commits in the range, both $c_max and $c_min
+               # will be undefined.  If there is at least 1 commit in the
+               # range, both will be defined.
+               return () if !defined $c_min || !defined $c_max;
+               if ($c_min eq $c_max) {
+                       push @cmd, '--max-count=1', $c_min;
+               } else {
+                       push @cmd, '--boundary', "$c_min..$c_max";
+               }
+       }
+       return (@cmd, @files);
+}
+
+# adapted from pager.c
+sub config_pager {
+       if (! -t *STDOUT) {
+               $ENV{GIT_PAGER_IN_USE} = 'false';
+               $pager = undef;
+               return;
+       }
+       chomp($pager = command_oneline(qw(var GIT_PAGER)));
+       if ($pager eq 'cat') {
+               $pager = undef;
+       }
+       $ENV{GIT_PAGER_IN_USE} = defined($pager);
+}
+
+sub run_pager {
+       return unless defined $pager;
+       pipe my ($rfd, $wfd) or return;
+       defined(my $pid = fork) or fatal "Can't fork: $!";
+       if (!$pid) {
+               open STDOUT, '>&', $wfd or
+                                    fatal "Can't redirect to stdout: $!";
+               return;
+       }
+       open STDIN, '<&', $rfd or fatal "Can't redirect stdin: $!";
+       $ENV{LESS} ||= 'FRSX';
+       exec $pager or fatal "Can't run pager: $! ($pager)";
+}
+
+sub format_svn_date {
+       my $t = shift || time;
+       require Git::SVN;
+       my $gmoff = Git::SVN::get_tz($t);
+       return strftime("%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)", localtime($t));
+}
+
+sub parse_git_date {
+       my ($t, $tz) = @_;
+       # Date::Parse isn't in the standard Perl distro :(
+       if ($tz =~ s/^\+//) {
+               $t += tz_to_s_offset($tz);
+       } elsif ($tz =~ s/^\-//) {
+               $t -= tz_to_s_offset($tz);
+       }
+       return $t;
+}
+
+sub set_local_timezone {
+       if (defined $TZ) {
+               $ENV{TZ} = $TZ;
+       } else {
+               delete $ENV{TZ};
+       }
+}
+
+sub tz_to_s_offset {
+       my ($tz) = @_;
+       $tz =~ s/(\d\d)$//;
+       return ($1 * 60) + ($tz * 3600);
+}
+
+sub get_author_info {
+       my ($dest, $author, $t, $tz) = @_;
+       $author =~ s/(?:^\s*|\s*$)//g;
+       $dest->{a_raw} = $author;
+       my $au;
+       if ($::_authors) {
+               $au = $rusers{$author} || undef;
+       }
+       if (!$au) {
+               ($au) = ($author =~ /<([^>]+)\@[^>]+>$/);
+       }
+       $dest->{t} = $t;
+       $dest->{tz} = $tz;
+       $dest->{a} = $au;
+       $dest->{t_utc} = parse_git_date($t, $tz);
+}
+
+sub process_commit {
+       my ($c, $r_min, $r_max, $defer) = @_;
+       if (defined $r_min && defined $r_max) {
+               if ($r_min == $c->{r} && $r_min == $r_max) {
+                       show_commit($c);
+                       return 0;
+               }
+               return 1 if $r_min == $r_max;
+               if ($r_min < $r_max) {
+                       # we need to reverse the print order
+                       return 0 if (defined $limit && --$limit < 0);
+                       push @$defer, $c;
+                       return 1;
+               }
+               if ($r_min != $r_max) {
+                       return 1 if ($r_min < $c->{r});
+                       return 1 if ($r_max > $c->{r});
+               }
+       }
+       return 0 if (defined $limit && --$limit < 0);
+       show_commit($c);
+       return 1;
+}
+
+my $l_fmt;
+sub show_commit {
+       my $c = shift;
+       if ($oneline) {
+               my $x = "\n";
+               if (my $l = $c->{l}) {
+                       while ($l->[0] =~ /^\s*$/) { shift @$l }
+                       $x = $l->[0];
+               }
+               $l_fmt ||= 'A' . length($c->{r});
+               print 'r',pack($l_fmt, $c->{r}),' | ';
+               print "$c->{c} | " if $show_commit;
+               print $x;
+       } else {
+               show_commit_normal($c);
+       }
+}
+
+sub show_commit_changed_paths {
+       my ($c) = @_;
+       return unless $c->{changed};
+       print "Changed paths:\n", @{$c->{changed}};
+}
+
+sub show_commit_normal {
+       my ($c) = @_;
+       print commit_log_separator, "r$c->{r} | ";
+       print "$c->{c} | " if $show_commit;
+       print "$c->{a} | ", format_svn_date($c->{t_utc}), ' | ';
+       my $nr_line = 0;
+
+       if (my $l = $c->{l}) {
+               while ($l->[$#$l] eq "\n" && $#$l > 0
+                                         && $l->[($#$l - 1)] eq "\n") {
+                       pop @$l;
+               }
+               $nr_line = scalar @$l;
+               if (!$nr_line) {
+                       print "1 line\n\n\n";
+               } else {
+                       if ($nr_line == 1) {
+                               $nr_line = '1 line';
+                       } else {
+                               $nr_line .= ' lines';
+                       }
+                       print $nr_line, "\n";
+                       show_commit_changed_paths($c);
+                       print "\n";
+                       print $_ foreach @$l;
+               }
+       } else {
+               print "1 line\n";
+               show_commit_changed_paths($c);
+               print "\n";
+
+       }
+       foreach my $x (qw/raw stat diff/) {
+               if ($c->{$x}) {
+                       print "\n";
+                       print $_ foreach @{$c->{$x}}
+               }
+       }
+}
+
+sub cmd_show_log {
+       my (@args) = @_;
+       my ($r_min, $r_max);
+       my $r_last = -1; # prevent dupes
+       set_local_timezone();
+       if (defined $::_revision) {
+               if ($::_revision =~ /^(\d+):(\d+)$/) {
+                       ($r_min, $r_max) = ($1, $2);
+               } elsif ($::_revision =~ /^\d+$/) {
+                       $r_min = $r_max = $::_revision;
+               } else {
+                       fatal "-r$::_revision is not supported, use ",
+                               "standard 'git log' arguments instead";
+               }
+       }
+
+       config_pager();
+       @args = git_svn_log_cmd($r_min, $r_max, @args);
+       if (!@args) {
+               print commit_log_separator unless $incremental || $oneline;
+               return;
+       }
+       my $log = command_output_pipe(@args);
+       run_pager();
+       my (@k, $c, $d, $stat);
+       my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
+       while (<$log>) {
+               if (/^${esc_color}commit (?:- )?($::sha1_short)/o) {
+                       my $cmt = $1;
+                       if ($c && cmt_showable($c) && $c->{r} != $r_last) {
+                               $r_last = $c->{r};
+                               process_commit($c, $r_min, $r_max, \@k) or
+                                                               goto out;
+                       }
+                       $d = undef;
+                       $c = { c => $cmt };
+               } elsif (/^${esc_color}author (.+) (\d+) ([\-\+]?\d+)$/o) {
+                       get_author_info($c, $1, $2, $3);
+               } elsif (/^${esc_color}(?:tree|parent|committer) /o) {
+                       # ignore
+               } elsif (/^${esc_color}:\d{6} \d{6} $::sha1_short/o) {
+                       push @{$c->{raw}}, $_;
+               } elsif (/^${esc_color}[ACRMDT]\t/) {
+                       # we could add $SVN->{svn_path} here, but that requires
+                       # remote access at the moment (repo_path_split)...
+                       s#^(${esc_color})([ACRMDT])\t#$1   $2 #o;
+                       push @{$c->{changed}}, $_;
+               } elsif (/^${esc_color}diff /o) {
+                       $d = 1;
+                       push @{$c->{diff}}, $_;
+               } elsif ($d) {
+                       push @{$c->{diff}}, $_;
+               } elsif (/^\ .+\ \|\s*\d+\ $esc_color[\+\-]*
+                         $esc_color*[\+\-]*$esc_color$/x) {
+                       $stat = 1;
+                       push @{$c->{stat}}, $_;
+               } elsif ($stat && /^ \d+ files changed, \d+ insertions/) {
+                       push @{$c->{stat}}, $_;
+                       $stat = undef;
+               } elsif (/^${esc_color}    (git-svn-id:.+)$/o) {
+                       ($c->{url}, $c->{r}, undef) = ::extract_metadata($1);
+               } elsif (s/^${esc_color}    //o) {
+                       push @{$c->{l}}, $_;
+               }
+       }
+       if ($c && defined $c->{r} && $c->{r} != $r_last) {
+               $r_last = $c->{r};
+               process_commit($c, $r_min, $r_max, \@k);
+       }
+       if (@k) {
+               ($r_min, $r_max) = ($r_max, $r_min);
+               process_commit($_, $r_min, $r_max) foreach reverse @k;
+       }
+out:
+       close $log;
+       print commit_log_separator unless $incremental || $oneline;
+}
+
+sub cmd_blame {
+       my $path = pop;
+
+       config_pager();
+       run_pager();
+
+       my ($fh, $ctx, $rev);
+
+       if ($_git_format) {
+               ($fh, $ctx) = command_output_pipe('blame', @_, $path);
+               while (my $line = <$fh>) {
+                       if ($line =~ /^\^?([[:xdigit:]]+)\s/) {
+                               # Uncommitted edits show up as a rev ID of
+                               # all zeros, which we can't look up with
+                               # cmt_metadata
+                               if ($1 !~ /^0+$/) {
+                                       (undef, $rev, undef) =
+                                               ::cmt_metadata($1);
+                                       $rev = '0' if (!$rev);
+                               } else {
+                                       $rev = '0';
+                               }
+                               $rev = sprintf('%-10s', $rev);
+                               $line =~ s/^\^?[[:xdigit:]]+(\s)/$rev$1/;
+                       }
+                       print $line;
+               }
+       } else {
+               ($fh, $ctx) = command_output_pipe('blame', '-p', @_, 'HEAD',
+                                                 '--', $path);
+               my ($sha1);
+               my %authors;
+               my @buffer;
+               my %dsha; #distinct sha keys
+
+               while (my $line = <$fh>) {
+                       push @buffer, $line;
+                       if ($line =~ /^([[:xdigit:]]{40})\s\d+\s\d+/) {
+                               $dsha{$1} = 1;
+                       }
+               }
+
+               my $s2r = ::cmt_sha2rev_batch([keys %dsha]);
+
+               foreach my $line (@buffer) {
+                       if ($line =~ /^([[:xdigit:]]{40})\s\d+\s\d+/) {
+                               $rev = $s2r->{$1};
+                               $rev = '0' if (!$rev)
+                       }
+                       elsif ($line =~ /^author (.*)/) {
+                               $authors{$rev} = $1;
+                               $authors{$rev} =~ s/\s/_/g;
+                       }
+                       elsif ($line =~ /^\t(.*)$/) {
+                               printf("%6s %10s %s\n", $rev, $authors{$rev}, $1);
+                       }
+               }
+       }
+       command_close_pipe($fh, $ctx);
+}
+
+1;
diff --git a/perl/Git/SVN/Migration.pm b/perl/Git/SVN/Migration.pm
new file mode 100644 (file)
index 0000000..30daf35
--- /dev/null
@@ -0,0 +1,258 @@
+package Git::SVN::Migration;
+# these version numbers do NOT correspond to actual version numbers
+# of git nor git-svn.  They are just relative.
+#
+# v0 layout: .git/$id/info/url, refs/heads/$id-HEAD
+#
+# v1 layout: .git/$id/info/url, refs/remotes/$id
+#
+# v2 layout: .git/svn/$id/info/url, refs/remotes/$id
+#
+# v3 layout: .git/svn/$id, refs/remotes/$id
+#            - info/url may remain for backwards compatibility
+#            - this is what we migrate up to this layout automatically,
+#            - this will be used by git svn init on single branches
+# v3.1 layout (auto migrated):
+#            - .rev_db => .rev_db.$UUID, .rev_db will remain as a symlink
+#              for backwards compatibility
+#
+# v4 layout: .git/svn/$repo_id/$id, refs/remotes/$repo_id/$id
+#            - this is only created for newly multi-init-ed
+#              repositories.  Similar in spirit to the
+#              --use-separate-remotes option in git-clone (now default)
+#            - we do not automatically migrate to this (following
+#              the example set by core git)
+#
+# v5 layout: .rev_db.$UUID => .rev_map.$UUID
+#            - newer, more-efficient format that uses 24-bytes per record
+#              with no filler space.
+#            - use xxd -c24 < .rev_map.$UUID to view and debug
+#            - This is a one-way migration, repositories updated to the
+#              new format will not be able to use old git-svn without
+#              rebuilding the .rev_db.  Rebuilding the rev_db is not
+#              possible if noMetadata or useSvmProps are set; but should
+#              be no problem for users that use the (sensible) defaults.
+use strict;
+use warnings;
+use Carp qw/croak/;
+use File::Path qw/mkpath/;
+use File::Basename qw/dirname basename/;
+
+our $_minimize;
+use Git qw(
+       command
+       command_noisy
+       command_output_pipe
+       command_close_pipe
+);
+
+sub migrate_from_v0 {
+       my $git_dir = $ENV{GIT_DIR};
+       return undef unless -d $git_dir;
+       my ($fh, $ctx) = command_output_pipe(qw/rev-parse --symbolic --all/);
+       my $migrated = 0;
+       while (<$fh>) {
+               chomp;
+               my ($id, $orig_ref) = ($_, $_);
+               next unless $id =~ s#^refs/heads/(.+)-HEAD$#$1#;
+               next unless -f "$git_dir/$id/info/url";
+               my $new_ref = "refs/remotes/$id";
+               if (::verify_ref("$new_ref^0")) {
+                       print STDERR "W: $orig_ref is probably an old ",
+                                    "branch used by an ancient version of ",
+                                    "git-svn.\n",
+                                    "However, $new_ref also exists.\n",
+                                    "We will not be able ",
+                                    "to use this branch until this ",
+                                    "ambiguity is resolved.\n";
+                       next;
+               }
+               print STDERR "Migrating from v0 layout...\n" if !$migrated;
+               print STDERR "Renaming ref: $orig_ref => $new_ref\n";
+               command_noisy('update-ref', $new_ref, $orig_ref);
+               command_noisy('update-ref', '-d', $orig_ref, $orig_ref);
+               $migrated++;
+       }
+       command_close_pipe($fh, $ctx);
+       print STDERR "Done migrating from v0 layout...\n" if $migrated;
+       $migrated;
+}
+
+sub migrate_from_v1 {
+       my $git_dir = $ENV{GIT_DIR};
+       my $migrated = 0;
+       return $migrated unless -d $git_dir;
+       my $svn_dir = "$git_dir/svn";
+
+       # just in case somebody used 'svn' as their $id at some point...
+       return $migrated if -d $svn_dir && ! -f "$svn_dir/info/url";
+
+       print STDERR "Migrating from a git-svn v1 layout...\n";
+       mkpath([$svn_dir]);
+       print STDERR "Data from a previous version of git-svn exists, but\n\t",
+                    "$svn_dir\n\t(required for this version ",
+                    "($::VERSION) of git-svn) does not exist.\n";
+       my ($fh, $ctx) = command_output_pipe(qw/rev-parse --symbolic --all/);
+       while (<$fh>) {
+               my $x = $_;
+               next unless $x =~ s#^refs/remotes/##;
+               chomp $x;
+               next unless -f "$git_dir/$x/info/url";
+               my $u = eval { ::file_to_s("$git_dir/$x/info/url") };
+               next unless $u;
+               my $dn = dirname("$git_dir/svn/$x");
+               mkpath([$dn]) unless -d $dn;
+               if ($x eq 'svn') { # they used 'svn' as GIT_SVN_ID:
+                       mkpath(["$git_dir/svn/svn"]);
+                       print STDERR " - $git_dir/$x/info => ",
+                                       "$git_dir/svn/$x/info\n";
+                       rename "$git_dir/$x/info", "$git_dir/svn/$x/info" or
+                              croak "$!: $x";
+                       # don't worry too much about these, they probably
+                       # don't exist with repos this old (save for index,
+                       # and we can easily regenerate that)
+                       foreach my $f (qw/unhandled.log index .rev_db/) {
+                               rename "$git_dir/$x/$f", "$git_dir/svn/$x/$f";
+                       }
+               } else {
+                       print STDERR " - $git_dir/$x => $git_dir/svn/$x\n";
+                       rename "$git_dir/$x", "$git_dir/svn/$x" or
+                              croak "$!: $x";
+               }
+               $migrated++;
+       }
+       command_close_pipe($fh, $ctx);
+       print STDERR "Done migrating from a git-svn v1 layout\n";
+       $migrated;
+}
+
+sub read_old_urls {
+       my ($l_map, $pfx, $path) = @_;
+       my @dir;
+       foreach (<$path/*>) {
+               if (-r "$_/info/url") {
+                       $pfx .= '/' if $pfx && $pfx !~ m!/$!;
+                       my $ref_id = $pfx . basename $_;
+                       my $url = ::file_to_s("$_/info/url");
+                       $l_map->{$ref_id} = $url;
+               } elsif (-d $_) {
+                       push @dir, $_;
+               }
+       }
+       foreach (@dir) {
+               my $x = $_;
+               $x =~ s!^\Q$ENV{GIT_DIR}\E/svn/!!o;
+               read_old_urls($l_map, $x, $_);
+       }
+}
+
+sub migrate_from_v2 {
+       my @cfg = command(qw/config -l/);
+       return if grep /^svn-remote\..+\.url=/, @cfg;
+       my %l_map;
+       read_old_urls(\%l_map, '', "$ENV{GIT_DIR}/svn");
+       my $migrated = 0;
+
+       require Git::SVN;
+       foreach my $ref_id (sort keys %l_map) {
+               eval { Git::SVN->init($l_map{$ref_id}, '', undef, $ref_id) };
+               if ($@) {
+                       Git::SVN->init($l_map{$ref_id}, '', $ref_id, $ref_id);
+               }
+               $migrated++;
+       }
+       $migrated;
+}
+
+sub minimize_connections {
+       require Git::SVN;
+       require Git::SVN::Ra;
+
+       my $r = Git::SVN::read_all_remotes();
+       my $new_urls = {};
+       my $root_repos = {};
+       foreach my $repo_id (keys %$r) {
+               my $url = $r->{$repo_id}->{url} or next;
+               my $fetch = $r->{$repo_id}->{fetch} or next;
+               my $ra = Git::SVN::Ra->new($url);
+
+               # skip existing cases where we already connect to the root
+               if (($ra->url eq $ra->{repos_root}) ||
+                   ($ra->{repos_root} eq $repo_id)) {
+                       $root_repos->{$ra->url} = $repo_id;
+                       next;
+               }
+
+               my $root_ra = Git::SVN::Ra->new($ra->{repos_root});
+               my $root_path = $ra->url;
+               $root_path =~ s#^\Q$ra->{repos_root}\E(/|$)##;
+               foreach my $path (keys %$fetch) {
+                       my $ref_id = $fetch->{$path};
+                       my $gs = Git::SVN->new($ref_id, $repo_id, $path);
+
+                       # make sure we can read when connecting to
+                       # a higher level of a repository
+                       my ($last_rev, undef) = $gs->last_rev_commit;
+                       if (!defined $last_rev) {
+                               $last_rev = eval {
+                                       $root_ra->get_latest_revnum;
+                               };
+                               next if $@;
+                       }
+                       my $new = $root_path;
+                       $new .= length $path ? "/$path" : '';
+                       eval {
+                               $root_ra->get_log([$new], $last_rev, $last_rev,
+                                                 0, 0, 1, sub { });
+                       };
+                       next if $@;
+                       $new_urls->{$ra->{repos_root}}->{$new} =
+                               { ref_id => $ref_id,
+                                 old_repo_id => $repo_id,
+                                 old_path => $path };
+               }
+       }
+
+       my @emptied;
+       foreach my $url (keys %$new_urls) {
+               # see if we can re-use an existing [svn-remote "repo_id"]
+               # instead of creating a(n ugly) new section:
+               my $repo_id = $root_repos->{$url} || $url;
+
+               my $fetch = $new_urls->{$url};
+               foreach my $path (keys %$fetch) {
+                       my $x = $fetch->{$path};
+                       Git::SVN->init($url, $path, $repo_id, $x->{ref_id});
+                       my $pfx = "svn-remote.$x->{old_repo_id}";
+
+                       my $old_fetch = quotemeta("$x->{old_path}:".
+                                                 "$x->{ref_id}");
+                       command_noisy(qw/config --unset/,
+                                     "$pfx.fetch", '^'. $old_fetch . '$');
+                       delete $r->{$x->{old_repo_id}}->
+                              {fetch}->{$x->{old_path}};
+                       if (!keys %{$r->{$x->{old_repo_id}}->{fetch}}) {
+                               command_noisy(qw/config --unset/,
+                                             "$pfx.url");
+                               push @emptied, $x->{old_repo_id}
+                       }
+               }
+       }
+       if (@emptied) {
+               my $file = $ENV{GIT_CONFIG} || "$ENV{GIT_DIR}/config";
+               print STDERR <<EOF;
+The following [svn-remote] sections in your config file ($file) are empty
+and can be safely removed:
+EOF
+               print STDERR "[svn-remote \"$_\"]\n" foreach @emptied;
+       }
+}
+
+sub migration_check {
+       migrate_from_v0();
+       migrate_from_v1();
+       migrate_from_v2();
+       minimize_connections() if $_minimize;
+}
+
+1;
index 23ff43e86b4f08fb38b8d9ca90a6c77319ae8f63..90ec30bfff25c5cb5cd3c171fdc4a81c46e0f156 100644 (file)
@@ -3,6 +3,12 @@ package Git::SVN::Ra;
 use strict;
 use warnings;
 use SVN::Client;
+use Git::SVN::Utils qw(
+       canonicalize_url
+       canonicalize_path
+       add_path_to_url
+);
+
 use SVN::Ra;
 BEGIN {
        @ISA = qw(SVN::Ra);
@@ -62,29 +68,11 @@ ()
        \@rv;
 }
 
-sub escape_uri_only {
-       my ($uri) = @_;
-       my @tmp;
-       foreach (split m{/}, $uri) {
-               s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
-               push @tmp, $_;
-       }
-       join('/', @tmp);
-}
-
-sub escape_url {
-       my ($url) = @_;
-       if ($url =~ m#^(https?)://([^/]+)(.*)$#) {
-               my ($scheme, $domain, $uri) = ($1, $2, escape_uri_only($3));
-               $url = "$scheme://$domain$uri";
-       }
-       $url;
-}
 
 sub new {
        my ($class, $url) = @_;
-       $url =~ s!/+$!!;
-       return $RA if ($RA && $RA->{url} eq $url);
+       $url = canonicalize_url($url);
+       return $RA if ($RA && $RA->url eq $url);
 
        ::_req_svn();
 
@@ -115,17 +103,34 @@ sub new {
                        $Git::SVN::Prompt::_no_auth_cache = 1;
                }
        } # no warnings 'once'
-       my $self = SVN::Ra->new(url => escape_url($url), auth => $baton,
+
+       my $self = SVN::Ra->new(url => $url, auth => $baton,
                              config => $config,
                              pool => SVN::Pool->new,
                              auth_provider_callbacks => $callbacks);
-       $self->{url} = $url;
+       $RA = bless $self, $class;
+
+       # Make sure its canonicalized
+       $self->url($url);
        $self->{svn_path} = $url;
        $self->{repos_root} = $self->get_repos_root;
        $self->{svn_path} =~ s#^\Q$self->{repos_root}\E(/|$)##;
        $self->{cache} = { check_path => { r => 0, data => {} },
                           get_dir => { r => 0, data => {} } };
-       $RA = bless $self, $class;
+
+       return $RA;
+}
+
+sub url {
+       my $self = shift;
+
+       if (@_) {
+               my $url = shift;
+               $self->{url} = canonicalize_url($url);
+               return;
+       }
+
+       return $self->{url};
 }
 
 sub check_path {
@@ -195,6 +200,7 @@ sub get_log {
                                qw/copyfrom_path copyfrom_rev action/;
                        if ($s{'copyfrom_path'}) {
                                $s{'copyfrom_path'} =~ s/$prefix_regex//;
+                               $s{'copyfrom_path'} = canonicalize_path($s{'copyfrom_path'});
                        }
                        $_[0]{$p} = \%s;
                }
@@ -246,7 +252,7 @@ sub get_commit_editor {
 sub gs_do_update {
        my ($self, $rev_a, $rev_b, $gs, $editor) = @_;
        my $new = ($rev_a == $rev_b);
-       my $path = $gs->{path};
+       my $path = $gs->path;
 
        if ($new && -e $gs->{index}) {
                unlink $gs->{index} or die
@@ -282,30 +288,33 @@ sub gs_do_update {
 # svn_ra_reparent didn't work before 1.4)
 sub gs_do_switch {
        my ($self, $rev_a, $rev_b, $gs, $url_b, $editor) = @_;
-       my $path = $gs->{path};
+       my $path = $gs->path;
        my $pool = SVN::Pool->new;
 
-       my $full_url = $self->{url};
-       my $old_url = $full_url;
-       $full_url .= '/' . $path if length $path;
+       my $old_url = $self->url;
+       my $full_url = add_path_to_url( $self->url, $path );
        my ($ra, $reparented);
 
        if ($old_url =~ m#^svn(\+ssh)?://# ||
            ($full_url =~ m#^https?://# &&
-            escape_url($full_url) ne $full_url)) {
+            canonicalize_url($full_url) ne $full_url)) {
                $_[0] = undef;
                $self = undef;
                $RA = undef;
                $ra = Git::SVN::Ra->new($full_url);
                $ra_invalid = 1;
        } elsif ($old_url ne $full_url) {
-               SVN::_Ra::svn_ra_reparent($self->{session}, $full_url, $pool);
-               $self->{url} = $full_url;
+               SVN::_Ra::svn_ra_reparent(
+                       $self->{session},
+                       canonicalize_url($full_url),
+                       $pool
+               );
+               $self->url($full_url);
                $reparented = 1;
        }
 
        $ra ||= $self;
-       $url_b = escape_url($url_b);
+       $url_b = canonicalize_url($url_b);
        my $reporter = $ra->do_switch($rev_b, '', 1, $url_b, $editor, $pool);
        my @lock = (::compare_svn_version('1.2.0') >= 0) ? (undef) : ();
        $reporter->set_path('', $rev_a, 0, @lock, $pool);
@@ -313,7 +322,7 @@ sub gs_do_switch {
 
        if ($reparented) {
                SVN::_Ra::svn_ra_reparent($self->{session}, $old_url, $pool);
-               $self->{url} = $old_url;
+               $self->url($old_url);
        }
 
        $pool->clear;
@@ -326,7 +335,7 @@ sub longest_common_path {
        my $common_max = scalar @$gsv;
 
        foreach my $gs (@$gsv) {
-               my @tmp = split m#/#, $gs->{path};
+               my @tmp = split m#/#, $gs->path;
                my $p = '';
                foreach (@tmp) {
                        $p .= length($p) ? "/$_" : $_;
@@ -362,7 +371,7 @@ sub gs_fetch_loop_common {
        my $inc = $_log_window_size;
        my ($min, $max) = ($base, $head < $base + $inc ? $head : $base + $inc);
        my $longest_path = longest_common_path($gsv, $globs);
-       my $ra_url = $self->{url};
+       my $ra_url = $self->url;
        my $find_trailing_edge;
        while (1) {
                my %revs;
@@ -508,7 +517,7 @@ sub match_globs {
                                 ($self->check_path($p, $r) !=
                                  $SVN::Node::dir));
                        next unless $p =~ /$g->{path}->{regex}/;
-                       $exists->{$p} = Git::SVN->init($self->{url}, $p, undef,
+                       $exists->{$p} = Git::SVN->init($self->url, $p, undef,
                                         $g->{ref}->full_path($de), 1);
                }
        }
@@ -532,7 +541,7 @@ sub match_globs {
                        next if ($self->check_path($pathname, $r) !=
                                 $SVN::Node::dir);
                        $exists->{$pathname} = Git::SVN->init(
-                                             $self->{url}, $pathname, undef,
+                                             $self->url, $pathname, undef,
                                              $g->{ref}->full_path($p), 1);
                }
                my $c = '';
@@ -548,19 +557,20 @@ sub match_globs {
 
 sub minimize_url {
        my ($self) = @_;
-       return $self->{url} if ($self->{url} eq $self->{repos_root});
+       return $self->url if ($self->url eq $self->{repos_root});
        my $url = $self->{repos_root};
        my @components = split(m!/!, $self->{svn_path});
        my $c = '';
        do {
-               $url .= "/$c" if length $c;
+               $url = add_path_to_url($url, $c);
                eval {
                        my $ra = (ref $self)->new($url);
                        my $latest = $ra->get_latest_revnum;
                        $ra->get_log("", $latest, 0, 1, 0, 1, sub {});
                };
        } while ($@ && ($c = shift @components));
-       $url;
+
+       return canonicalize_url($url);
 }
 
 sub can_do_switch {
@@ -568,7 +578,7 @@ sub can_do_switch {
        unless (defined $can_do_switch) {
                my $pool = SVN::Pool->new;
                my $rep = eval {
-                       $self->do_switch(1, '', 0, $self->{url},
+                       $self->do_switch(1, '', 0, $self->url,
                                         SVN::Delta::Editor->new, $pool);
                };
                if ($@) {
diff --git a/perl/Git/SVN/Utils.pm b/perl/Git/SVN/Utils.pm
new file mode 100644 (file)
index 0000000..4bb4dde
--- /dev/null
@@ -0,0 +1,233 @@
+package Git::SVN::Utils;
+
+use strict;
+use warnings;
+
+use SVN::Core;
+
+use base qw(Exporter);
+
+our @EXPORT_OK = qw(
+       fatal
+       can_compress
+       canonicalize_path
+       canonicalize_url
+       join_paths
+       add_path_to_url
+);
+
+
+=head1 NAME
+
+Git::SVN::Utils - utility functions used across Git::SVN
+
+=head1 SYNOPSIS
+
+    use Git::SVN::Utils qw(functions to import);
+
+=head1 DESCRIPTION
+
+This module contains functions which are useful across many different
+parts of Git::SVN.  Mostly it's a place to put utility functions
+rather than duplicate the code or have classes grabbing at other
+classes.
+
+=head1 FUNCTIONS
+
+All functions can be imported only on request.
+
+=head3 fatal
+
+    fatal(@message);
+
+Display a message and exit with a fatal error code.
+
+=cut
+
+# Note: not certain why this is in use instead of die.  Probably because
+# the exit code of die is 255?  Doesn't appear to be used consistently.
+sub fatal (@) { print STDERR "@_\n"; exit 1 }
+
+
+=head3 can_compress
+
+    my $can_compress = can_compress;
+
+Returns true if Compress::Zlib is available, false otherwise.
+
+=cut
+
+my $can_compress;
+sub can_compress {
+       return $can_compress if defined $can_compress;
+
+       return $can_compress = eval { require Compress::Zlib; };
+}
+
+
+=head3 canonicalize_path
+
+    my $canoncalized_path = canonicalize_path($path);
+
+Converts $path into a canonical form which is safe to pass to the SVN
+API as a file path.
+
+=cut
+
+# Turn foo/../bar into bar
+sub _collapse_dotdot {
+       my $path = shift;
+
+       1 while $path =~ s{/[^/]+/+\.\.}{};
+       1 while $path =~ s{[^/]+/+\.\./}{};
+       1 while $path =~ s{[^/]+/+\.\.}{};
+
+       return $path;
+}
+
+
+sub canonicalize_path {
+       my $path = shift;
+       my $rv;
+
+       # The 1.7 way to do it
+       if ( defined &SVN::_Core::svn_dirent_canonicalize ) {
+               $path = _collapse_dotdot($path);
+               $rv = SVN::_Core::svn_dirent_canonicalize($path);
+       }
+       # The 1.6 way to do it
+       # This can return undef on subversion-perl-1.4.2-2.el5 (CentOS 5.2)
+       elsif ( defined &SVN::_Core::svn_path_canonicalize ) {
+               $path = _collapse_dotdot($path);
+               $rv = SVN::_Core::svn_path_canonicalize($path);
+       }
+
+       return $rv if defined $rv;
+
+       # No SVN API canonicalization is available, or the SVN API
+       # didn't return a successful result, do it ourselves
+       return _canonicalize_path_ourselves($path);
+}
+
+
+sub _canonicalize_path_ourselves {
+       my ($path) = @_;
+       my $dot_slash_added = 0;
+       if (substr($path, 0, 1) ne "/") {
+               $path = "./" . $path;
+               $dot_slash_added = 1;
+       }
+       $path =~ s#/+#/#g;
+       $path =~ s#/\.(?:/|$)#/#g;
+       $path = _collapse_dotdot($path);
+       $path =~ s#/$##g;
+       $path =~ s#^\./## if $dot_slash_added;
+       $path =~ s#^/##;
+       $path =~ s#^\.$##;
+       return $path;
+}
+
+
+=head3 canonicalize_url
+
+    my $canonicalized_url = canonicalize_url($url);
+
+Converts $url into a canonical form which is safe to pass to the SVN
+API as a URL.
+
+=cut
+
+sub canonicalize_url {
+       my $url = shift;
+
+       # The 1.7 way to do it
+       if ( defined &SVN::_Core::svn_uri_canonicalize ) {
+               return SVN::_Core::svn_uri_canonicalize($url);
+       }
+       # There wasn't a 1.6 way to do it, so we do it ourself.
+       else {
+               return _canonicalize_url_ourselves($url);
+       }
+}
+
+
+sub _canonicalize_url_path {
+       my ($uri_path) = @_;
+
+       my @parts;
+       foreach my $part (split m{/+}, $uri_path) {
+               $part =~ s/([^~\w.%+-]|%(?![a-fA-F0-9]{2}))/sprintf("%%%02X",ord($1))/eg;
+               push @parts, $part;
+       }
+
+       return join('/', @parts);
+}
+
+sub _canonicalize_url_ourselves {
+       my ($url) = @_;
+       if ($url =~ m#^([^:]+)://([^/]*)(.*)$#) {
+               my ($scheme, $domain, $uri) = ($1, $2, _canonicalize_url_path(canonicalize_path($3)));
+               $url = "$scheme://$domain$uri";
+       }
+       $url;
+}
+
+
+=head3 join_paths
+
+    my $new_path = join_paths(@paths);
+
+Appends @paths together into a single path.  Any empty paths are ignored.
+
+=cut
+
+sub join_paths {
+       my @paths = @_;
+
+       @paths = grep { defined $_ && length $_ } @paths;
+
+       return '' unless @paths;
+       return $paths[0] if @paths == 1;
+
+       my $new_path = shift @paths;
+       $new_path =~ s{/+$}{};
+
+       my $last_path = pop @paths;
+       $last_path =~ s{^/+}{};
+
+       for my $path (@paths) {
+               $path =~ s{^/+}{};
+               $path =~ s{/+$}{};
+               $new_path .= "/$path";
+       }
+
+       return $new_path .= "/$last_path";
+}
+
+
+=head3 add_path_to_url
+
+    my $new_url = add_path_to_url($url, $path);
+
+Appends $path onto the $url.  If $path is empty, $url is returned unchanged.
+
+=cut
+
+sub add_path_to_url {
+       my($url, $path) = @_;
+
+       return $url if !defined $path or !length $path;
+
+       # Strip trailing and leading slashes so we don't
+       # wind up with http://x.com///path
+       $url  =~ s{/+$}{};
+       $path =~ s{^/+}{};
+
+       # If a path has a % in it, URI escape it so it's not
+       # mistaken for a URI escape later.
+       $path =~ s{%}{%25}g;
+
+       return join '/', $url, $path;
+}
+
+1;
index 6ca7d472ebad5c93c014ddaac556e6a4f2284990..15d96fcc7a5a81ae0304bc51a603fe54bcbb95c6 100644 (file)
@@ -20,17 +20,26 @@ clean:
        $(RM) ppport.h
        $(RM) $(makfile)
        $(RM) $(makfile).old
+       $(RM) PM.stamp
+
+$(makfile): PM.stamp
 
 ifdef NO_PERL_MAKEMAKER
 instdir_SQ = $(subst ','\'',$(prefix)/lib)
 
 modules += Git
 modules += Git/I18N
+modules += Git/IndexInfo
+modules += Git/SVN
 modules += Git/SVN/Memoize/YAML
 modules += Git/SVN/Fetcher
 modules += Git/SVN/Editor
+modules += Git/SVN/GlobSpec
+modules += Git/SVN/Log
+modules += Git/SVN/Migration
 modules += Git/SVN/Prompt
 modules += Git/SVN/Ra
+modules += Git/SVN/Utils
 
 $(makfile): ../GIT-CFLAGS Makefile
        echo all: private-Error.pm Git.pm Git/I18N.pm > $@
index b54b04a619b0aa338cae37ade9350bb52f2edd05..3f29ba98a6fcaa6ad023123b68cd6f6b5b9250dd 100644 (file)
@@ -2,11 +2,16 @@ use strict;
 use warnings;
 use ExtUtils::MakeMaker;
 use Getopt::Long;
+use File::Find;
+
+# Don't forget to update the perl/Makefile, too.
+# Don't forget to test with NO_PERL_MAKEMAKER=YesPlease
 
 # Sanity: die at first unknown option
 Getopt::Long::Configure qw/ pass_through /;
 
-GetOptions("localedir=s" => \my $localedir);
+my $localedir = '';
+GetOptions("localedir=s" => \$localedir);
 
 sub MY::postamble {
        return <<'MAKE_FRAG';
@@ -24,24 +29,22 @@ endif
 MAKE_FRAG
 }
 
-# XXX. When editing this list:
-#
-# * Please update perl/Makefile, too.
-# * Don't forget to test with NO_PERL_MAKEMAKER=YesPlease
-my %pm = (
-       'Git.pm' => '$(INST_LIBDIR)/Git.pm',
-       'Git/I18N.pm' => '$(INST_LIBDIR)/Git/I18N.pm',
-       'Git/SVN/Memoize/YAML.pm' => '$(INST_LIBDIR)/Git/SVN/Memoize/YAML.pm',
-       'Git/SVN/Fetcher.pm' => '$(INST_LIBDIR)/Git/SVN/Fetcher.pm',
-       'Git/SVN/Editor.pm' => '$(INST_LIBDIR)/Git/SVN/Editor.pm',
-       'Git/SVN/Prompt.pm' => '$(INST_LIBDIR)/Git/SVN/Prompt.pm',
-       'Git/SVN/Ra.pm' => '$(INST_LIBDIR)/Git/SVN/Ra.pm',
-);
+# Find all the .pm files in "Git/" and Git.pm
+my %pm;
+find sub {
+       return unless /\.pm$/;
+
+       # sometimes File::Find prepends a ./  Strip it.
+       my $pm_path = $File::Find::name;
+       $pm_path =~ s{^\./}{};
+
+       $pm{$pm_path} = '$(INST_LIBDIR)/'.$pm_path;
+}, "Git", "Git.pm";
+
 
 # We come with our own bundled Error.pm. It's not in the set of default
 # Perl modules so install it if it's not available on the system yet.
-eval { require Error };
-if ($@ || $Error::VERSION < 0.15009) {
+if ( !eval { require Error } || $Error::VERSION < 0.15009) {
        $pm{'private-Error.pm'} = '$(INST_LIBDIR)/Error.pm';
 }
 
index 0cbcd64a7e1d25d677e03edb8b4499ea9d6f008c..2739bc0a3137ed506b2d7289c9bf46b81bdb5933 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -5,9 +5,9 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git 1.7.11\n"
+"Project-Id-Version: git 1.7.12\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-07-03 10:23+0800\n"
+"POT-Creation-Date: 2012-08-06 23:47+0800\n"
 "PO-Revision-Date: 2012-03-28 18:46+0200\n"
 "Last-Translator: Ralf Thielow <ralf.thielow@googlemail.com>\n"
 "Language-Team: German\n"
@@ -48,7 +48,7 @@ msgstr "'%s' sieht nicht wie eine v2 Paketdatei aus"
 msgid "unrecognized header: %s%s (%d)"
 msgstr "nicht erkannter Kopfbereich: %s%s (%d)"
 
-#: bundle.c:89 builtin/commit.c:696
+#: bundle.c:89 builtin/commit.c:699
 #, c-format
 msgid "could not open '%s'"
 msgstr "Konnte '%s' nicht öffnen"
@@ -58,7 +58,7 @@ msgid "Repository lacks these prerequisite commits:"
 msgstr "Dem Projektarchiv fehlen folgende vorrausgesetzte Versionen:"
 
 #: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
-#: builtin/log.c:721 builtin/log.c:1310 builtin/log.c:1529 builtin/merge.c:347
+#: builtin/log.c:726 builtin/log.c:1316 builtin/log.c:1535 builtin/merge.c:347
 #: builtin/shortlog.c:181
 msgid "revision walk setup failed"
 msgstr "Einrichtung des Revisionsgangs fehlgeschlagen"
@@ -85,7 +85,7 @@ msgstr[1] "Das Paket benötigt diese %d Referenzen"
 msgid "rev-list died"
 msgstr "\"rev-list\" abgebrochen"
 
-#: bundle.c:300 builtin/log.c:1206 builtin/shortlog.c:284
+#: bundle.c:300 builtin/log.c:1212 builtin/shortlog.c:284
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "nicht erkanntes Argument: %s"
@@ -232,8 +232,8 @@ msgstr ""
 "%s"
 
 #: diff.c:1400
-msgid " 0 files changed\n"
-msgstr " 0 Dateien geändert\n"
+msgid " 0 files changed"
+msgstr " 0 Dateien geändert"
 
 #: diff.c:1404
 #, c-format
@@ -256,7 +256,7 @@ msgid_plural ", %d deletions(-)"
 msgstr[0] ", %d Zeile entfernt(-)"
 msgstr[1] ", %d Zeilen entfernt(-)"
 
-#: diff.c:3478
+#: diff.c:3461
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -292,16 +292,16 @@ msgstr "'%s': %s"
 msgid "'%s': short read %s"
 msgstr "'%s': read() zu kurz %s"
 
-#: help.c:208
+#: help.c:212
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "Vorhandene Git-Kommandos in '%s'"
 
-#: help.c:215
+#: help.c:219
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "Vorhandene Git-Kommandos irgendwo in deinem $PATH"
 
-#: help.c:271
+#: help.c:275
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -310,11 +310,11 @@ msgstr ""
 "'%s' scheint ein git-Kommando zu sein, konnte aber\n"
 "nicht ausgeführt werden. Vielleicht ist git-%s fehlerhaft?"
 
-#: help.c:328
+#: help.c:332
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Uh oh. Keine Git-Kommandos auf deinem System vorhanden."
 
-#: help.c:350
+#: help.c:354
 #, c-format
 msgid ""
 "WARNING: You called a Git command named '%s', which does not exist.\n"
@@ -323,17 +323,17 @@ msgstr ""
 "Warnung: Du hast das nicht existierende Git-Kommando '%s' ausgeführt.\n"
 "Setze fort unter der Annahme das du '%s' gemeint hast"
 
-#: help.c:355
+#: help.c:359
 #, c-format
 msgid "in %0.1f seconds automatically..."
 msgstr "automatisch in %0.1f Sekunden..."
 
-#: help.c:362
+#: help.c:366
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: '%s' ist kein Git-Kommando. Siehe 'git --help'."
 
-#: help.c:366
+#: help.c:370
 msgid ""
 "\n"
 "Did you mean this?"
@@ -347,35 +347,301 @@ msgstr[1] ""
 "\n"
 "Hast du eines von diesen gemeint?"
 
-#: parse-options.c:493
+#: merge-recursive.c:190
+#, c-format
+msgid "(bad commit)\n"
+msgstr "(ungültige Version)\n"
+
+#: merge-recursive.c:206
+#, c-format
+msgid "addinfo_cache failed for path '%s'"
+msgstr "addinfo_cache für Pfad '%s' fehlgeschlagen"
+
+#: merge-recursive.c:268
+msgid "error building trees"
+msgstr "Fehler beim Erstellen der Bäume"
+
+#: merge-recursive.c:497
+msgid "diff setup failed"
+msgstr "diff_setup_done fehlgeschlagen"
+
+#: merge-recursive.c:627
+msgid "merge-recursive: disk full?"
+msgstr "merge-recursive: Festplatte voll?"
+
+#: merge-recursive.c:690
+#, c-format
+msgid "failed to create path '%s'%s"
+msgstr "Fehler beim Erstellen des Pfades '%s'%s"
+
+#: merge-recursive.c:701
+#, c-format
+msgid "Removing %s to make room for subdirectory\n"
+msgstr "Entferne %s um Platz für Unterverzeichnis zu schaffen\n"
+
+#. something else exists
+#. .. but not some other error (who really cares what?)
+#: merge-recursive.c:715 merge-recursive.c:736
+msgid ": perhaps a D/F conflict?"
+msgstr ": vielleicht ein Verzeichnis/Datei-Konflikt?"
+
+#: merge-recursive.c:726
+#, c-format
+msgid "refusing to lose untracked file at '%s'"
+msgstr "verweigere, da unbeobachtete Dateien in '%s' verloren gehen würden"
+
+#: merge-recursive.c:766
+#, c-format
+msgid "cannot read object %s '%s'"
+msgstr "kann Objekt %s '%s' nicht lesen"
+
+#: merge-recursive.c:768
+#, c-format
+msgid "blob expected for %s '%s'"
+msgstr "Blob erwartet für %s '%s'"
+
+#: merge-recursive.c:791 builtin/clone.c:302
+#, c-format
+msgid "failed to open '%s'"
+msgstr "Fehler beim Öffnen von '%s'"
+
+#: merge-recursive.c:799
+#, c-format
+msgid "failed to symlink '%s'"
+msgstr "Fehler beim Erstellen einer symbolischen Verknüpfung für '%s'"
+
+#: merge-recursive.c:802
+#, c-format
+msgid "do not know what to do with %06o %s '%s'"
+msgstr "weiß nicht was mit %06o %s '%s' zu machen ist"
+
+#: merge-recursive.c:939
+msgid "Failed to execute internal merge"
+msgstr "Fehler bei Ausführung der internen Zusammenführung"
+
+#: merge-recursive.c:943
+#, c-format
+msgid "Unable to add %s to database"
+msgstr "Konnte %s nicht zur Datenbank hinzufügen"
+
+#: merge-recursive.c:959
+msgid "unsupported object type in the tree"
+msgstr "nicht unterstützter Objekttyp im Baum"
+
+#: merge-recursive.c:1038 merge-recursive.c:1052
+#, c-format
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree."
+msgstr ""
+"KONFLIKT (%s/löschen): %s gelöscht in %s und %s in %s. Stand %s von %s wurde "
+"im Arbeitsbereich gelassen."
+
+#: merge-recursive.c:1044 merge-recursive.c:1057
+#, c-format
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree at %s."
+msgstr ""
+"KONFLIKT (%s/löschen): %s gelöscht in %s und %s in %s. Stand %s von %s wurde "
+"im Arbeitsbereich bei %s gelassen."
+
+#: merge-recursive.c:1098
+msgid "rename"
+msgstr "umbenennen"
+
+#: merge-recursive.c:1098
+msgid "renamed"
+msgstr "umbenannt"
+
+#: merge-recursive.c:1154
+#, c-format
+msgid "%s is a directory in %s adding as %s instead"
+msgstr "%s ist ein Verzeichnis in %s, füge es stattdessen als %s hinzu"
+
+#: merge-recursive.c:1176
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
+"\"->\"%s\" in \"%s\"%s"
+msgstr ""
+"KONFLIKT (umbenennen/umbenennen): Benenne um \"%s\"->\"%s\" in Zweig \"%s\" "
+"und \"%s\"->\"%s\" in Zweig \"%s\"%s"
+
+#: merge-recursive.c:1181
+msgid " (left unresolved)"
+msgstr " (bleibt unaufgelöst)"
+
+#: merge-recursive.c:1235
+#, c-format
+msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
+msgstr ""
+"KONFLIKT (umbenennen/umbenennen): Benenne um %s->%s in %s. Benenne um %s->%s "
+"in %s"
+
+#: merge-recursive.c:1265
+#, c-format
+msgid "Renaming %s to %s and %s to %s instead"
+msgstr "Benenne stattdessen %s nach %s und %s nach %s um"
+
+#: merge-recursive.c:1464
+#, c-format
+msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
+msgstr ""
+"KONFLIKT (umbenennen/hinzufügen): Benenne um %s->%s in %s. %s hinzugefügt in "
+"%s"
+
+#: merge-recursive.c:1474
+#, c-format
+msgid "Adding merged %s"
+msgstr "Füge zusammengeführte Datei %s hinzu"
+
+#: merge-recursive.c:1479 merge-recursive.c:1677
+#, c-format
+msgid "Adding as %s instead"
+msgstr "Füge stattdessen als %s hinzu"
+
+#: merge-recursive.c:1530
+#, c-format
+msgid "cannot read object %s"
+msgstr "kann Objekt %s nicht lesen"
+
+#: merge-recursive.c:1533
+#, c-format
+msgid "object %s is not a blob"
+msgstr "Objekt %s ist kein Blob"
+
+#: merge-recursive.c:1581
+msgid "modify"
+msgstr "ändern"
+
+#: merge-recursive.c:1581
+msgid "modified"
+msgstr "geändert"
+
+#: merge-recursive.c:1591
+msgid "content"
+msgstr "Inhalt"
+
+#: merge-recursive.c:1598
+msgid "add/add"
+msgstr "hinzufügen/hinzufügen"
+
+#: merge-recursive.c:1632
+#, c-format
+msgid "Skipped %s (merged same as existing)"
+msgstr "%s ausgelassen (Ergebnis der Zusammenführung existiert bereits)"
+
+#: merge-recursive.c:1646
+#, c-format
+msgid "Auto-merging %s"
+msgstr "automatische Zusammenführung von %s"
+
+#: merge-recursive.c:1650 git-submodule.sh:844
+msgid "submodule"
+msgstr "Unterprojekt"
+
+#: merge-recursive.c:1651
+#, c-format
+msgid "CONFLICT (%s): Merge conflict in %s"
+msgstr "KONFLIKT (%s): Zusammenführungskonflikt in %s"
+
+#: merge-recursive.c:1741
+#, c-format
+msgid "Removing %s"
+msgstr "Entferne %s"
+
+#: merge-recursive.c:1766
+msgid "file/directory"
+msgstr "Datei/Verzeichnis"
+
+#: merge-recursive.c:1772
+msgid "directory/file"
+msgstr "Verzeichnis/Datei"
+
+#: merge-recursive.c:1777
+#, c-format
+msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
+msgstr ""
+"KONFLIKT (%s): Es existiert bereits ein Verzeichnis %s in %s. Füge %s als %s "
+"hinzu."
+
+#: merge-recursive.c:1787
+#, c-format
+msgid "Adding %s"
+msgstr "Füge %s hinzu"
+
+#: merge-recursive.c:1804
+msgid "Fatal merge failure, shouldn't happen."
+msgstr "Fataler Fehler bei der Zusammenführung. Sollte nicht passieren."
+
+#: merge-recursive.c:1823
+msgid "Already up-to-date!"
+msgstr "Bereits aktuell!"
+
+#: merge-recursive.c:1832
+#, c-format
+msgid "merging of trees %s and %s failed"
+msgstr "Zusammenführen der Bäume %s und %s fehlgeschlagen"
+
+#: merge-recursive.c:1862
+#, c-format
+msgid "Unprocessed path??? %s"
+msgstr "unverarbeiteter Pfad??? %s"
+
+#: merge-recursive.c:1907
+msgid "Merging:"
+msgstr "Zusammenführung:"
+
+#: merge-recursive.c:1920
+#, c-format
+msgid "found %u common ancestor:"
+msgid_plural "found %u common ancestors:"
+msgstr[0] "%u gemeinsamen Vorfahren gefunden"
+msgstr[1] "%u gemeinsame Vorfahren gefunden"
+
+#: merge-recursive.c:1957
+msgid "merge returned no commit"
+msgstr "Zusammenführung hat keine Version zurückgegeben"
+
+#: merge-recursive.c:2014
+#, c-format
+msgid "Could not parse object '%s'"
+msgstr "Konnte Objekt '%s' nicht parsen."
+
+#: merge-recursive.c:2026 builtin/merge.c:697
+msgid "Unable to write index."
+msgstr "Konnte Bereitstellung nicht schreiben."
+
+#: parse-options.c:494
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:511
+#: parse-options.c:512
 #, c-format
 msgid "usage: %s"
 msgstr "Verwendung: %s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:515
+#: parse-options.c:516
 #, c-format
 msgid "   or: %s"
 msgstr "      oder: %s"
 
-#: parse-options.c:518
+#: parse-options.c:519
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: remote.c:1629
+#: remote.c:1632
 #, 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] "Dein Zweig ist vor '%s' um %d Version.\n"
 msgstr[1] "Dein Zweig ist vor '%s' um %d Versionen.\n"
 
-#: remote.c:1635
+#: remote.c:1638
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -386,7 +652,7 @@ msgstr[1] ""
 "Dein Zweig ist zu '%s' um %d Versionen hinterher, und kann vorgespult "
 "werden.\n"
 
-#: remote.c:1643
+#: remote.c:1646
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -614,7 +880,7 @@ msgstr "kann Zweigspitze (HEAD) nicht auflösen"
 msgid "cannot abort from a branch yet to be born"
 msgstr "kann nicht abbrechen: bin auf einem Zweig, der noch geboren wird"
 
-#: sequencer.c:805 builtin/apply.c:3697
+#: sequencer.c:805 builtin/apply.c:3988
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "Kann %s nicht öffnen: %s"
@@ -648,21 +914,21 @@ msgstr "Kann nicht zu initialer Version zurücksetzen."
 msgid "Can't cherry-pick into empty head"
 msgstr "Kann \"cherry-pick\" nicht in einem leerem Kopf ausführen."
 
-#: sha1_name.c:864
+#: sha1_name.c:1044
 msgid "HEAD does not point to a branch"
 msgstr "Zweigspitze (HEAD) zeigt auf keinen Zweig"
 
-#: sha1_name.c:867
+#: sha1_name.c:1047
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "Kein solcher Zweig '%s'"
 
-#: sha1_name.c:869
+#: sha1_name.c:1049
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "Kein entferntes Projektarchiv für Zweig '%s' konfiguriert."
 
-#: sha1_name.c:872
+#: sha1_name.c:1052
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr ""
@@ -677,351 +943,353 @@ msgstr "konnte aktuellen Benutzer nicht in Passwort-Datei finden: %s"
 msgid "no such user"
 msgstr "kein solcher Benutzer"
 
-#: wt-status.c:141
+#: wt-status.c:140
 msgid "Unmerged paths:"
 msgstr "Nicht zusammengeführte Pfade:"
 
-#: wt-status.c:168 wt-status.c:195
+#: wt-status.c:167 wt-status.c:194
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr ""
 "  (benutze \"git reset %s <Datei>...\" zum Herausnehmen aus der "
 "Bereitstellung)"
 
-#: wt-status.c:170 wt-status.c:197
+#: wt-status.c:169 wt-status.c:196
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr ""
 "  (benutze \"git rm --cached <Datei>...\" zum Herausnehmen aus der "
 "Bereitstellung)"
 
-#: wt-status.c:174
+#: wt-status.c:173
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (benutze \"git add/rm <Datei>...\" um die Auflösung zu markieren)"
 
-#: wt-status.c:176 wt-status.c:180
+#: wt-status.c:175 wt-status.c:179
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 "  (benutze \"git add/rm <Datei>...\" um die Auflösung entsprechend zu "
 "markieren)"
 
-#: wt-status.c:178
+#: wt-status.c:177
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (benutze \"git add/rm <Datei>...\" um die Auflösung zu markieren)"
 
-#: wt-status.c:189
+#: wt-status.c:188
 msgid "Changes to be committed:"
 msgstr "zum Eintragen bereitgestellte Änderungen:"
 
-#: wt-status.c:207
+#: wt-status.c:206
 msgid "Changes not staged for commit:"
 msgstr "Änderungen, die nicht zum Eintragen bereitgestellt sind:"
 
-#: wt-status.c:211
+#: wt-status.c:210
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr "  (benutze \"git add <Datei>...\" zum Bereitstellen)"
 
-#: wt-status.c:213
+#: wt-status.c:212
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr "  (benutze \"git add/rm <Datei>...\" zum Bereitstellen)"
 
-#: wt-status.c:214
+#: wt-status.c:213
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (benutze \"git checkout -- <Datei>...\" um die Änderungen im "
 "Arbeitsverzeichnis zu verwerfen)"
 
-#: wt-status.c:216
+#: wt-status.c:215
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (trage ein oder verwerfe den unbeobachteten oder geänderten Inhalt in den "
 "Unterprojekten)"
 
-#: wt-status.c:225
+#: wt-status.c:224
 #, c-format
 msgid "%s files:"
 msgstr "%s Dateien:"
 
-#: wt-status.c:228
+#: wt-status.c:227
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr "  (benutze \"git %s <Datei>...\" zum Einfügen in die Eintragung)"
 
-#: wt-status.c:245
+#: wt-status.c:244
 msgid "bug"
 msgstr "Fehler"
 
-#: wt-status.c:250
+#: wt-status.c:249
 msgid "both deleted:"
 msgstr "beide gelöscht:"
 
-#: wt-status.c:251
+#: wt-status.c:250
 msgid "added by us:"
 msgstr "von uns hinzugefügt:"
 
-#: wt-status.c:252
+#: wt-status.c:251
 msgid "deleted by them:"
 msgstr "von denen gelöscht:"
 
-#: wt-status.c:253
+#: wt-status.c:252
 msgid "added by them:"
 msgstr "von denen hinzugefügt:"
 
-#: wt-status.c:254
+#: wt-status.c:253
 msgid "deleted by us:"
 msgstr "von uns gelöscht:"
 
-#: wt-status.c:255
+#: wt-status.c:254
 msgid "both added:"
 msgstr "von beiden hinzugefügt:"
 
-#: wt-status.c:256
+#: wt-status.c:255
 msgid "both modified:"
 msgstr "von beiden geändert:"
 
-#: wt-status.c:286
+#: wt-status.c:285
 msgid "new commits, "
 msgstr "neue Versionen, "
 
-#: wt-status.c:288
+#: wt-status.c:287
 msgid "modified content, "
 msgstr "geänderter Inhalt, "
 
-#: wt-status.c:290
+#: wt-status.c:289
 msgid "untracked content, "
 msgstr "unbeobachteter Inhalt, "
 
-#: wt-status.c:304
+#: wt-status.c:303
 #, c-format
 msgid "new file:   %s"
 msgstr "neue Datei:   %s"
 
-#: wt-status.c:307
+#: wt-status.c:306
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "kopiert:     %s -> %s"
 
-#: wt-status.c:310
+#: wt-status.c:309
 #, c-format
 msgid "deleted:    %s"
 msgstr "gelöscht:    %s"
 
-#: wt-status.c:313
+#: wt-status.c:312
 #, c-format
 msgid "modified:   %s"
 msgstr "geändert:   %s"
 
-#: wt-status.c:316
+#: wt-status.c:315
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "umbenannt:    %s -> %s"
 
-#: wt-status.c:319
+#: wt-status.c:318
 #, c-format
 msgid "typechange: %s"
 msgstr "Typänderung: %s"
 
-#: wt-status.c:322
+#: wt-status.c:321
 #, c-format
 msgid "unknown:    %s"
 msgstr "unbekannt:    %s"
 
-#: wt-status.c:325
+#: wt-status.c:324
 #, c-format
 msgid "unmerged:   %s"
 msgstr "nicht zusammengeführt:   %s"
 
-#: wt-status.c:328
+#: wt-status.c:327
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr "Fehler: unbehandelter Differenz-Status %c"
 
-#: wt-status.c:786
+#: wt-status.c:785
 msgid "You have unmerged paths."
 msgstr "Du hast nicht zusammengeführte Pfade."
 
-#: wt-status.c:789 wt-status.c:913
+#: wt-status.c:788 wt-status.c:912
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr " (behebe die Konflikte und führe \"git commit\" aus)"
 
-#: wt-status.c:792
+#: wt-status.c:791
 msgid "All conflicts fixed but you are still merging."
-msgstr "Alle Konflikte sind behoben, aber du bist immer noch beim "
-"Zusammenführen."
+msgstr ""
+"Alle Konflikte sind behoben, aber du bist immer noch beim Zusammenführen."
 
-#: wt-status.c:795
+#: wt-status.c:794
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (benutze \"git commit\" um die Zusammenführung abzuschließen)"
 
-#: wt-status.c:805
+#: wt-status.c:804
 msgid "You are in the middle of an am session."
 msgstr "Eine \"am\"-Sitzung ist im Gange."
 
-#: wt-status.c:808
+#: wt-status.c:807
 msgid "The current patch is empty."
 msgstr "Der aktuelle Patch ist leer."
 
-#: wt-status.c:812
+#: wt-status.c:811
 msgid "  (fix conflicts and then run \"git am --resolved\")"
 msgstr "  (behebe die Konflikte und führe dann \"git am --resolved\" aus)"
 
-#: wt-status.c:814
+#: wt-status.c:813
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr " (benutze \"git am --skip\" um diesen Patch auszulassen)"
 
-#: wt-status.c:816
+#: wt-status.c:815
 msgid "  (use \"git am --abort\" to restore the original branch)"
-msgstr "  (benutze \"git am --abort\" um den ursprünglichen Zweig "
-"wiederherzustellen)"
+msgstr ""
+"  (benutze \"git am --abort\" um den ursprünglichen Zweig wiederherzustellen)"
 
-#: wt-status.c:874 wt-status.c:884
+#: wt-status.c:873 wt-status.c:883
 msgid "You are currently rebasing."
 msgstr "Du bist gerade beim Neuaufbau."
 
-#: wt-status.c:877
+#: wt-status.c:876
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (behebe die Konflikte und führe dann \"git rebase --continue\" aus)"
 
-#: wt-status.c:879
+#: wt-status.c:878
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (benutze \"git rebase --skip\" um diesen Patch auszulassen)"
 
-#: wt-status.c:881
+#: wt-status.c:880
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
-msgstr "  (benutze \"git rebase --abort\" um den ursprünglichen Zweig "
-"auszuchecken)"
+msgstr ""
+"  (benutze \"git rebase --abort\" um den ursprünglichen Zweig auszuchecken)"
 
-#: wt-status.c:887
+#: wt-status.c:886
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (alle Konflikte behoben: führe \"git rebase --continue\" aus)"
 
-#: wt-status.c:889
+#: wt-status.c:888
 msgid "You are currently splitting a commit during a rebase."
 msgstr "Du teilst gerade eine Version während eines Neuaufbaus auf."
 
-#: wt-status.c:892
+#: wt-status.c:891
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
-msgstr "  (Sobald dein Arbeitsverzeichnis sauber ist, führe "
-"\"git rebase --continue\" aus)"
+msgstr ""
+"  (Sobald dein Arbeitsverzeichnis sauber ist, führe \"git rebase --continue"
+"\" aus)"
 
-#: wt-status.c:894
+#: wt-status.c:893
 msgid "You are currently editing a commit during a rebase."
 msgstr "Du editierst gerade eine Version während eines Neuaufbaus."
 
-#: wt-status.c:897
+#: wt-status.c:896
 msgid "  (use \"git commit --amend\" to amend the current commit)"
-msgstr "  (benutze \"git commit --amend\" um die aktuelle Version "
-"nachzubessern)"
+msgstr ""
+"  (benutze \"git commit --amend\" um die aktuelle Version nachzubessern)"
 
-#: wt-status.c:899
+#: wt-status.c:898
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
-msgstr "  (benutze \"git rebase --continue\" sobald deine Änderungen "
-"abgeschlossen sind)"
+msgstr ""
+"  (benutze \"git rebase --continue\" sobald deine Änderungen abgeschlossen "
+"sind)"
 
-#: wt-status.c:909
+#: wt-status.c:908
 msgid "You are currently cherry-picking."
 msgstr "Du führst gerade \"cherry-pick\" aus."
 
-#: wt-status.c:916
+#: wt-status.c:915
 msgid "  (all conflicts fixed: run \"git commit\")"
 msgstr "  (alle Konflikte behoben: führe \"git commit\" aus)"
 
-#: wt-status.c:925
+#: wt-status.c:924
 msgid "You are currently bisecting."
 msgstr "Du bist gerade beim Halbieren."
 
-#: wt-status.c:928
+#: wt-status.c:927
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
-msgstr "  (benutze \"git bisect reset\" um zum ursprünglichen Zweig "
-"zurückzukehren)"
+msgstr ""
+"  (benutze \"git bisect reset\" um zum ursprünglichen Zweig zurückzukehren)"
 
-#: wt-status.c:979
+#: wt-status.c:978
 msgid "On branch "
 msgstr "Auf Zweig "
 
-#: wt-status.c:986
+#: wt-status.c:985
 msgid "Not currently on any branch."
 msgstr "Im Moment auf keinem Zweig."
 
-#: wt-status.c:998
+#: wt-status.c:997
 msgid "Initial commit"
 msgstr "Initiale Version"
 
-#: wt-status.c:1012
+#: wt-status.c:1011
 msgid "Untracked"
 msgstr "Unbeobachtete"
 
-#: wt-status.c:1014
+#: wt-status.c:1013
 msgid "Ignored"
 msgstr "Ignorierte"
 
-#: wt-status.c:1016
+#: wt-status.c:1015
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Unbeobachtete Dateien nicht aufgelistet%s"
 
-#: wt-status.c:1018
+#: wt-status.c:1017
 msgid " (use -u option to show untracked files)"
 msgstr " (benutze die Option -u um unbeobachteten Dateien anzuzeigen)"
 
-#: wt-status.c:1024
+#: wt-status.c:1023
 msgid "No changes"
 msgstr "Keine Änderungen"
 
-#: wt-status.c:1028
+#: wt-status.c:1027
 #, c-format
 msgid "no changes added to commit%s\n"
 msgstr "keine Änderungen zum Eintragen hinzugefügt%s\n"
 
-#: wt-status.c:1030
+#: wt-status.c:1029
 msgid " (use \"git add\" and/or \"git commit -a\")"
 msgstr " (benutze \"git add\" und/oder \"git commit -a\")"
 
-#: wt-status.c:1032
+#: wt-status.c:1031
 #, c-format
 msgid "nothing added to commit but untracked files present%s\n"
 msgstr ""
 "nichts zum Eintragen hinzugefügt, aber es gibt unbeobachtete Dateien%s\n"
 
-#: wt-status.c:1034
+#: wt-status.c:1033
 msgid " (use \"git add\" to track)"
 msgstr " (benutze \"git add\" zum Beobachten)"
 
-#: wt-status.c:1036 wt-status.c:1039 wt-status.c:1042
+#: wt-status.c:1035 wt-status.c:1038 wt-status.c:1041
 #, c-format
 msgid "nothing to commit%s\n"
 msgstr "nichts zum Eintragen%s\n"
 
-#: wt-status.c:1037
+#: wt-status.c:1036
 msgid " (create/copy files and use \"git add\" to track)"
 msgstr " (Erstelle/Kopiere Dateien und benutze \"git add\" zum Beobachten)"
 
-#: wt-status.c:1040
+#: wt-status.c:1039
 msgid " (use -u to show untracked files)"
 msgstr " (benutze die Option -u um unbeobachtete Dateien anzuzeigen)"
 
-#: wt-status.c:1043
+#: wt-status.c:1042
 msgid " (working directory clean)"
 msgstr " (Arbeitsverzeichnis sauber)"
 
-#: wt-status.c:1151
+#: wt-status.c:1150
 msgid "HEAD (no branch)"
 msgstr "HEAD (kein Zweig)"
 
-#: wt-status.c:1157
+#: wt-status.c:1156
 msgid "Initial commit on "
 msgstr "Initiale Version auf "
 
-#: wt-status.c:1172
+#: wt-status.c:1171
 msgid "behind "
 msgstr "hinterher "
 
-#: wt-status.c:1175 wt-status.c:1178
+#: wt-status.c:1174 wt-status.c:1177
 msgid "ahead "
 msgstr "voraus "
 
-#: wt-status.c:1180
+#: wt-status.c:1179
 msgid ", behind "
 msgstr ", hinterher "
 
@@ -1030,7 +1298,7 @@ msgstr ", hinterher "
 msgid "unexpected diff status %c"
 msgstr "unerwarteter Differenz-Status %c"
 
-#: builtin/add.c:67 builtin/commit.c:226
+#: builtin/add.c:67 builtin/commit.c:229
 msgid "updating files failed"
 msgstr "Aktualisierung der Dateien fehlgeschlagen"
 
@@ -1124,79 +1392,79 @@ msgstr "Nichts spezifiziert, nichts hinzugefügt.\n"
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Wolltest du vielleicht 'git add .' sagen?\n"
 
-#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:286 builtin/mv.c:82
+#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:289 builtin/mv.c:82
 #: builtin/rm.c:162
 msgid "index file corrupt"
 msgstr "Bereitstellungsdatei beschädigt"
 
-#: builtin/add.c:480 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4433 builtin/mv.c:229 builtin/rm.c:260
 msgid "Unable to write new index file"
 msgstr "Konnte neue Bereitstellungsdatei nicht schreiben."
 
-#: builtin/apply.c:53
+#: builtin/apply.c:57
 msgid "git apply [options] [<patch>...]"
 msgstr "git apply [Optionen] [<Patch>...]"
 
-#: builtin/apply.c:106
+#: builtin/apply.c:110
 #, c-format
 msgid "unrecognized whitespace option '%s'"
 msgstr "nicht erkannte Option für Leerzeichen: '%s'"
 
-#: builtin/apply.c:121
+#: builtin/apply.c:125
 #, c-format
 msgid "unrecognized whitespace ignore option '%s'"
 msgstr "nicht erkannte Option zum Ignorieren von Leerzeichen: '%s'"
 
-#: builtin/apply.c:815
+#: builtin/apply.c:824
 #, c-format
 msgid "Cannot prepare timestamp regexp %s"
 msgstr "Kann regulären Ausdruck für Zeitstempel %s nicht verarbeiten"
 
-#: builtin/apply.c:824
+#: builtin/apply.c:833
 #, c-format
 msgid "regexec returned %d for input: %s"
 msgstr "Ausführung des regulären Ausdrucks gab %d zurück. Eingabe: %s"
 
-#: builtin/apply.c:905
+#: builtin/apply.c:914
 #, c-format
 msgid "unable to find filename in patch at line %d"
 msgstr "Konnte keinen Dateinamen in Zeile %d des Patches finden."
 
-#: builtin/apply.c:937
+#: builtin/apply.c:946
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
 msgstr ""
 "git apply: ungültiges 'git-diff' - erwartete /dev/null, erhielt %s in Zeile "
 "%d"
 
-#: builtin/apply.c:941
+#: builtin/apply.c:950
 #, c-format
 msgid "git apply: bad git-diff - inconsistent new filename on line %d"
 msgstr ""
 "git apply: ungültiges 'git-diff' - Inkonsistenter neuer Dateiname in Zeile %d"
 
-#: builtin/apply.c:942
+#: builtin/apply.c:951
 #, c-format
 msgid "git apply: bad git-diff - inconsistent old filename on line %d"
 msgstr ""
 "git apply: ungültiges 'git-diff' - Inkonsistenter alter Dateiname in Zeile %d"
 
-#: builtin/apply.c:949
+#: builtin/apply.c:958
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null on line %d"
 msgstr "git apply: ungültiges 'git-diff' - erwartete /dev/null in Zeile %d"
 
-#: builtin/apply.c:1394
+#: builtin/apply.c:1403
 #, c-format
 msgid "recount: unexpected line: %.*s"
 msgstr "recount: unerwartete Zeile: %.*s"
 
-#: builtin/apply.c:1451
+#: builtin/apply.c:1460
 #, c-format
 msgid "patch fragment without header at line %d: %.*s"
 msgstr "Patch-Fragment ohne Kopfbereich bei Zeile %d: %.*s"
 
-#: builtin/apply.c:1468
+#: builtin/apply.c:1477
 #, c-format
 msgid ""
 "git diff header lacks filename information when removing %d leading pathname "
@@ -1211,70 +1479,70 @@ msgstr[1] ""
 "Dem Kopfbereich von \"git diff\" fehlen Informationen zum Dateinamen, wenn "
 "%d vorangestellte Teile des Pfades entfernt werden (Zeile %d)"
 
-#: builtin/apply.c:1628
+#: builtin/apply.c:1637
 msgid "new file depends on old contents"
 msgstr "neue Datei hängt von alten Inhalten ab"
 
-#: builtin/apply.c:1630
+#: builtin/apply.c:1639
 msgid "deleted file still has contents"
 msgstr "entfernte Datei hat noch Inhalte"
 
-#: builtin/apply.c:1656
+#: builtin/apply.c:1665
 #, c-format
 msgid "corrupt patch at line %d"
 msgstr "fehlerhafter Patch bei Zeile %d"
 
-#: builtin/apply.c:1692
+#: builtin/apply.c:1701
 #, c-format
 msgid "new file %s depends on old contents"
 msgstr "neue Datei %s hängt von alten Inhalten ab"
 
-#: builtin/apply.c:1694
+#: builtin/apply.c:1703
 #, c-format
 msgid "deleted file %s still has contents"
 msgstr "entfernte Datei %s hat noch Inhalte"
 
-#: builtin/apply.c:1697
+#: builtin/apply.c:1706
 #, c-format
 msgid "** warning: file %s becomes empty but is not deleted"
 msgstr "** Warnung: Datei %s wird leer, aber nicht entfernt."
 
-#: builtin/apply.c:1843
+#: builtin/apply.c:1852
 #, c-format
 msgid "corrupt binary patch at line %d: %.*s"
 msgstr "fehlerhafter Binär-Patch bei Zeile %d: %.*s"
 
 #. there has to be one hunk (forward hunk)
-#: builtin/apply.c:1872
+#: builtin/apply.c:1881
 #, c-format
 msgid "unrecognized binary patch at line %d"
 msgstr "nicht erkannter Binär-Patch bei Zeile %d"
 
-#: builtin/apply.c:1958
+#: builtin/apply.c:1967
 #, c-format
 msgid "patch with only garbage at line %d"
 msgstr "Patch mit nutzlosen Informationen bei Zeile %d"
 
-#: builtin/apply.c:2048
+#: builtin/apply.c:2057
 #, c-format
 msgid "unable to read symlink %s"
 msgstr "konnte symbolische Verknüpfung %s nicht lesen"
 
-#: builtin/apply.c:2052
+#: builtin/apply.c:2061
 #, c-format
 msgid "unable to open or read %s"
 msgstr "konnte %s nicht öffnen oder lesen"
 
-#: builtin/apply.c:2123
+#: builtin/apply.c:2132
 msgid "oops"
 msgstr "Ups"
 
-#: builtin/apply.c:2645
+#: builtin/apply.c:2654
 #, c-format
 msgid "invalid start of line: '%c'"
 msgstr "Ungültiger Zeilenanfang: '%c'"
 
-#: builtin/apply.c:2763
+#: builtin/apply.c:2772
 #, c-format
 msgid "Hunk #%d succeeded at %d (offset %d line)."
 msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
@@ -1282,12 +1550,12 @@ msgstr[0] "Patch-Bereich #%d erfolgreich angewendet bei %d (%d Zeile versetzt)"
 msgstr[1] ""
 "Patch-Bereich #%d erfolgreich angewendet bei %d (%d Zeilen versetzt)"
 
-#: builtin/apply.c:2775
+#: builtin/apply.c:2784
 #, c-format
 msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
 msgstr "Kontext reduziert zu (%ld/%ld) um Patch-Bereich bei %d anzuwenden"
 
-#: builtin/apply.c:2781
+#: builtin/apply.c:2790
 #, c-format
 msgid ""
 "while searching for:\n"
@@ -1296,329 +1564,339 @@ msgstr ""
 "bei der Suche nach:\n"
 "%.*s"
 
-#: builtin/apply.c:2800
+#: builtin/apply.c:2809
 #, c-format
 msgid "missing binary patch data for '%s'"
 msgstr "keine Daten in Binär-Patch für '%s'"
 
-#: builtin/apply.c:2903
+#: builtin/apply.c:2912
 #, c-format
 msgid "binary patch does not apply to '%s'"
 msgstr "Konnte Binär-Patch nicht auf '%s' anwenden"
 
-#: builtin/apply.c:2909
+#: builtin/apply.c:2918
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
 msgstr ""
 "Binär-Patch für '%s' erzeugt falsches Ergebnis (erwartete %s, bekam %s)"
 
-#: builtin/apply.c:2930
+#: builtin/apply.c:2939
 #, c-format
 msgid "patch failed: %s:%ld"
 msgstr "Anwendung des Patches fehlgeschlagen: %s:%ld"
 
-#: builtin/apply.c:3045
+#: builtin/apply.c:3061
 #, c-format
-msgid "patch %s has been renamed/deleted"
-msgstr "Patch %s wurde umbenannt/gelöscht"
+msgid "cannot checkout %s"
+msgstr "kann %s nicht auschecken"
 
-#: builtin/apply.c:3052 builtin/apply.c:3069
+#: builtin/apply.c:3106 builtin/apply.c:3115 builtin/apply.c:3159
 #, c-format
 msgid "read of %s failed"
 msgstr "Konnte %s nicht lesen"
 
-#: builtin/apply.c:3084
-msgid "removal patch leaves file contents"
-msgstr "Lösch-Patch hinterlässt Dateiinhalte"
-
-#: builtin/apply.c:3105
+#: builtin/apply.c:3139 builtin/apply.c:3361
 #, c-format
-msgid "%s: already exists in working directory"
-msgstr "%s existiert bereits im Arbeitsverzeichnis"
+msgid "path %s has been renamed/deleted"
+msgstr "Pfad %s wurde umbenannt/gelöscht"
 
-#: builtin/apply.c:3143
+#: builtin/apply.c:3220 builtin/apply.c:3375
 #, c-format
-msgid "%s: has been deleted/renamed"
-msgstr "%s wurde gelöscht/umbenannt"
+msgid "%s: does not exist in index"
+msgstr "%s ist nicht bereitgestellt"
 
-#: builtin/apply.c:3148 builtin/apply.c:3179
+#: builtin/apply.c:3224 builtin/apply.c:3367 builtin/apply.c:3389
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: builtin/apply.c:3159
-#, c-format
-msgid "%s: does not exist in index"
-msgstr "%s ist nicht bereitgestellt"
-
-#: builtin/apply.c:3173
+#: builtin/apply.c:3229 builtin/apply.c:3383
 #, c-format
 msgid "%s: does not match index"
 msgstr "%s entspricht nicht der Bereitstellung"
 
-#: builtin/apply.c:3190
+#: builtin/apply.c:3331
+msgid "removal patch leaves file contents"
+msgstr "Lösch-Patch hinterlässt Dateiinhalte"
+
+#: builtin/apply.c:3400
 #, c-format
 msgid "%s: wrong type"
 msgstr "%s: falscher Typ"
 
-#: builtin/apply.c:3192
+#: builtin/apply.c:3402
 #, c-format
 msgid "%s has type %o, expected %o"
 msgstr "%s ist vom Typ %o, erwartete %o"
 
-#: builtin/apply.c:3247
+#: builtin/apply.c:3503
 #, c-format
 msgid "%s: already exists in index"
 msgstr "%s ist bereits bereitgestellt"
 
-#: builtin/apply.c:3267
+#: builtin/apply.c:3506
+#, c-format
+msgid "%s: already exists in working directory"
+msgstr "%s existiert bereits im Arbeitsverzeichnis"
+
+#: builtin/apply.c:3526
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
 msgstr "neuer Modus (%o) von %s entspricht nicht dem alten Modus (%o)"
 
-#: builtin/apply.c:3272
+#: builtin/apply.c:3531
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o) of %s"
 msgstr "neuer Modus (%o) von %s entspricht nicht dem alten Modus (%o) von %s"
 
-#: builtin/apply.c:3280
+#: builtin/apply.c:3539
 #, c-format
 msgid "%s: patch does not apply"
 msgstr "%s: Patch konnte nicht angewendet werden"
 
-#: builtin/apply.c:3293
+#: builtin/apply.c:3552
 #, c-format
 msgid "Checking patch %s..."
 msgstr "Prüfe Patch %s..."
 
-#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
+#: builtin/apply.c:3607 builtin/checkout.c:213 builtin/reset.c:158
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr "make_cache_entry für Pfad '%s' fehlgeschlagen"
 
-#: builtin/apply.c:3491
+#: builtin/apply.c:3750
 #, c-format
 msgid "unable to remove %s from index"
 msgstr "konnte %s nicht aus der Bereitstellung entfernen"
 
-#: builtin/apply.c:3518
+#: builtin/apply.c:3778
 #, c-format
 msgid "corrupt patch for subproject %s"
 msgstr "fehlerhafter Patch für Unterprojekt %s"
 
-#: builtin/apply.c:3522
+#: builtin/apply.c:3782
 #, c-format
 msgid "unable to stat newly created file '%s'"
 msgstr "konnte neu erstellte Datei '%s' nicht lesen"
 
-#: builtin/apply.c:3527
+#: builtin/apply.c:3787
 #, c-format
 msgid "unable to create backing store for newly created file %s"
 msgstr "kann internen Speicher für eben erstellte Datei %s nicht erzeugen"
 
-#: builtin/apply.c:3530
+#: builtin/apply.c:3790 builtin/apply.c:3898
 #, c-format
 msgid "unable to add cache entry for %s"
 msgstr "kann für %s keinen Eintrag in den Zwischenspeicher hinzufügen"
 
-#: builtin/apply.c:3563
+#: builtin/apply.c:3823
 #, c-format
 msgid "closing file '%s'"
 msgstr "schließe Datei '%s'"
 
-#: builtin/apply.c:3612
+#: builtin/apply.c:3872
 #, c-format
 msgid "unable to write file '%s' mode %o"
 msgstr "konnte Datei '%s' mit Modus %o nicht schreiben"
 
-#: builtin/apply.c:3668
+#: builtin/apply.c:3959
 #, c-format
 msgid "Applied patch %s cleanly."
 msgstr "Patch %s sauber angewendet"
 
-#: builtin/apply.c:3676
+#: builtin/apply.c:3967
 msgid "internal error"
 msgstr "interner Fehler"
 
 #. Say this even without --verbose
-#: builtin/apply.c:3679
+#: builtin/apply.c:3970
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
 msgstr[0] "Wende Patch %%s mit %d Zurückweisung an..."
 msgstr[1] "Wende Patch %%s mit %d Zurückweisungen an..."
 
-#: builtin/apply.c:3689
+#: builtin/apply.c:3980
 #, c-format
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "Verkürze Name von .rej Datei zu %.*s.rej"
 
-#: builtin/apply.c:3710
+#: builtin/apply.c:4001
 #, c-format
 msgid "Hunk #%d applied cleanly."
 msgstr "Patch-Bereich #%d sauber angewendet."
 
-#: builtin/apply.c:3713
+#: builtin/apply.c:4004
 #, c-format
 msgid "Rejected hunk #%d."
 msgstr "Patch-Bereich #%d zurückgewiesen."
 
-#: builtin/apply.c:3844
+#: builtin/apply.c:4154
 msgid "unrecognized input"
 msgstr "nicht erkannte Eingabe"
 
-#: builtin/apply.c:3855
+#: builtin/apply.c:4165
 msgid "unable to read index file"
 msgstr "Konnte Bereitstellungsdatei nicht lesen"
 
-#: builtin/apply.c:3970 builtin/apply.c:3973
+#: builtin/apply.c:4284 builtin/apply.c:4287
 msgid "path"
 msgstr "Pfad"
 
-#: builtin/apply.c:3971
+#: builtin/apply.c:4285
 msgid "don't apply changes matching the given path"
 msgstr "wendet keine Änderungen im angegebenen Pfad an"
 
-#: builtin/apply.c:3974
+#: builtin/apply.c:4288
 msgid "apply changes matching the given path"
 msgstr "wendet Änderungen nur im angegebenen Pfad an"
 
-#: builtin/apply.c:3976
+#: builtin/apply.c:4290
 msgid "num"
 msgstr "Anzahl"
 
-#: builtin/apply.c:3977
+#: builtin/apply.c:4291
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr ""
 "entfernt <Anzahl> vorrangestellte Schrägstriche von herkömmlichen "
 "Differenzpfaden"
 
-#: builtin/apply.c:3980
+#: builtin/apply.c:4294
 msgid "ignore additions made by the patch"
 msgstr "ignoriert hinzugefügte Zeilen des Patches"
 
-#: builtin/apply.c:3982
+#: builtin/apply.c:4296
 msgid "instead of applying the patch, output diffstat for the input"
 msgstr ""
 "anstatt der Anwendung des Patches, wird der \"diffstat\" für die Eingabe "
 "ausgegeben"
 
-#: builtin/apply.c:3986
+#: builtin/apply.c:4300
 msgid "shows number of added and deleted lines in decimal notation"
 msgstr ""
 "zeigt die Anzahl von hinzugefügten/entfernten Zeilen in Dezimalnotation"
 
-#: builtin/apply.c:3988
+#: builtin/apply.c:4302
 msgid "instead of applying the patch, output a summary for the input"
 msgstr ""
 "anstatt der Anwendung des Patches, wird eine Zusammenfassung für die Eingabe "
 "ausgegeben"
 
-#: builtin/apply.c:3990
+#: builtin/apply.c:4304
 msgid "instead of applying the patch, see if the patch is applicable"
 msgstr ""
 "anstatt der Anwendung des Patches, zeige ob Patch angewendet werden kann"
 
-#: builtin/apply.c:3992
+#: builtin/apply.c:4306
 msgid "make sure the patch is applicable to the current index"
 msgstr ""
 "stellt sicher, dass der Patch in der aktuellen Bereitstellung angewendet "
 "werden kann"
 
-#: builtin/apply.c:3994
+#: builtin/apply.c:4308
 msgid "apply a patch without touching the working tree"
 msgstr "wendet einen Patch an, ohne Änderungen im Arbeitszweig vorzunehmen"
 
-#: builtin/apply.c:3996
+#: builtin/apply.c:4310
 msgid "also apply the patch (use with --stat/--summary/--check)"
 msgstr "wendet den Patch an (Benutzung mit --stat/--summary/--check)"
 
-#: builtin/apply.c:3998
+#: builtin/apply.c:4312
+msgid "attempt three-way merge if a patch does not apply"
+msgstr ""
+"versucht 3-Wege-Zusammenführung, wenn der Patch nicht angewendet werden "
+"konnte"
+
+#: builtin/apply.c:4314
 msgid "build a temporary index based on embedded index information"
 msgstr ""
 "erstellt eine temporäre Bereitstellung basierend auf den integrierten "
 "Bereitstellungsinformationen"
 
-#: builtin/apply.c:4000
+#: builtin/apply.c:4316
 msgid "paths are separated with NUL character"
 msgstr "Pfade sind getrennt durch NUL Zeichen"
 
-#: builtin/apply.c:4003
+#: builtin/apply.c:4319
 msgid "ensure at least <n> lines of context match"
 msgstr ""
 "stellt sicher, dass mindestens <Anzahl> Zeilen des Kontextes übereinstimmen"
 
-#: builtin/apply.c:4004
+#: builtin/apply.c:4320
 msgid "action"
 msgstr "Aktion"
 
-#: builtin/apply.c:4005
+#: builtin/apply.c:4321
 msgid "detect new or modified lines that have whitespace errors"
 msgstr "ermittelt neue oder geänderte Zeilen die Fehler in Leerzeichen haben"
 
-#: builtin/apply.c:4008 builtin/apply.c:4011
+#: builtin/apply.c:4324 builtin/apply.c:4327
 msgid "ignore changes in whitespace when finding context"
 msgstr "ignoriert Änderungen in Leerzeichen bei der Suche des Kontextes"
 
-#: builtin/apply.c:4014
+#: builtin/apply.c:4330
 msgid "apply the patch in reverse"
 msgstr "wendet den Patch in umgekehrter Reihenfolge an"
 
-#: builtin/apply.c:4016
+#: builtin/apply.c:4332
 msgid "don't expect at least one line of context"
 msgstr "erwartet keinen Kontext"
 
-#: builtin/apply.c:4018
+#: builtin/apply.c:4334
 msgid "leave the rejected hunks in corresponding *.rej files"
 msgstr ""
 "hinterlässt zurückgewiesene Patch-Bereiche in den entsprechenden *.rej "
 "Dateien"
 
-#: builtin/apply.c:4020
+#: builtin/apply.c:4336
 msgid "allow overlapping hunks"
 msgstr "erlaubt sich überlappende Patch-Bereiche"
 
-#: builtin/apply.c:4021
+#: builtin/apply.c:4337
 msgid "be verbose"
 msgstr "erweiterte Ausgaben"
 
-#: builtin/apply.c:4023
+#: builtin/apply.c:4339
 msgid "tolerate incorrectly detected missing new-line at the end of file"
 msgstr "toleriert fehlerhaft erkannten fehlenden Zeilenumbruch am Dateiende"
 
-#: builtin/apply.c:4026
+#: builtin/apply.c:4342
 msgid "do not trust the line counts in the hunk headers"
 msgstr "vertraut nicht den Zeilennummern im Kopf des Patch-Bereiches"
 
-#: builtin/apply.c:4028
+#: builtin/apply.c:4344
 msgid "root"
 msgstr "Wurzelverzeichnis"
 
-#: builtin/apply.c:4029
+#: builtin/apply.c:4345
 msgid "prepend <root> to all filenames"
 msgstr "stellt <Wurzelverzeichnis> vor alle Dateinamen"
 
-#: builtin/apply.c:4050
+#: builtin/apply.c:4367
+msgid "--3way outside a repository"
+msgstr "--3way außerhalb eines Projektarchivs"
+
+#: builtin/apply.c:4375
 msgid "--index outside a repository"
 msgstr "--index außerhalb eines Projektarchivs"
 
-#: builtin/apply.c:4053
+#: builtin/apply.c:4378
 msgid "--cached outside a repository"
 msgstr "--cached außerhalb eines Projektarchivs"
 
-#: builtin/apply.c:4069
+#: builtin/apply.c:4394
 #, c-format
 msgid "can't open patch '%s'"
 msgstr "kann Patch '%s' nicht öffnen"
 
-#: builtin/apply.c:4083
+#: builtin/apply.c:4408
 #, c-format
 msgid "squelched %d whitespace error"
 msgid_plural "squelched %d whitespace errors"
 msgstr[0] "unterdrückte %d Fehler in Leerzeichen"
 msgstr[1] "unterdrückte %d Fehler in Leerzeichen"
 
-#: builtin/apply.c:4089 builtin/apply.c:4099
+#: builtin/apply.c:4414 builtin/apply.c:4424
 #, c-format
 msgid "%d line adds whitespace errors."
 msgid_plural "%d lines add whitespace errors."
@@ -1828,7 +2106,7 @@ msgstr "Konnte Beschreibungsvorlage für Zweig nicht schreiben: %s"
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Konnte Zweigspitze (HEAD) nicht als gültige Referenz auflösen."
 
-#: builtin/branch.c:788 builtin/clone.c:558
+#: builtin/branch.c:788 builtin/clone.c:561
 msgid "HEAD not found below refs/heads!"
 msgstr "Zweigspitze (HEAD) wurde nicht unter \"refs/heads\" gefunden!"
 
@@ -1855,99 +2133,99 @@ msgstr "Um ein Paket zu erstellen wird ein Projektarchiv benötigt."
 msgid "Need a repository to unbundle."
 msgstr "Zum Entpacken wird ein Projektarchiv benötigt."
 
-#: builtin/checkout.c:113 builtin/checkout.c:146
+#: builtin/checkout.c:114 builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
 msgstr "Pfad '%s' hat nicht unsere Version."
 
-#: builtin/checkout.c:115 builtin/checkout.c:148
+#: builtin/checkout.c:116 builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
 msgstr "Pfad '%s' hat nicht deren Version."
 
-#: builtin/checkout.c:131
+#: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
 msgstr "Pfad '%s' hat nicht alle notwendigen Versionen."
 
-#: builtin/checkout.c:175
+#: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
 msgstr "Pfad '%s' hat nicht die notwendigen Versionen."
 
-#: builtin/checkout.c:192
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr "Pfad '%s': kann nicht zusammenführen"
 
-#: builtin/checkout.c:209
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr "Konnte Ergebnis der Zusammenführung von '%s' nicht hinzufügen."
 
-#: builtin/checkout.c:234 builtin/checkout.c:392
+#: builtin/checkout.c:235 builtin/checkout.c:393
 msgid "corrupt index file"
 msgstr "beschädigte Bereitstellungsdatei"
 
-#: builtin/checkout.c:264 builtin/checkout.c:271
+#: builtin/checkout.c:265 builtin/checkout.c:272
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "Pfad '%s' ist nicht zusammengeführt."
 
-#: builtin/checkout.c:302 builtin/checkout.c:498 builtin/clone.c:583
+#: builtin/checkout.c:303 builtin/checkout.c:499 builtin/clone.c:586
 #: builtin/merge.c:812
 msgid "unable to write new index file"
 msgstr "Konnte neue Bereitstellungsdatei nicht schreiben."
 
-#: builtin/checkout.c:319 builtin/diff.c:302 builtin/merge.c:408
+#: builtin/checkout.c:320 builtin/diff.c:302 builtin/merge.c:408
 msgid "diff_setup_done failed"
 msgstr "diff_setup_done fehlgeschlagen"
 
-#: builtin/checkout.c:414
+#: builtin/checkout.c:415
 msgid "you need to resolve your current index first"
 msgstr "Du musst zuerst deine aktuelle Bereitstellung auflösen."
 
-#: builtin/checkout.c:533
+#: builtin/checkout.c:534
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr "Konnte \"reflog\" für '%s' nicht durchführen\n"
 
-#: builtin/checkout.c:566
+#: builtin/checkout.c:567
 msgid "HEAD is now at"
 msgstr "Zweigspitze (HEAD) ist jetzt bei"
 
-#: builtin/checkout.c:573
+#: builtin/checkout.c:574
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Setze Zweig '%s' zurück\n"
 
-#: builtin/checkout.c:576
+#: builtin/checkout.c:577
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Bereits auf '%s'\n"
 
-#: builtin/checkout.c:580
+#: builtin/checkout.c:581
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Gewechselt zu zurückgesetztem Zweig '%s'\n"
 
-#: builtin/checkout.c:582
+#: builtin/checkout.c:583
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Gewechselt zu einem neuen Zweig '%s'\n"
 
-#: builtin/checkout.c:584
+#: builtin/checkout.c:585
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Gewechselt zu Zweig '%s'\n"
 
-#: builtin/checkout.c:640
+#: builtin/checkout.c:641
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... und %d weitere.\n"
 
 #. The singular version
-#: builtin/checkout.c:646
+#: builtin/checkout.c:647
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -1970,7 +2248,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:664
+#: builtin/checkout.c:665
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -1985,71 +2263,71 @@ msgstr ""
 " git branch neuer_zweig_name %s\n"
 "\n"
 
-#: builtin/checkout.c:694
+#: builtin/checkout.c:695
 msgid "internal error in revision walk"
 msgstr "interner Fehler im Revisionsgang"
 
-#: builtin/checkout.c:698
+#: builtin/checkout.c:699
 msgid "Previous HEAD position was"
 msgstr "Vorherige Position der Zweigspitze (HEAD) war"
 
-#: builtin/checkout.c:724
+#: builtin/checkout.c:725 builtin/checkout.c:920
 msgid "You are on a branch yet to be born"
 msgstr "du bist auf einem Zweig, der noch geboren wird"
 
 #. case (1)
-#: builtin/checkout.c:855
+#: builtin/checkout.c:856
 #, c-format
 msgid "invalid reference: %s"
 msgstr "Ungültige Referenz: %s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:894
+#: builtin/checkout.c:895
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "Referenz ist kein Baum: %s"
 
-#: builtin/checkout.c:974
+#: builtin/checkout.c:977
 msgid "-B cannot be used with -b"
 msgstr "-B kann nicht mit -b benutzt werden"
 
-#: builtin/checkout.c:983
+#: builtin/checkout.c:986
 msgid "--patch is incompatible with all other options"
 msgstr "--patch ist inkompatibel mit allen anderen Optionen"
 
-#: builtin/checkout.c:986
+#: builtin/checkout.c:989
 msgid "--detach cannot be used with -b/-B/--orphan"
 msgstr "--detach kann nicht mit -b/-B/--orphan benutzt werden"
 
-#: builtin/checkout.c:988
+#: builtin/checkout.c:991
 msgid "--detach cannot be used with -t"
 msgstr "--detach kann nicht mit -t benutzt werden"
 
-#: builtin/checkout.c:994
+#: builtin/checkout.c:997
 msgid "--track needs a branch name"
 msgstr "--track benötigt einen Zweignamen"
 
-#: builtin/checkout.c:1001
+#: builtin/checkout.c:1004
 msgid "Missing branch name; try -b"
 msgstr "Vermisse Zweignamen; versuche -b"
 
-#: builtin/checkout.c:1007
+#: builtin/checkout.c:1010
 msgid "--orphan and -b|-B are mutually exclusive"
 msgstr "--orphan und -b|-B sind gegenseitig exklusiv"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1012
 msgid "--orphan cannot be used with -t"
 msgstr "--orphan kann nicht mit -t benutzt werden"
 
-#: builtin/checkout.c:1019
+#: builtin/checkout.c:1022
 msgid "git checkout: -f and -m are incompatible"
 msgstr "git checkout: -f und -m sind inkompatibel"
 
-#: builtin/checkout.c:1053
+#: builtin/checkout.c:1056
 msgid "invalid path specification"
 msgstr "ungültige Pfadspezifikation"
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid ""
 "git checkout: updating paths is incompatible with switching branches.\n"
@@ -2060,17 +2338,17 @@ msgstr ""
 "Hast du beabsichtigt '%s' auszuchecken, welcher nicht als Version aufgelöst "
 "werden kann?"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1066
 msgid "git checkout: updating paths is incompatible with switching branches."
 msgstr ""
 "git checkout: Die Aktualisierung von Pfaden ist inkompatibel mit dem Wechsel "
 "von Zweigen."
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1071
 msgid "git checkout: --detach does not take a path argument"
 msgstr "git checkout: --detach nimmt kein Pfad-Argument"
 
-#: builtin/checkout.c:1071
+#: builtin/checkout.c:1074
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -2078,11 +2356,11 @@ msgstr ""
 "git checkout: --ours/--theirs, --force and --merge sind inkompatibel wenn\n"
 "du aus der Bereitstellung auscheckst."
 
-#: builtin/checkout.c:1090
+#: builtin/checkout.c:1093
 msgid "Cannot switch branch to a non-commit."
 msgstr "Kann Zweig nur zu einer Version wechseln."
 
-#: builtin/checkout.c:1093
+#: builtin/checkout.c:1096
 msgid "--ours/--theirs is incompatible with switching branches."
 msgstr "--ours/--theirs ist inkompatibel mit den Wechseln von Zweigen."
 
@@ -2135,11 +2413,6 @@ msgstr "Entferne nicht %s\n"
 msgid "reference repository '%s' is not a local directory."
 msgstr "Referenziertes Projektarchiv '%s' ist kein lokales Verzeichnis."
 
-#: builtin/clone.c:302
-#, c-format
-msgid "failed to open '%s'"
-msgstr "Fehler beim Öffnen von '%s'"
-
 #: builtin/clone.c:306
 #, c-format
 msgid "failed to create directory '%s'"
@@ -2180,80 +2453,80 @@ msgstr "Konnte Datei nicht nach '%s' kopieren"
 msgid "done.\n"
 msgstr "Fertig.\n"
 
-#: builtin/clone.c:440
+#: builtin/clone.c:443
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "Konnte zu klonenden externer Zweig %s nicht finden."
 
-#: builtin/clone.c:549
+#: builtin/clone.c:552
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 "Externe Zweigspitze (HEAD) bezieht sich auf eine nicht existierende Referenz "
 "und kann nicht ausgecheckt werden.\n"
 
-#: builtin/clone.c:639
+#: builtin/clone.c:642
 msgid "Too many arguments."
 msgstr "Zu viele Argumente."
 
-#: builtin/clone.c:643
+#: builtin/clone.c:646
 msgid "You must specify a repository to clone."
 msgstr "Du musst ein Projektarchiv zum Klonen angeben."
 
-#: builtin/clone.c:654
+#: builtin/clone.c:657
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "--bare und --origin %s Optionen sind inkompatibel."
 
-#: builtin/clone.c:668
+#: builtin/clone.c:671
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "Projektarchiv '%s' existiert nicht."
 
-#: builtin/clone.c:673
+#: builtin/clone.c:676
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr "--depth wird in lokalen Klonen ignoriert; benutze stattdessen file://."
 
-#: builtin/clone.c:683
+#: builtin/clone.c:686
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "Zielpfad '%s' existiert bereits und ist kein leeres Verzeichnis."
 
-#: builtin/clone.c:693
+#: builtin/clone.c:696
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "Arbeitsbaum '%s' existiert bereits."
 
-#: builtin/clone.c:706 builtin/clone.c:720
+#: builtin/clone.c:709 builtin/clone.c:723
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "Konnte führende Verzeichnisse von '%s' nicht erstellen."
 
-#: builtin/clone.c:709
+#: builtin/clone.c:712
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr "Konnte Arbeitsverzeichnis '%s' nicht erstellen."
 
-#: builtin/clone.c:728
+#: builtin/clone.c:731
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Klone in bloßes Projektarchiv '%s'...\n"
 
-#: builtin/clone.c:730
+#: builtin/clone.c:733
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Klone nach '%s'...\n"
 
-#: builtin/clone.c:786
+#: builtin/clone.c:789
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr "Weiß nicht wie %s zu klonen ist."
 
-#: builtin/clone.c:835
+#: builtin/clone.c:838
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr "externer Zweig %s nicht im anderen Projektarchiv %s gefunden"
 
-#: builtin/clone.c:842
+#: builtin/clone.c:845
 msgid "You appear to have cloned an empty repository."
 msgstr "Du scheinst ein leeres Projektarchiv geklont zu haben."
 
@@ -2314,97 +2587,97 @@ msgstr ""
 "\n"
 "Andernfalls benutze bitte 'git reset'\n"
 
-#: builtin/commit.c:253
+#: builtin/commit.c:256
 msgid "failed to unpack HEAD tree object"
 msgstr "Fehler beim Entpacken des Baum-Objektes der Zweigspitze (HEAD)."
 
-#: builtin/commit.c:295
+#: builtin/commit.c:298
 msgid "unable to create temporary index"
 msgstr "Konnte temporäre Bereitstellung nicht erstellen."
 
-#: builtin/commit.c:301
+#: builtin/commit.c:304
 msgid "interactive add failed"
 msgstr "interaktives Hinzufügen fehlgeschlagen"
 
-#: builtin/commit.c:334 builtin/commit.c:355 builtin/commit.c:405
+#: builtin/commit.c:337 builtin/commit.c:358 builtin/commit.c:408
 msgid "unable to write new_index file"
 msgstr "Konnte new_index Datei nicht schreiben"
 
-#: builtin/commit.c:386
+#: builtin/commit.c:389
 msgid "cannot do a partial commit during a merge."
 msgstr ""
 "Kann keine partielle Eintragung durchführen, während eine Zusammenführung im "
 "Gange ist."
 
-#: builtin/commit.c:388
+#: builtin/commit.c:391
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr ""
 "Kann keine partielle Eintragung durchführen, während \"cherry-pick\" im "
 "Gange ist."
 
-#: builtin/commit.c:398
+#: builtin/commit.c:401
 msgid "cannot read the index"
 msgstr "Kann Bereitstellung nicht lesen"
 
-#: builtin/commit.c:418
+#: builtin/commit.c:421
 msgid "unable to write temporary index file"
 msgstr "Konnte temporäre Bereitstellungsdatei nicht schreiben."
 
-#: builtin/commit.c:493 builtin/commit.c:499
+#: builtin/commit.c:496 builtin/commit.c:502
 #, c-format
 msgid "invalid commit: %s"
 msgstr "Ungültige Version: %s"
 
-#: builtin/commit.c:522
+#: builtin/commit.c:525
 msgid "malformed --author parameter"
 msgstr "Fehlerhafter --author Parameter"
 
-#: builtin/commit.c:582
+#: builtin/commit.c:585
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "Fehlerhafte Identifikations-String: '%s'"
 
-#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
+#: builtin/commit.c:623 builtin/commit.c:656 builtin/commit.c:970
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "Konnte Version %s nicht nachschlagen"
 
-#: builtin/commit.c:632 builtin/shortlog.c:296
+#: builtin/commit.c:635 builtin/shortlog.c:296
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(lese Log-Nachricht von Standard-Eingabe)\n"
 
-#: builtin/commit.c:634
+#: builtin/commit.c:637
 msgid "could not read log from standard input"
 msgstr "Konnte Log nicht von Standard-Eingabe lesen."
 
-#: builtin/commit.c:638
+#: builtin/commit.c:641
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "Konnte Log-Datei '%s' nicht lesen"
 
-#: builtin/commit.c:644
+#: builtin/commit.c:647
 msgid "commit has empty message"
 msgstr "Version hat eine leere Beschreibung"
 
-#: builtin/commit.c:660
+#: builtin/commit.c:663
 msgid "could not read MERGE_MSG"
 msgstr "Konnte MERGE_MSG nicht lesen"
 
-#: builtin/commit.c:664
+#: builtin/commit.c:667
 msgid "could not read SQUASH_MSG"
 msgstr "Konnte SQUASH_MSG nicht lesen"
 
-#: builtin/commit.c:668
+#: builtin/commit.c:671
 #, c-format
 msgid "could not read '%s'"
 msgstr "Konnte '%s' nicht lesen"
 
-#: builtin/commit.c:720
+#: builtin/commit.c:723
 msgid "could not write commit template"
 msgstr "Konnte Versionsvorlage nicht schreiben"
 
-#: builtin/commit.c:731
+#: builtin/commit.c:734
 #, c-format
 msgid ""
 "\n"
@@ -2419,7 +2692,7 @@ msgstr ""
 "\t%s\n"
 "und versuche es erneut.\n"
 
-#: builtin/commit.c:736
+#: builtin/commit.c:739
 #, c-format
 msgid ""
 "\n"
@@ -2434,7 +2707,7 @@ msgstr ""
 "\t%s\n"
 "und versuche es erneut.\n"
 
-#: builtin/commit.c:748
+#: builtin/commit.c:751
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be ignored, and an empty message aborts the commit.\n"
@@ -2443,7 +2716,7 @@ msgstr ""
 "die mit '#' beginnen, werden ignoriert, und eine leere Versionsbeschreibung\n"
 "bricht die Eintragung ab.\n"
 
-#: builtin/commit.c:753
+#: builtin/commit.c:756
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be kept; you may remove them yourself if you want to.\n"
@@ -2454,171 +2727,171 @@ msgstr ""
 "entfernen.\n"
 "Eine leere Versionsbeschreibung bricht die Eintragung ab.\n"
 
-#: builtin/commit.c:766
+#: builtin/commit.c:769
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%sAutor:    %s"
 
-#: builtin/commit.c:773
+#: builtin/commit.c:776
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%sEintragender: %s"
 
-#: builtin/commit.c:793
+#: builtin/commit.c:796
 msgid "Cannot read index"
 msgstr "Kann Bereitstellung nicht lesen"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:833
 msgid "Error building trees"
 msgstr "Fehler beim Erzeugen der Zweige"
 
-#: builtin/commit.c:845 builtin/tag.c:361
+#: builtin/commit.c:848 builtin/tag.c:361
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Bitte liefere eine Beschreibung entweder mit der Option -m oder -F.\n"
 
-#: builtin/commit.c:942
+#: builtin/commit.c:945
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "Kein existierender Autor mit '%s' gefunden."
 
-#: builtin/commit.c:957 builtin/commit.c:1157
+#: builtin/commit.c:960 builtin/commit.c:1160
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Ungültiger Modus '%s' für unbeobachtete Dateien"
 
-#: builtin/commit.c:997
+#: builtin/commit.c:1000
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "Verwendung von --reset-author und --author macht keinen Sinn."
 
-#: builtin/commit.c:1008
+#: builtin/commit.c:1011
 msgid "You have nothing to amend."
 msgstr "Du hast nichts zum nachbessern."
 
-#: builtin/commit.c:1011
+#: builtin/commit.c:1014
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "Eine Zusammenführung ist im Gange -- kann nicht nachbessern."
 
-#: builtin/commit.c:1013
+#: builtin/commit.c:1016
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "\"cherry-pick\" ist im Gange -- kann nicht nachbessern."
 
-#: builtin/commit.c:1016
+#: builtin/commit.c:1019
 msgid "Options --squash and --fixup cannot be used together"
 msgstr ""
 "Die Optionen --squash und --fixup können nicht gemeinsam benutzt werden."
 
-#: builtin/commit.c:1026
+#: builtin/commit.c:1029
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Nur eines von -c/-C/-F/--fixup kann benutzt werden."
 
-#: builtin/commit.c:1028
+#: builtin/commit.c:1031
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
 msgstr "Option -m kann nicht mit -c/-C/-F/--fixup kombiniert werden"
 
-#: builtin/commit.c:1036
+#: builtin/commit.c:1039
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset--author kann nur mit -C, -c oder --amend benutzt werden"
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1056
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 "Nur eines von --include/--only/--all/--interactive/--patch kann benutzt "
 "werden."
 
-#: builtin/commit.c:1055
+#: builtin/commit.c:1058
 msgid "No paths with --include/--only does not make sense."
 msgstr "--include/--only machen ohne Pfade keinen Sinn."
 
-#: builtin/commit.c:1057
+#: builtin/commit.c:1060
 msgid "Clever... amending the last one with dirty index."
 msgstr ""
 "Klug... die letzte Version mit einer unsauberen Bereitstellung nachbessern."
 
-#: builtin/commit.c:1059
+#: builtin/commit.c:1062
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
 msgstr ""
 "Explizite Pfade ohne -i oder -o angegeben; unter der Annahme von --only "
 "Pfaden..."
 
-#: builtin/commit.c:1069 builtin/tag.c:577
+#: builtin/commit.c:1072 builtin/tag.c:577
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Ungültiger \"cleanup\" Modus %s"
 
-#: builtin/commit.c:1074
+#: builtin/commit.c:1077
 msgid "Paths with -a does not make sense."
 msgstr "Pfade mit -a machen keinen Sinn."
 
-#: builtin/commit.c:1257
+#: builtin/commit.c:1260
 msgid "couldn't look up newly created commit"
 msgstr "Konnte neu erstellte Version nicht nachschlagen."
 
-#: builtin/commit.c:1259
+#: builtin/commit.c:1262
 msgid "could not parse newly created commit"
 msgstr "Konnte neulich erstellte Version nicht analysieren."
 
-#: builtin/commit.c:1300
+#: builtin/commit.c:1303
 msgid "detached HEAD"
 msgstr "losgelöste Zweigspitze (HEAD)"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1305
 msgid " (root-commit)"
 msgstr " (Basis-Version)"
 
-#: builtin/commit.c:1446
+#: builtin/commit.c:1449
 msgid "could not parse HEAD commit"
 msgstr "Konnte Version der Zweigspitze (HEAD) nicht analysieren."
 
-#: builtin/commit.c:1484 builtin/merge.c:509
+#: builtin/commit.c:1487 builtin/merge.c:509
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "Konnte '%s' nicht zum Lesen öffnen."
 
-#: builtin/commit.c:1491
+#: builtin/commit.c:1494
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Beschädigte MERGE_HEAD-Datei (%s)"
 
-#: builtin/commit.c:1498
+#: builtin/commit.c:1501
 msgid "could not read MERGE_MODE"
 msgstr "Konnte MERGE_MODE nicht lesen"
 
-#: builtin/commit.c:1517
+#: builtin/commit.c:1520
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "Konnte Versionsbeschreibung nicht lesen: %s"
 
-#: builtin/commit.c:1531
+#: builtin/commit.c:1534
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Eintragung abgebrochen; du hast die Beschreibung nicht editiert.\n"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1539
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Eintragung aufgrund leerer Versionsbeschreibung abgebrochen.\n"
 
-#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1554 builtin/merge.c:936 builtin/merge.c:961
 msgid "failed to write commit object"
 msgstr "Fehler beim Schreiben des Versionsobjektes."
 
-#: builtin/commit.c:1572
+#: builtin/commit.c:1575
 msgid "cannot lock HEAD ref"
 msgstr "Kann Referenz der Zweigspitze (HEAD) nicht sperren."
 
-#: builtin/commit.c:1576
+#: builtin/commit.c:1579
 msgid "cannot update HEAD ref"
 msgstr "Kann Referenz der Zweigspitze (HEAD) nicht aktualisieren."
 
-#: builtin/commit.c:1587
+#: builtin/commit.c:1590
 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 ""
 "Das Projektarchiv wurde aktualisiert, aber die \"new_index\"-Datei\n"
-"konnte nicht geschrieben werden. Prüfe, dass dein Speicher nicht\n"
+"konnte nicht geschrieben werden. Prüfe, dass deine Festplatte nicht\n"
 "voll und Dein Kontingent nicht aufgebraucht ist und führe\n"
 "anschließend \"git reset HEAD\" zu Wiederherstellung aus."
 
@@ -2994,30 +3267,30 @@ msgstr ""
 msgid "both --cached and trees are given."
 msgstr "sowohl --cached als auch Zweige gegeben"
 
-#: builtin/help.c:63
+#: builtin/help.c:65
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "nicht erkanntes Hilfeformat: %s"
 
-#: builtin/help.c:91
+#: builtin/help.c:93
 msgid "Failed to start emacsclient."
 msgstr "Konnte emacsclient nicht starten."
 
-#: builtin/help.c:104
+#: builtin/help.c:106
 msgid "Failed to parse emacsclient version."
 msgstr "Konnte Version des emacsclient nicht parsen."
 
-#: builtin/help.c:112
+#: builtin/help.c:114
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "Version des emacsclient '%d' ist zu alt (< 22)."
 
-#: builtin/help.c:130 builtin/help.c:158 builtin/help.c:167 builtin/help.c:175
+#: builtin/help.c:132 builtin/help.c:160 builtin/help.c:169 builtin/help.c:177
 #, c-format
 msgid "failed to exec '%s': %s"
 msgstr "Fehler beim Ausführen von '%s': %s"
 
-#: builtin/help.c:215
+#: builtin/help.c:217
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -3026,7 +3299,7 @@ msgstr ""
 "'%s': Pfad für nicht unterstützten Handbuchbetrachter.\n"
 "Du könntest stattdessen 'man.<Werkzeug>.cmd' benutzen."
 
-#: builtin/help.c:227
+#: builtin/help.c:229
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -3035,34 +3308,29 @@ msgstr ""
 "'%s': Kommando für unterstützten Handbuchbetrachter.\n"
 "Du könntest stattdessen 'man.<Werkzeug>.path' benutzen."
 
-#: builtin/help.c:291
+#: builtin/help.c:299
 msgid "The most commonly used git commands are:"
 msgstr "Die allgemein verwendeten Git-Kommandos sind:"
 
-#: builtin/help.c:359
+#: builtin/help.c:367
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "'%s': unbekannter Handbuch-Betrachter."
 
-#: builtin/help.c:376
+#: builtin/help.c:384
 msgid "no man viewer handled the request"
 msgstr "kein Handbuch-Betrachter konnte mit dieser Anfrage umgehen"
 
-#: builtin/help.c:384
+#: builtin/help.c:392
 msgid "no info viewer handled the request"
 msgstr "kein Informations-Betrachter konnte mit dieser Anfrage umgehen"
 
-#: builtin/help.c:395
-#, c-format
-msgid "'%s': not a documentation directory."
-msgstr "'%s' ist kein Dokumentationsverzeichnis"
-
-#: builtin/help.c:436 builtin/help.c:443
+#: builtin/help.c:447 builtin/help.c:454
 #, c-format
 msgid "usage: %s%s"
 msgstr "Verwendung: %s%s"
 
-#: builtin/help.c:459
+#: builtin/help.c:470
 #, c-format
 msgid "`git %s' is aliased to `%s'"
 msgstr "für `git %s' wurde der Alias `%s' angelegt"
@@ -3137,176 +3405,176 @@ msgstr ""
 msgid "unknown object type %d"
 msgstr "Unbekannter Objekt-Typ %d"
 
-#: builtin/index-pack.c:531
+#: builtin/index-pack.c:530
 msgid "cannot pread pack file"
 msgstr "Kann Paketdatei %s nicht lesen"
 
-#: builtin/index-pack.c:533
+#: builtin/index-pack.c:532
 #, c-format
 msgid "premature end of pack file, %lu byte missing"
 msgid_plural "premature end of pack file, %lu bytes missing"
 msgstr[0] "frühzeitiges Ende der Paketdatei, vermisse %lu Byte"
 msgstr[1] "frühzeitiges Ende der Paketdatei, vermisse %lu Bytes"
 
-#: builtin/index-pack.c:555
+#: builtin/index-pack.c:558
 msgid "serious inflate inconsistency"
 msgstr "ernsthafte Inkonsistenz nach Dekomprimierung"
 
-#: builtin/index-pack.c:646 builtin/index-pack.c:652 builtin/index-pack.c:675
-#: builtin/index-pack.c:709 builtin/index-pack.c:718
+#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678
+#: builtin/index-pack.c:712 builtin/index-pack.c:721
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SHA1 KOLLISION MIT %s GEFUNDEN !"
 
-#: builtin/index-pack.c:649 builtin/pack-objects.c:170
+#: builtin/index-pack.c:652 builtin/pack-objects.c:170
 #: builtin/pack-objects.c:262
 #, c-format
 msgid "unable to read %s"
 msgstr "kann %s nicht lesen"
 
-#: builtin/index-pack.c:715
+#: builtin/index-pack.c:718
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "Kann existierendes Objekt %s nicht lesen."
 
-#: builtin/index-pack.c:729
+#: builtin/index-pack.c:732
 #, c-format
 msgid "invalid blob object %s"
 msgstr "ungültiges Blob-Objekt %s"
 
-#: builtin/index-pack.c:744
+#: builtin/index-pack.c:747
 #, c-format
 msgid "invalid %s"
 msgstr "Ungültiger Objekt-Typ %s"
 
-#: builtin/index-pack.c:746
+#: builtin/index-pack.c:749
 msgid "Error in object"
 msgstr "Fehler in Objekt"
 
-#: builtin/index-pack.c:748
+#: builtin/index-pack.c:751
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "Nicht alle Kind-Objekte von %s sind erreichbar"
 
-#: builtin/index-pack.c:818 builtin/index-pack.c:844
+#: builtin/index-pack.c:821 builtin/index-pack.c:847
 msgid "failed to apply delta"
 msgstr "Konnte Dateiunterschied nicht anwenden"
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Receiving objects"
 msgstr "Empfange Objekte"
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Indexing objects"
 msgstr "Indiziere Objekte"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1012
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "Paket ist beschädigt (SHA1 unterschiedlich)"
 
-#: builtin/index-pack.c:1014
+#: builtin/index-pack.c:1017
 msgid "cannot fstat packfile"
 msgstr "kann Paketdatei nicht lesen"
 
-#: builtin/index-pack.c:1017
+#: builtin/index-pack.c:1020
 msgid "pack has junk at the end"
 msgstr "Paketende enthält nicht verwendbaren Inhalt"
 
-#: builtin/index-pack.c:1028
+#: builtin/index-pack.c:1031
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "Fehler beim Ausführen von \"parse_pack_objects()\""
 
-#: builtin/index-pack.c:1051
+#: builtin/index-pack.c:1054
 msgid "Resolving deltas"
 msgstr "Löse Unterschiede auf"
 
-#: builtin/index-pack.c:1102
+#: builtin/index-pack.c:1105
 msgid "confusion beyond insanity"
 msgstr "Fehler beim Auflösen der Unterschiede"
 
-#: builtin/index-pack.c:1121
+#: builtin/index-pack.c:1124
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "Paket hat %d unaufgelöste Unterschied"
 msgstr[1] "Paket hat %d unaufgelöste Unterschiede"
 
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1149
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "Konnte angehängtes Objekt (%d) nicht komprimieren"
 
-#: builtin/index-pack.c:1225
+#: builtin/index-pack.c:1228
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "lokales Objekt %s ist beschädigt"
 
-#: builtin/index-pack.c:1249
+#: builtin/index-pack.c:1252
 msgid "error while closing pack file"
 msgstr "Fehler beim Schließen der Paketdatei"
 
-#: builtin/index-pack.c:1262
+#: builtin/index-pack.c:1265
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr "Kann Paketbeschreibungsdatei '%s' nicht schreiben"
 
-#: builtin/index-pack.c:1270
+#: builtin/index-pack.c:1273
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr "Kann eben erstellte Paketbeschreibungsdatei '%s' nicht schließen"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1286
 msgid "cannot store pack file"
 msgstr "Kann Paketdatei nicht speichern"
 
-#: builtin/index-pack.c:1294
+#: builtin/index-pack.c:1297
 msgid "cannot store index file"
 msgstr "Kann Indexdatei nicht speichern"
 
-#: builtin/index-pack.c:1395
+#: builtin/index-pack.c:1398
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Kann existierende Paketdatei '%s' nicht öffnen"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1400
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "Kann existierende Indexdatei für Paket '%s' nicht öffnen"
 
-#: builtin/index-pack.c:1444
+#: builtin/index-pack.c:1447
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "kein Unterschied: %d Objekt"
 msgstr[1] "kein Unterschied: %d Objekte"
 
-#: builtin/index-pack.c:1451
+#: builtin/index-pack.c:1454
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "Länge der Objekt-Liste = %d: %lu Objekt"
 msgstr[1] "Länge der Objekt-Liste = %d: %lu Objekte"
 
-#: builtin/index-pack.c:1478
+#: builtin/index-pack.c:1481
 msgid "Cannot come back to cwd"
 msgstr "Kann nicht zurück zu Arbeitsverzeichnis wechseln"
 
-#: builtin/index-pack.c:1522 builtin/index-pack.c:1525
-#: builtin/index-pack.c:1537 builtin/index-pack.c:1541
+#: builtin/index-pack.c:1525 builtin/index-pack.c:1528
+#: builtin/index-pack.c:1540 builtin/index-pack.c:1544
 #, c-format
 msgid "bad %s"
 msgstr "%s ist ungültig"
 
-#: builtin/index-pack.c:1555
+#: builtin/index-pack.c:1558
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin kann nicht ohne --stdin benutzt werden"
 
-#: builtin/index-pack.c:1559 builtin/index-pack.c:1569
+#: builtin/index-pack.c:1562 builtin/index-pack.c:1572
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "Name der Paketdatei '%s' endet nicht mit '.pack'"
 
-#: builtin/index-pack.c:1578
+#: builtin/index-pack.c:1581
 msgid "--verify with no packfile name given"
 msgstr "--verify ohne Name der Paketdatei angegeben"
 
@@ -3380,22 +3648,22 @@ msgstr "kopiere keine Vorlagen mit einer falschen Formatversion %d von '%s'"
 msgid "insane git directory %s"
 msgstr "ungültiges Git-Verzeichnis %s"
 
-#: builtin/init-db.c:322 builtin/init-db.c:325
+#: builtin/init-db.c:323 builtin/init-db.c:326
 #, c-format
 msgid "%s already exists"
 msgstr "%s existiert bereits"
 
-#: builtin/init-db.c:354
+#: builtin/init-db.c:355
 #, c-format
 msgid "unable to handle file type %d"
 msgstr "kann nicht mit Dateityp %d umgehen"
 
-#: builtin/init-db.c:357
+#: builtin/init-db.c:358
 #, c-format
 msgid "unable to move %s to %s"
 msgstr "Konnte %s nicht nach %s verschieben"
 
-#: builtin/init-db.c:362
+#: builtin/init-db.c:363
 #, c-format
 msgid "Could not create git link %s"
 msgstr "Konnte git-Verknüfung %s nicht erstellen"
@@ -3405,38 +3673,38 @@ msgstr "Konnte git-Verknüfung %s nicht erstellen"
 #. * existing" or "Initialized empty", the second " shared" or
 #. * "", and the last '%s%s' is the verbatim directory name.
 #.
-#: builtin/init-db.c:419
+#: builtin/init-db.c:420
 #, c-format
 msgid "%s%s Git repository in %s%s\n"
 msgstr "%s%s Git-Projektarchiv in %s%s\n"
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Reinitialized existing"
 msgstr "Reinitialisierte existierendes"
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Initialized empty"
 msgstr "Initialisierte leeres"
 
-#: builtin/init-db.c:421
+#: builtin/init-db.c:422
 msgid " shared"
 msgstr " gemeinsames"
 
-#: builtin/init-db.c:440
+#: builtin/init-db.c:441
 msgid "cannot tell cwd"
 msgstr "kann aktuelles Arbeitsverzeichnis nicht ermitteln"
 
-#: builtin/init-db.c:521 builtin/init-db.c:528
+#: builtin/init-db.c:522 builtin/init-db.c:529
 #, c-format
 msgid "cannot mkdir %s"
 msgstr "kann Verzeichnis %s nicht erstellen"
 
-#: builtin/init-db.c:532
+#: builtin/init-db.c:533
 #, c-format
 msgid "cannot chdir to %s"
 msgstr "kann nicht in Verzeichnis %s wechseln"
 
-#: builtin/init-db.c:554
+#: builtin/init-db.c:555
 #, c-format
 msgid ""
 "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
@@ -3445,11 +3713,11 @@ msgstr ""
 "%s (oder --work-tree=<Verzeichnis>) nicht erlaubt ohne Spezifizierung von %s "
 "(oder --git-dir=<Verzeichnis>)"
 
-#: builtin/init-db.c:578
+#: builtin/init-db.c:579
 msgid "Cannot access current working directory"
 msgstr "Kann nicht auf aktuelles Arbeitsverzeichnis zugreifen."
 
-#: builtin/init-db.c:585
+#: builtin/init-db.c:586
 #, c-format
 msgid "Cannot access work tree '%s'"
 msgstr "Kann nicht auf Arbeitsbaum '%s' zugreifen."
@@ -3459,89 +3727,89 @@ msgstr "Kann nicht auf Arbeitsbaum '%s' zugreifen."
 msgid "Final output: %d %s\n"
 msgstr "letzte Ausgabe: %d %s\n"
 
-#: builtin/log.c:402 builtin/log.c:490
+#: builtin/log.c:403 builtin/log.c:494
 #, c-format
 msgid "Could not read object %s"
 msgstr "Kann Objekt %s nicht lesen."
 
-#: builtin/log.c:514
+#: builtin/log.c:518
 #, c-format
 msgid "Unknown type: %d"
 msgstr "Unbekannter Typ: %d"
 
-#: builtin/log.c:603
+#: builtin/log.c:608
 msgid "format.headers without value"
 msgstr "format.headers ohne Wert"
 
-#: builtin/log.c:677
+#: builtin/log.c:682
 msgid "name of output directory is too long"
 msgstr "Name des Ausgabeverzeichnisses ist zu lang."
 
-#: builtin/log.c:688
+#: builtin/log.c:693
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr "Kann Patch-Datei %s nicht öffnen"
 
-#: builtin/log.c:702
+#: builtin/log.c:707
 msgid "Need exactly one range."
 msgstr "Brauche genau einen Versionsbereich."
 
-#: builtin/log.c:710
+#: builtin/log.c:715
 msgid "Not a range."
 msgstr "Kein Versionsbereich."
 
-#: builtin/log.c:787
+#: builtin/log.c:792
 msgid "Cover letter needs email format"
 msgstr "Anschreiben benötigt E-Mail-Format"
 
-#: builtin/log.c:860
+#: builtin/log.c:865
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr "ungültiges in-reply-to: %s"
 
-#: builtin/log.c:933
+#: builtin/log.c:938
 msgid "Two output directories?"
 msgstr "Zwei Ausgabeverzeichnisse?"
 
-#: builtin/log.c:1154
+#: builtin/log.c:1160
 #, c-format
 msgid "bogus committer info %s"
 msgstr "unechte Einreicher-Informationen %s"
 
-#: builtin/log.c:1199
+#: builtin/log.c:1205
 msgid "-n and -k are mutually exclusive."
 msgstr "-n und -k schliessen sich gegenseitig aus"
 
-#: builtin/log.c:1201
+#: builtin/log.c:1207
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr "--subject-prefix und -k schliessen sich gegenseitig aus"
 
-#: builtin/log.c:1209
+#: builtin/log.c:1215
 msgid "--name-only does not make sense"
 msgstr "--name-only macht keinen Sinn"
 
-#: builtin/log.c:1211
+#: builtin/log.c:1217
 msgid "--name-status does not make sense"
 msgstr "--name-status macht keinen Sinn"
 
-#: builtin/log.c:1213
+#: builtin/log.c:1219
 msgid "--check does not make sense"
 msgstr "--check macht keinen Sinn"
 
-#: builtin/log.c:1236
+#: builtin/log.c:1242
 msgid "standard output, or directory, which one?"
 msgstr "Standard-Ausgabe oder Verzeichnis, welches von beidem?"
 
-#: builtin/log.c:1238
+#: builtin/log.c:1244
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "Konnte Verzeichnis '%s' nicht erstellen."
 
-#: builtin/log.c:1391
+#: builtin/log.c:1397
 msgid "Failed to create output files"
 msgstr "Fehler beim Erstellen der Ausgabedateien."
 
-#: builtin/log.c:1495
+#: builtin/log.c:1501
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
@@ -3549,7 +3817,7 @@ msgstr ""
 "Konnte gefolgten, externen Zweig nicht finden, bitte gebe <upstream> manuell "
 "an.\n"
 
-#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
+#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531
 #, c-format
 msgid "Unknown commit %s"
 msgstr "Unbekannte Version %s"
@@ -3632,10 +3900,6 @@ msgstr "\"git write-tree\" schlug beim Schreiben eines Baumes fehl"
 msgid "failed to read the cache"
 msgstr "Lesen des Zwischenspeichers fehlgeschlagen"
 
-#: builtin/merge.c:697
-msgid "Unable to write index."
-msgstr "Konnte Bereitstellung nicht schreiben."
-
 #: builtin/merge.c:710
 msgid "Not handling anything other than two heads merge."
 msgstr "Es wird nur die Zusammenführung von zwei Zweigen behandelt."
@@ -4694,31 +4958,31 @@ msgstr ""
 "Kann keine '%s' Zurücksetzung durchführen, während eine Zusammenführung im "
 "Gange ist."
 
-#: builtin/reset.c:297
+#: builtin/reset.c:303
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "Konnte Objekt '%s' nicht parsen."
 
-#: builtin/reset.c:302
+#: builtin/reset.c:308
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch ist inkompatibel mit --{hard,mixed,soft}"
 
-#: builtin/reset.c:311
+#: builtin/reset.c:317
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr ""
 "--mixed mit Pfaden ist veraltet; benutze stattdessen 'git reset -- <Pfade>'."
 
-#: builtin/reset.c:313
+#: builtin/reset.c:319
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "Eine '%s' Zurücksetzung mit Pfaden ist nicht möglich."
 
-#: builtin/reset.c:325
+#: builtin/reset.c:331
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr "'%s' Zurücksetzung ist in einem bloßen Projektarchiv nicht erlaubt"
 
-#: builtin/reset.c:341
+#: builtin/reset.c:347
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "Konnte Bereitstellungsdatei nicht zu Version '%s' zurücksetzen."
@@ -5069,11 +5333,11 @@ msgstr ""
 #: git-am.sh:105
 #, sh-format
 msgid ""
-"When you have resolved this problem run \"$cmdline --resolved\".\n"
-"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
-"To restore the original branch and stop patching run \"$cmdline --abort\"."
+"When you have resolved this problem, run \"$cmdline --resolved\".\n"
+"If you prefer to skip this patch, run \"$cmdline --skip\" instead.\n"
+"To restore the original branch and stop patching, run \"$cmdline --abort\"."
 msgstr ""
-"Wenn du das Problem aufgelöst hast, führe \"$cmdline --resolved\" aus.\n"
+"Wenn du das Problem gelöst hast, führe \"$cmdline --resolved\" aus.\n"
 "Falls du diesen Patch auslassen möchtest, führe stattdessen \"$cmdline --skip"
 "\" aus.\n"
 "Um den ursprünglichen Zweig wiederherzustellen und die Anwendung der "
@@ -5090,6 +5354,12 @@ msgstr ""
 "Dem Projektarchiv fehlen notwendige Blobs um auf eine 3-Wege-Zusammenführung "
 "zurückzufallen."
 
+#: git-am.sh:139
+msgid "Using index info to reconstruct a base tree..."
+msgstr ""
+"Verwende Informationen aus der Bereitstellung um einen Basisbaum "
+"nachzustellen"
+
 #: git-am.sh:154
 msgid ""
 "Did you hand edit your patch?\n"
@@ -5102,45 +5372,53 @@ msgstr ""
 msgid "Falling back to patching base and 3-way merge..."
 msgstr "Falle zurück zum Patchen der Basis und der 3-Wege-Zusammenführung..."
 
-#: git-am.sh:275
+#: git-am.sh:179
+msgid "Failed to merge in the changes."
+msgstr "Zusammenführung der Änderungen fehlgeschlagen"
+
+#: git-am.sh:274
 msgid "Only one StGIT patch series can be applied at once"
 msgstr "Es kann nur eine StGIT Patch-Serie auf einmal angewendet werden."
 
-#: git-am.sh:362
+#: git-am.sh:361
 #, sh-format
 msgid "Patch format $patch_format is not supported."
 msgstr "Patch-Format $patch_format wird nicht unterstützt."
 
-#: git-am.sh:364
+#: git-am.sh:363
 msgid "Patch format detection failed."
 msgstr "Patch-Formaterkennung fehlgeschlagen."
 
-#: git-am.sh:418
-msgid "-d option is no longer supported.  Do not use."
-msgstr "-d Option wird nicht länger unterstützt. Nicht benutzen."
+#: git-am.sh:389
+msgid ""
+"The -b/--binary option has been a no-op for long time, and\n"
+"it will be removed. Please do not use it anymore."
+msgstr ""
+"Die -b/--binary Option hat seit Langem keinen Effekt und wird\n"
+"entfernt. Bitte nicht mehr verwenden."
 
-#: git-am.sh:481
+#: git-am.sh:477
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
 msgstr ""
 "Vorheriges Verzeichnis des Neuaufbaus $dotest existiert noch, aber mbox "
 "gegeben."
 
-#: git-am.sh:486
+#: git-am.sh:482
 msgid "Please make up your mind. --skip or --abort?"
 msgstr "Bitte werde dir klar. --skip oder --abort?"
 
-#: git-am.sh:513
+#: git-am.sh:509
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr "Es ist keine Auflösung im Gange, es wird nicht fortgesetzt."
 
-#: git-am.sh:579
+#: git-am.sh:575
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
 msgstr ""
 "Unsaubere Bereitstellung: kann Patches nicht anwenden (unsauber: $files)"
 
-#: git-am.sh:671
+#: git-am.sh:679
 #, sh-format
 msgid ""
 "Patch is empty.  Was it split wrong?\n"
@@ -5154,33 +5432,33 @@ msgstr ""
 "Patches\n"
 "abzubrechen, führe \"$cmdline --abort\" aus."
 
-#: git-am.sh:708
+#: git-am.sh:706
 msgid "Patch does not have a valid e-mail address."
 msgstr "Patch enthält keine gültige eMail-Adresse."
 
-#: git-am.sh:755
+#: git-am.sh:753
 msgid "cannot be interactive without stdin connected to a terminal."
 msgstr ""
 "Kann nicht interaktiv sein, ohne dass die Standard-Eingabe mit einem "
 "Terminal verbunden ist."
 
-#: git-am.sh:759
+#: git-am.sh:757
 msgid "Commit Body is:"
 msgstr "Beschreibung der Eintragung ist:"
 
 #. 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:766
+#: git-am.sh:764
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr "Anwenden? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 
-#: git-am.sh:802
+#: git-am.sh:800
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr "Wende an: $FIRSTLINE"
 
-#: git-am.sh:823
+#: git-am.sh:821
 msgid ""
 "No changes - did you forget to use 'git add'?\n"
 "If there is nothing left to stage, chances are that something else\n"
@@ -5191,7 +5469,7 @@ msgstr ""
 "diese bereits anderweitig eingefügt worden sein; du könntest diesen Patch\n"
 "auslassen."
 
-#: git-am.sh:831
+#: git-am.sh:829
 msgid ""
 "You still have unmerged paths in your index\n"
 "did you forget to use 'git add'?"
@@ -5199,16 +5477,16 @@ msgstr ""
 "Du hast immer noch nicht zusammengeführte Pfade in der Bereitstellung.\n"
 "Hast du vergessen 'git add' zu benutzen?"
 
-#: git-am.sh:847
+#: git-am.sh:845
 msgid "No changes -- Patch already applied."
 msgstr "Keine Änderungen -- Patches bereits angewendet."
 
-#: git-am.sh:857
+#: git-am.sh:855
 #, sh-format
 msgid "Patch failed at $msgnum $FIRSTLINE"
 msgstr "Anwendung des Patches fehlgeschlagen bei $msgnum $FIRSTLINE"
 
-#: git-am.sh:873
+#: git-am.sh:876
 msgid "applying to an empty history"
 msgstr "wende zu leerer Historie an"
 
@@ -5413,6 +5691,131 @@ msgstr "Kann nicht mehrere Zweige in einen ungeborenen Zweig zusammenführen"
 msgid "Cannot rebase onto multiple branches"
 msgstr "kann nicht auf mehrere Zweige neu aufbauen"
 
+#: git-rebase.sh:52
+msgid ""
+"When you have resolved this problem, run \"git rebase --continue\".\n"
+"If you prefer to skip this patch, run \"git rebase --skip\" instead.\n"
+"To check out the original branch and stop rebasing, run \"git rebase --abort"
+"\"."
+msgstr ""
+"Wenn du das Problem aufgelöst hast, führe \"git rebase --continue\" aus.\n"
+"Falls du diesen Patch auslassen möchtest, führe stattdessen \"git rebase --"
+"skip\" aus.\n"
+"Um den ursprünglichen Zweig wiederherzustellen und den Neuaufbau "
+"abzubrechen,\n"
+"führe \"git rebase --abort\" aus."
+
+#: git-rebase.sh:159
+msgid "The pre-rebase hook refused to rebase."
+msgstr "Der \"pre-rebase hook\" hat den Neuaufbau zurückgewiesen."
+
+#: git-rebase.sh:164
+msgid "It looks like git-am is in progress. Cannot rebase."
+msgstr "\"git-am\" scheint im Gange zu sein. Kann nicht neu aufbauen."
+
+#: git-rebase.sh:295
+msgid "The --exec option must be used with the --interactive option"
+msgstr "Die --exec Option muss mit der --interactive Option benutzt werden"
+
+#: git-rebase.sh:300
+msgid "No rebase in progress?"
+msgstr "Kein Neuaufbau im Gange?"
+
+#: git-rebase.sh:313
+msgid "Cannot read HEAD"
+msgstr "Kann Zweigspitze (HEAD) nicht lesen"
+
+#: git-rebase.sh:316
+msgid ""
+"You must edit all merge conflicts and then\n"
+"mark them as resolved using git add"
+msgstr ""
+"Du musst alle Zusammenführungskonflikte editieren und diese dann\n"
+"mittels \"git add\" als aufgelöst markieren"
+
+#: git-rebase.sh:334
+#, sh-format
+msgid "Could not move back to $head_name"
+msgstr "Konnte nicht zu $head_name zurückgehen"
+
+#: git-rebase.sh:350
+#, sh-format
+msgid ""
+"It seems that there is already a $state_dir_base directory, and\n"
+"I wonder if you are in the middle of another rebase.  If that is the\n"
+"case, please try\n"
+"\t$cmd_live_rebase\n"
+"If that is not the case, please\n"
+"\t$cmd_clear_stale_rebase\n"
+"and run me again.  I am stopping in case you still have something\n"
+"valuable there."
+msgstr ""
+"Es scheint so, als gäbe es das Verzeichnis $state_dir_base bereits, und\n"
+"es wäre verwunderlich, wenn ein Neuaufbau bereits im Gange ist. Wenn das\n"
+"der Fall ist, probiere bitte\n"
+"\t$cmd_live_rebase\n"
+"Wenn das nicht der Fall ist, probiere bitte\n"
+"\t$cmd_clear_stale_rebase\n"
+"und führe dieses Kommando nochmal aus. Es wird angehalten, falls bereits\n"
+"etwas Nützliches vorhanden ist."
+
+#: git-rebase.sh:395
+#, sh-format
+msgid "invalid upstream $upstream_name"
+msgstr "ungültiger Übernahmezweig $upstream_name"
+
+#: git-rebase.sh:419
+#, sh-format
+msgid "$onto_name: there are more than one merge bases"
+msgstr "$onto_name: es gibt mehr als eine Zusammenführungsbasis"
+
+#: git-rebase.sh:422 git-rebase.sh:426
+#, sh-format
+msgid "$onto_name: there is no merge base"
+msgstr "$onto_name: es gibt keine Zusammenführungsbasis"
+
+#: git-rebase.sh:431
+#, sh-format
+msgid "Does not point to a valid commit: $onto_name"
+msgstr "$onto_name zeigt auf keine gültige Version"
+
+#: git-rebase.sh:454
+#, sh-format
+msgid "fatal: no such branch: $branch_name"
+msgstr "fatal: Zweig $branch_name nicht gefunden"
+
+#: git-rebase.sh:474
+msgid "Please commit or stash them."
+msgstr "Bitte trage die Änderungen ein oder benutze \"stash\"."
+
+#: git-rebase.sh:492
+#, sh-format
+msgid "Current branch $branch_name is up to date."
+msgstr "Aktueller Zweig $branch_name ist auf dem neusten Stand."
+
+#: git-rebase.sh:495
+#, sh-format
+msgid "Current branch $branch_name is up to date, rebase forced."
+msgstr ""
+"Aktueller Zweig $branch_name ist auf dem neusten Stand, Neuaufbau erzwungen."
+
+#: git-rebase.sh:506
+#, sh-format
+msgid "Changes from $mb to $onto:"
+msgstr "Änderungen von $mb zu $onto:"
+
+#. Detach HEAD and reset the tree
+#: git-rebase.sh:515
+msgid "First, rewinding head to replay your work on top of it..."
+msgstr ""
+"Zunächst wird die Zweigspitze zurückgespult, um deine Änderungen\n"
+"darauf neu anzuwenden..."
+
+#: git-rebase.sh:523
+#, sh-format
+msgid "Fast-forwarded $branch_name to $onto_name."
+msgstr "$branch_name zu $onto_name vorgespult."
+
 #: git-stash.sh:51
 msgid "git stash clear with parameters is unimplemented"
 msgstr "git stash clear mit Parametern ist nicht implementiert"
@@ -5555,28 +5958,28 @@ msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
 msgstr ""
 "Keine Unterprojekt-Zuordnung in .gitmodules für Pfad '$sm_path' gefunden"
 
-#: git-submodule.sh:186
+#: git-submodule.sh:189
 #, sh-format
 msgid "Clone of '$url' into submodule path '$sm_path' failed"
 msgstr "Klonen von '$url' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
 
-#: git-submodule.sh:196
+#: git-submodule.sh:201
 #, sh-format
 msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
 msgstr ""
 "Git-Verzeichnis '$a' ist Teil des Unterprojekt-Pfades '$b', oder umgekehrt"
 
-#: git-submodule.sh:285
+#: git-submodule.sh:290
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "repo URL: '$repo' muss absolut sein oder mit ./|../ beginnen"
 
-#: git-submodule.sh:302
+#: git-submodule.sh:307
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "'$sm_path' existiert bereits in der Bereitstellung"
 
-#: git-submodule.sh:306
+#: git-submodule.sh:311
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -5587,65 +5990,65 @@ msgstr ""
 "$sm_path\n"
 "Benutze -f wenn du diesen wirklich hinzufügen möchtest."
 
-#: git-submodule.sh:317
+#: git-submodule.sh:322
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr ""
 "Füge existierendes Projektarchiv in '$sm_path' der Bereitstellung hinzu."
 
-#: git-submodule.sh:319
+#: git-submodule.sh:324
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "'$sm_path' existiert bereits und ist kein gültiges Git-Projektarchiv"
 
-#: git-submodule.sh:333
+#: git-submodule.sh:338
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "Unfähig Unterprojekt '$sm_path' auszuchecken"
 
-#: git-submodule.sh:338
+#: git-submodule.sh:343
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "Hinzufügen von Unterprojekt '$sm_path' fehlgeschlagen"
 
-#: git-submodule.sh:343
+#: git-submodule.sh:348
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "Registierung von Unterprojekt '$sm_path' fehlgeschlagen"
 
-#: git-submodule.sh:385
+#: git-submodule.sh:390
 #, sh-format
 msgid "Entering '$prefix$sm_path'"
 msgstr "Betrete '$prefix$sm_path'"
 
-#: git-submodule.sh:399
+#: git-submodule.sh:404
 #, sh-format
 msgid "Stopping at '$sm_path'; script returned non-zero status."
 msgstr "Stoppe bei '$sm_path'; Skript gab nicht-Null Status zurück."
 
-#: git-submodule.sh:442
+#: git-submodule.sh:447
 #, sh-format
 msgid "No url found for submodule path '$sm_path' in .gitmodules"
 msgstr "Keine URL für Unterprojekt-Pfad '$sm_path' in .gitmodules gefunden"
 
-#: git-submodule.sh:451
+#: git-submodule.sh:456
 #, sh-format
 msgid "Failed to register url for submodule path '$sm_path'"
 msgstr "Registrierung der URL für Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
 
-#: git-submodule.sh:453
+#: git-submodule.sh:458
 #, sh-format
 msgid "Submodule '$name' ($url) registered for path '$sm_path'"
 msgstr "Unterprojekt '$name' ($url) ist für Pfad '$sm_path' registriert"
 
-#: git-submodule.sh:461
+#: git-submodule.sh:466
 #, sh-format
 msgid "Failed to register update mode for submodule path '$sm_path'"
 msgstr ""
 "Registrierung des Aktualisierungsmodus für Unterprojekt-Pfad '$sm_path' "
 "fehlgeschlagen"
 
-#: git-submodule.sh:560
+#: git-submodule.sh:565
 #, sh-format
 msgid ""
 "Submodule path '$sm_path' not initialized\n"
@@ -5654,99 +6057,104 @@ msgstr ""
 "Unterprojekt-Pfad '$sm_path' ist nicht initialisiert\n"
 "Vielleicht möchtest du 'update --init' benutzen?"
 
-#: git-submodule.sh:573
+#: git-submodule.sh:578
 #, sh-format
 msgid "Unable to find current revision in submodule path '$sm_path'"
 msgstr "Konnte aktuelle Version in Unterprojekt-Pfad '$sm_path' nicht finden"
 
-#: git-submodule.sh:592
+#: git-submodule.sh:597
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "Konnte in Unterprojekt-Pfad '$sm_path' nicht anfordern"
 
-#: git-submodule.sh:606
+#: git-submodule.sh:611
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
 msgstr "Neuaufbau von '$sha1' in Unterprojekt-Pfad '$sm_path' nicht möglich"
 
-#: git-submodule.sh:607
+#: git-submodule.sh:612
 #, sh-format
 msgid "Submodule path '$sm_path': rebased into '$sha1'"
 msgstr "Unterprojekt-Pfad '$sm_path': neu aufgebaut in '$sha1'"
 
-#: git-submodule.sh:612
+#: git-submodule.sh:617
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
 msgstr ""
 "Zusammenführung von '$sha1' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen"
 
-#: git-submodule.sh:613
+#: git-submodule.sh:618
 #, sh-format
 msgid "Submodule path '$sm_path': merged in '$sha1'"
 msgstr "Unterprojekt-Pfad '$sm_path': zusammengeführt in '$sha1'"
 
-#: git-submodule.sh:618
+#: git-submodule.sh:623
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
 msgstr "Konnte '$sha1' in Unterprojekt-Pfad '$sm_path' nicht auschecken."
 
-#: git-submodule.sh:619
+#: git-submodule.sh:624
 #, sh-format
 msgid "Submodule path '$sm_path': checked out '$sha1'"
 msgstr "Unterprojekt-Pfad: '$sm_path': '$sha1' ausgecheckt"
 
-#: git-submodule.sh:641 git-submodule.sh:964
+#: git-submodule.sh:646 git-submodule.sh:969
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr "Fehler bei Rekursion in Unterprojekt-Pfad '$sm_path'"
 
-#: git-submodule.sh:749
-msgid "--cached cannot be used with --files"
-msgstr "--cached kann nicht mit --files benutzt werden"
+#: git-submodule.sh:754
+msgid "The --cached option cannot be used with the --files option"
+msgstr "Die --cached Option kann nicht mit der --files Option benutzt werden"
 
 #. unexpected type
-#: git-submodule.sh:789
+#: git-submodule.sh:794
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "unerwarteter Modus $mod_dst"
 
-#: git-submodule.sh:807
+#: git-submodule.sh:812
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_src"
 msgstr "  Warnung: $name beinhaltet nicht Version $sha1_src"
 
-#: git-submodule.sh:810
+#: git-submodule.sh:815
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_dst"
 msgstr "  Warnung: $name beinhaltet nicht Version $sha1_dst"
 
-#: git-submodule.sh:813
+#: git-submodule.sh:818
 #, sh-format
 msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
 "  Warnung: $name beinhaltet nicht die Versionen $sha1_src und $sha1_dst"
 
-#: git-submodule.sh:838
+#: git-submodule.sh:843
 msgid "blob"
 msgstr "Blob"
 
-#: git-submodule.sh:839
-msgid "submodule"
-msgstr "Unterprojekt"
-
-#: git-submodule.sh:876
+#: git-submodule.sh:881
 msgid "# Submodules changed but not updated:"
 msgstr "# Unterprojekte geändert, aber nicht aktualisiert:"
 
-#: git-submodule.sh:878
+#: git-submodule.sh:883
 msgid "# Submodule changes to be committed:"
 msgstr "# Änderungen in Unterprojekt zum Eintragen:"
 
-#: git-submodule.sh:1022
+#: git-submodule.sh:1027
 #, sh-format
 msgid "Synchronizing submodule url for '$name'"
 msgstr "Synchronisiere Unterprojekt-URL für '$name'"
 
+#~ msgid "-d option is no longer supported.  Do not use."
+#~ msgstr "-d Option wird nicht länger unterstützt. Nicht benutzen."
+
+#~ msgid "%s: has been deleted/renamed"
+#~ msgstr "%s wurde gelöscht/umbenannt"
+
+#~ msgid "'%s': not a documentation directory."
+#~ msgstr "'%s' ist kein Dokumentationsverzeichnis"
+
 #~ msgid "--"
 #~ msgstr "--"
 
index 3d9ae759ea3a512a5a638adfc70bda5139b25209..5c586d600751ca2384f8833c5bc92f72586dc134 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-07-03 10:23+0800\n"
+"POT-Creation-Date: 2012-08-06 23:47+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"
@@ -45,7 +45,7 @@ msgstr ""
 msgid "unrecognized header: %s%s (%d)"
 msgstr ""
 
-#: bundle.c:89 builtin/commit.c:696
+#: bundle.c:89 builtin/commit.c:699
 #, c-format
 msgid "could not open '%s'"
 msgstr ""
@@ -55,7 +55,7 @@ msgid "Repository lacks these prerequisite commits:"
 msgstr ""
 
 #: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
-#: builtin/log.c:721 builtin/log.c:1310 builtin/log.c:1529 builtin/merge.c:347
+#: builtin/log.c:726 builtin/log.c:1316 builtin/log.c:1535 builtin/merge.c:347
 #: builtin/shortlog.c:181
 msgid "revision walk setup failed"
 msgstr ""
@@ -82,7 +82,7 @@ msgstr[1] ""
 msgid "rev-list died"
 msgstr ""
 
-#: bundle.c:300 builtin/log.c:1206 builtin/shortlog.c:284
+#: bundle.c:300 builtin/log.c:1212 builtin/shortlog.c:284
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr ""
@@ -226,7 +226,7 @@ msgid ""
 msgstr ""
 
 #: diff.c:1400
-msgid " 0 files changed\n"
+msgid " 0 files changed"
 msgstr ""
 
 #: diff.c:1404
@@ -250,7 +250,7 @@ msgid_plural ", %d deletions(-)"
 msgstr[0] ""
 msgstr[1] ""
 
-#: diff.c:3478
+#: diff.c:3461
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -284,44 +284,44 @@ msgstr ""
 msgid "'%s': short read %s"
 msgstr ""
 
-#: help.c:208
+#: help.c:212
 #, c-format
 msgid "available git commands in '%s'"
 msgstr ""
 
-#: help.c:215
+#: help.c:219
 msgid "git commands available from elsewhere on your $PATH"
 msgstr ""
 
-#: help.c:271
+#: help.c:275
 #, 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 ""
 
-#: help.c:328
+#: help.c:332
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr ""
 
-#: help.c:350
+#: help.c:354
 #, c-format
 msgid ""
 "WARNING: You called a Git command named '%s', which does not exist.\n"
 "Continuing under the assumption that you meant '%s'"
 msgstr ""
 
-#: help.c:355
+#: help.c:359
 #, c-format
 msgid "in %0.1f seconds automatically..."
 msgstr ""
 
-#: help.c:362
+#: help.c:366
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr ""
 
-#: help.c:366
+#: help.c:370
 msgid ""
 "\n"
 "Did you mean this?"
@@ -331,35 +331,289 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: parse-options.c:493
+#: merge-recursive.c:190
+#, c-format
+msgid "(bad commit)\n"
+msgstr ""
+
+#: merge-recursive.c:206
+#, c-format
+msgid "addinfo_cache failed for path '%s'"
+msgstr ""
+
+#: merge-recursive.c:268
+msgid "error building trees"
+msgstr ""
+
+#: merge-recursive.c:497
+msgid "diff setup failed"
+msgstr ""
+
+#: merge-recursive.c:627
+msgid "merge-recursive: disk full?"
+msgstr ""
+
+#: merge-recursive.c:690
+#, c-format
+msgid "failed to create path '%s'%s"
+msgstr ""
+
+#: merge-recursive.c:701
+#, c-format
+msgid "Removing %s to make room for subdirectory\n"
+msgstr ""
+
+#. something else exists
+#. .. but not some other error (who really cares what?)
+#: merge-recursive.c:715 merge-recursive.c:736
+msgid ": perhaps a D/F conflict?"
+msgstr ""
+
+#: merge-recursive.c:726
+#, c-format
+msgid "refusing to lose untracked file at '%s'"
+msgstr ""
+
+#: merge-recursive.c:766
+#, c-format
+msgid "cannot read object %s '%s'"
+msgstr ""
+
+#: merge-recursive.c:768
+#, c-format
+msgid "blob expected for %s '%s'"
+msgstr ""
+
+#: merge-recursive.c:791 builtin/clone.c:302
+#, c-format
+msgid "failed to open '%s'"
+msgstr ""
+
+#: merge-recursive.c:799
+#, c-format
+msgid "failed to symlink '%s'"
+msgstr ""
+
+#: merge-recursive.c:802
+#, c-format
+msgid "do not know what to do with %06o %s '%s'"
+msgstr ""
+
+#: merge-recursive.c:939
+msgid "Failed to execute internal merge"
+msgstr ""
+
+#: merge-recursive.c:943
+#, c-format
+msgid "Unable to add %s to database"
+msgstr ""
+
+#: merge-recursive.c:959
+msgid "unsupported object type in the tree"
+msgstr ""
+
+#: merge-recursive.c:1038 merge-recursive.c:1052
+#, c-format
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree."
+msgstr ""
+
+#: merge-recursive.c:1044 merge-recursive.c:1057
+#, c-format
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree at %s."
+msgstr ""
+
+#: merge-recursive.c:1098
+msgid "rename"
+msgstr ""
+
+#: merge-recursive.c:1098
+msgid "renamed"
+msgstr ""
+
+#: merge-recursive.c:1154
+#, c-format
+msgid "%s is a directory in %s adding as %s instead"
+msgstr ""
+
+#: merge-recursive.c:1176
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
+"\"->\"%s\" in \"%s\"%s"
+msgstr ""
+
+#: merge-recursive.c:1181
+msgid " (left unresolved)"
+msgstr ""
+
+#: merge-recursive.c:1235
+#, c-format
+msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
+msgstr ""
+
+#: merge-recursive.c:1265
+#, c-format
+msgid "Renaming %s to %s and %s to %s instead"
+msgstr ""
+
+#: merge-recursive.c:1464
+#, c-format
+msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
+msgstr ""
+
+#: merge-recursive.c:1474
+#, c-format
+msgid "Adding merged %s"
+msgstr ""
+
+#: merge-recursive.c:1479 merge-recursive.c:1677
+#, c-format
+msgid "Adding as %s instead"
+msgstr ""
+
+#: merge-recursive.c:1530
+#, c-format
+msgid "cannot read object %s"
+msgstr ""
+
+#: merge-recursive.c:1533
+#, c-format
+msgid "object %s is not a blob"
+msgstr ""
+
+#: merge-recursive.c:1581
+msgid "modify"
+msgstr ""
+
+#: merge-recursive.c:1581
+msgid "modified"
+msgstr ""
+
+#: merge-recursive.c:1591
+msgid "content"
+msgstr ""
+
+#: merge-recursive.c:1598
+msgid "add/add"
+msgstr ""
+
+#: merge-recursive.c:1632
+#, c-format
+msgid "Skipped %s (merged same as existing)"
+msgstr ""
+
+#: merge-recursive.c:1646
+#, c-format
+msgid "Auto-merging %s"
+msgstr ""
+
+#: merge-recursive.c:1650 git-submodule.sh:844
+msgid "submodule"
+msgstr ""
+
+#: merge-recursive.c:1651
+#, c-format
+msgid "CONFLICT (%s): Merge conflict in %s"
+msgstr ""
+
+#: merge-recursive.c:1741
+#, c-format
+msgid "Removing %s"
+msgstr ""
+
+#: merge-recursive.c:1766
+msgid "file/directory"
+msgstr ""
+
+#: merge-recursive.c:1772
+msgid "directory/file"
+msgstr ""
+
+#: merge-recursive.c:1777
+#, c-format
+msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
+msgstr ""
+
+#: merge-recursive.c:1787
+#, c-format
+msgid "Adding %s"
+msgstr ""
+
+#: merge-recursive.c:1804
+msgid "Fatal merge failure, shouldn't happen."
+msgstr ""
+
+#: merge-recursive.c:1823
+msgid "Already up-to-date!"
+msgstr ""
+
+#: merge-recursive.c:1832
+#, c-format
+msgid "merging of trees %s and %s failed"
+msgstr ""
+
+#: merge-recursive.c:1862
+#, c-format
+msgid "Unprocessed path??? %s"
+msgstr ""
+
+#: merge-recursive.c:1907
+msgid "Merging:"
+msgstr ""
+
+#: merge-recursive.c:1920
+#, c-format
+msgid "found %u common ancestor:"
+msgid_plural "found %u common ancestors:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: merge-recursive.c:1957
+msgid "merge returned no commit"
+msgstr ""
+
+#: merge-recursive.c:2014
+#, c-format
+msgid "Could not parse object '%s'"
+msgstr ""
+
+#: merge-recursive.c:2026 builtin/merge.c:697
+msgid "Unable to write index."
+msgstr ""
+
+#: parse-options.c:494
 msgid "..."
 msgstr ""
 
-#: parse-options.c:511
+#: parse-options.c:512
 #, c-format
 msgid "usage: %s"
 msgstr ""
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:515
+#: parse-options.c:516
 #, c-format
 msgid "   or: %s"
 msgstr ""
 
-#: parse-options.c:518
+#: parse-options.c:519
 #, c-format
 msgid "    %s"
 msgstr ""
 
-#: remote.c:1629
+#: remote.c:1632
 #, 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:1635
+#: remote.c:1638
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -367,7 +621,7 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: remote.c:1643
+#: remote.c:1646
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -582,7 +836,7 @@ msgstr ""
 msgid "cannot abort from a branch yet to be born"
 msgstr ""
 
-#: sequencer.c:805 builtin/apply.c:3697
+#: sequencer.c:805 builtin/apply.c:3988
 #, c-format
 msgid "cannot open %s: %s"
 msgstr ""
@@ -614,21 +868,21 @@ msgstr ""
 msgid "Can't cherry-pick into empty head"
 msgstr ""
 
-#: sha1_name.c:864
+#: sha1_name.c:1044
 msgid "HEAD does not point to a branch"
 msgstr ""
 
-#: sha1_name.c:867
+#: sha1_name.c:1047
 #, c-format
 msgid "No such branch: '%s'"
 msgstr ""
 
-#: sha1_name.c:869
+#: sha1_name.c:1049
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr ""
 
-#: sha1_name.c:872
+#: sha1_name.c:1052
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr ""
@@ -642,333 +896,333 @@ msgstr ""
 msgid "no such user"
 msgstr ""
 
-#: wt-status.c:141
+#: wt-status.c:140
 msgid "Unmerged paths:"
 msgstr ""
 
-#: wt-status.c:168 wt-status.c:195
+#: wt-status.c:167 wt-status.c:194
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr ""
 
-#: wt-status.c:170 wt-status.c:197
+#: wt-status.c:169 wt-status.c:196
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr ""
 
-#: wt-status.c:174
+#: wt-status.c:173
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr ""
 
-#: wt-status.c:176 wt-status.c:180
+#: wt-status.c:175 wt-status.c:179
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 
-#: wt-status.c:178
+#: wt-status.c:177
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr ""
 
-#: wt-status.c:189
+#: wt-status.c:188
 msgid "Changes to be committed:"
 msgstr ""
 
-#: wt-status.c:207
+#: wt-status.c:206
 msgid "Changes not staged for commit:"
 msgstr ""
 
-#: wt-status.c:211
+#: wt-status.c:210
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 
-#: wt-status.c:213
+#: wt-status.c:212
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 
-#: wt-status.c:214
+#: wt-status.c:213
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 
-#: wt-status.c:216
+#: wt-status.c:215
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 
-#: wt-status.c:225
+#: wt-status.c:224
 #, c-format
 msgid "%s files:"
 msgstr ""
 
-#: wt-status.c:228
+#: wt-status.c:227
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 
-#: wt-status.c:245
+#: wt-status.c:244
 msgid "bug"
 msgstr ""
 
-#: wt-status.c:250
+#: wt-status.c:249
 msgid "both deleted:"
 msgstr ""
 
-#: wt-status.c:251
+#: wt-status.c:250
 msgid "added by us:"
 msgstr ""
 
-#: wt-status.c:252
+#: wt-status.c:251
 msgid "deleted by them:"
 msgstr ""
 
-#: wt-status.c:253
+#: wt-status.c:252
 msgid "added by them:"
 msgstr ""
 
-#: wt-status.c:254
+#: wt-status.c:253
 msgid "deleted by us:"
 msgstr ""
 
-#: wt-status.c:255
+#: wt-status.c:254
 msgid "both added:"
 msgstr ""
 
-#: wt-status.c:256
+#: wt-status.c:255
 msgid "both modified:"
 msgstr ""
 
-#: wt-status.c:286
+#: wt-status.c:285
 msgid "new commits, "
 msgstr ""
 
-#: wt-status.c:288
+#: wt-status.c:287
 msgid "modified content, "
 msgstr ""
 
-#: wt-status.c:290
+#: wt-status.c:289
 msgid "untracked content, "
 msgstr ""
 
-#: wt-status.c:304
+#: wt-status.c:303
 #, c-format
 msgid "new file:   %s"
 msgstr ""
 
-#: wt-status.c:307
+#: wt-status.c:306
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr ""
 
-#: wt-status.c:310
+#: wt-status.c:309
 #, c-format
 msgid "deleted:    %s"
 msgstr ""
 
-#: wt-status.c:313
+#: wt-status.c:312
 #, c-format
 msgid "modified:   %s"
 msgstr ""
 
-#: wt-status.c:316
+#: wt-status.c:315
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr ""
 
-#: wt-status.c:319
+#: wt-status.c:318
 #, c-format
 msgid "typechange: %s"
 msgstr ""
 
-#: wt-status.c:322
+#: wt-status.c:321
 #, c-format
 msgid "unknown:    %s"
 msgstr ""
 
-#: wt-status.c:325
+#: wt-status.c:324
 #, c-format
 msgid "unmerged:   %s"
 msgstr ""
 
-#: wt-status.c:328
+#: wt-status.c:327
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr ""
 
-#: wt-status.c:786
+#: wt-status.c:785
 msgid "You have unmerged paths."
 msgstr ""
 
-#: wt-status.c:789 wt-status.c:913
+#: wt-status.c:788 wt-status.c:912
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr ""
 
-#: wt-status.c:792
+#: wt-status.c:791
 msgid "All conflicts fixed but you are still merging."
 msgstr ""
 
-#: wt-status.c:795
+#: wt-status.c:794
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr ""
 
-#: wt-status.c:805
+#: wt-status.c:804
 msgid "You are in the middle of an am session."
 msgstr ""
 
-#: wt-status.c:808
+#: wt-status.c:807
 msgid "The current patch is empty."
 msgstr ""
 
-#: wt-status.c:812
+#: wt-status.c:811
 msgid "  (fix conflicts and then run \"git am --resolved\")"
 msgstr ""
 
-#: wt-status.c:814
+#: wt-status.c:813
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr ""
 
-#: wt-status.c:816
+#: wt-status.c:815
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr ""
 
-#: wt-status.c:874 wt-status.c:884
+#: wt-status.c:873 wt-status.c:883
 msgid "You are currently rebasing."
 msgstr ""
 
-#: wt-status.c:877
+#: wt-status.c:876
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:879
+#: wt-status.c:878
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr ""
 
-#: wt-status.c:881
+#: wt-status.c:880
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr ""
 
-#: wt-status.c:887
+#: wt-status.c:886
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:889
+#: wt-status.c:888
 msgid "You are currently splitting a commit during a rebase."
 msgstr ""
 
-#: wt-status.c:892
+#: wt-status.c:891
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:894
+#: wt-status.c:893
 msgid "You are currently editing a commit during a rebase."
 msgstr ""
 
-#: wt-status.c:897
+#: wt-status.c:896
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
 
-#: wt-status.c:899
+#: wt-status.c:898
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
 
-#: wt-status.c:909
+#: wt-status.c:908
 msgid "You are currently cherry-picking."
 msgstr ""
 
-#: wt-status.c:916
+#: wt-status.c:915
 msgid "  (all conflicts fixed: run \"git commit\")"
 msgstr ""
 
-#: wt-status.c:925
+#: wt-status.c:924
 msgid "You are currently bisecting."
 msgstr ""
 
-#: wt-status.c:928
+#: wt-status.c:927
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr ""
 
-#: wt-status.c:979
+#: wt-status.c:978
 msgid "On branch "
 msgstr ""
 
-#: wt-status.c:986
+#: wt-status.c:985
 msgid "Not currently on any branch."
 msgstr ""
 
-#: wt-status.c:998
+#: wt-status.c:997
 msgid "Initial commit"
 msgstr ""
 
-#: wt-status.c:1012
+#: wt-status.c:1011
 msgid "Untracked"
 msgstr ""
 
-#: wt-status.c:1014
+#: wt-status.c:1013
 msgid "Ignored"
 msgstr ""
 
-#: wt-status.c:1016
+#: wt-status.c:1015
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr ""
 
-#: wt-status.c:1018
+#: wt-status.c:1017
 msgid " (use -u option to show untracked files)"
 msgstr ""
 
-#: wt-status.c:1024
+#: wt-status.c:1023
 msgid "No changes"
 msgstr ""
 
-#: wt-status.c:1028
+#: wt-status.c:1027
 #, c-format
 msgid "no changes added to commit%s\n"
 msgstr ""
 
-#: wt-status.c:1030
+#: wt-status.c:1029
 msgid " (use \"git add\" and/or \"git commit -a\")"
 msgstr ""
 
-#: wt-status.c:1032
+#: wt-status.c:1031
 #, c-format
 msgid "nothing added to commit but untracked files present%s\n"
 msgstr ""
 
-#: wt-status.c:1034
+#: wt-status.c:1033
 msgid " (use \"git add\" to track)"
 msgstr ""
 
-#: wt-status.c:1036 wt-status.c:1039 wt-status.c:1042
+#: wt-status.c:1035 wt-status.c:1038 wt-status.c:1041
 #, c-format
 msgid "nothing to commit%s\n"
 msgstr ""
 
-#: wt-status.c:1037
+#: wt-status.c:1036
 msgid " (create/copy files and use \"git add\" to track)"
 msgstr ""
 
-#: wt-status.c:1040
+#: wt-status.c:1039
 msgid " (use -u to show untracked files)"
 msgstr ""
 
-#: wt-status.c:1043
+#: wt-status.c:1042
 msgid " (working directory clean)"
 msgstr ""
 
-#: wt-status.c:1151
+#: wt-status.c:1150
 msgid "HEAD (no branch)"
 msgstr ""
 
-#: wt-status.c:1157
+#: wt-status.c:1156
 msgid "Initial commit on "
 msgstr ""
 
-#: wt-status.c:1172
+#: wt-status.c:1171
 msgid "behind "
 msgstr ""
 
-#: wt-status.c:1175 wt-status.c:1178
+#: wt-status.c:1174 wt-status.c:1177
 msgid "ahead "
 msgstr ""
 
-#: wt-status.c:1180
+#: wt-status.c:1179
 msgid ", behind "
 msgstr ""
 
@@ -977,7 +1231,7 @@ msgstr ""
 msgid "unexpected diff status %c"
 msgstr ""
 
-#: builtin/add.c:67 builtin/commit.c:226
+#: builtin/add.c:67 builtin/commit.c:229
 msgid "updating files failed"
 msgstr ""
 
@@ -1067,75 +1321,75 @@ msgstr ""
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr ""
 
-#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:286 builtin/mv.c:82
+#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:289 builtin/mv.c:82
 #: builtin/rm.c:162
 msgid "index file corrupt"
 msgstr ""
 
-#: builtin/add.c:480 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4433 builtin/mv.c:229 builtin/rm.c:260
 msgid "Unable to write new index file"
 msgstr ""
 
-#: builtin/apply.c:53
+#: builtin/apply.c:57
 msgid "git apply [options] [<patch>...]"
 msgstr ""
 
-#: builtin/apply.c:106
+#: builtin/apply.c:110
 #, c-format
 msgid "unrecognized whitespace option '%s'"
 msgstr ""
 
-#: builtin/apply.c:121
+#: builtin/apply.c:125
 #, c-format
 msgid "unrecognized whitespace ignore option '%s'"
 msgstr ""
 
-#: builtin/apply.c:815
+#: builtin/apply.c:824
 #, c-format
 msgid "Cannot prepare timestamp regexp %s"
 msgstr ""
 
-#: builtin/apply.c:824
+#: builtin/apply.c:833
 #, c-format
 msgid "regexec returned %d for input: %s"
 msgstr ""
 
-#: builtin/apply.c:905
+#: builtin/apply.c:914
 #, c-format
 msgid "unable to find filename in patch at line %d"
 msgstr ""
 
-#: builtin/apply.c:937
+#: builtin/apply.c:946
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
 msgstr ""
 
-#: builtin/apply.c:941
+#: builtin/apply.c:950
 #, c-format
 msgid "git apply: bad git-diff - inconsistent new filename on line %d"
 msgstr ""
 
-#: builtin/apply.c:942
+#: builtin/apply.c:951
 #, c-format
 msgid "git apply: bad git-diff - inconsistent old filename on line %d"
 msgstr ""
 
-#: builtin/apply.c:949
+#: builtin/apply.c:958
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null on line %d"
 msgstr ""
 
-#: builtin/apply.c:1394
+#: builtin/apply.c:1403
 #, c-format
 msgid "recount: unexpected line: %.*s"
 msgstr ""
 
-#: builtin/apply.c:1451
+#: builtin/apply.c:1460
 #, c-format
 msgid "patch fragment without header at line %d: %.*s"
 msgstr ""
 
-#: builtin/apply.c:1468
+#: builtin/apply.c:1477
 #, c-format
 msgid ""
 "git diff header lacks filename information when removing %d leading pathname "
@@ -1146,395 +1400,403 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/apply.c:1628
+#: builtin/apply.c:1637
 msgid "new file depends on old contents"
 msgstr ""
 
-#: builtin/apply.c:1630
+#: builtin/apply.c:1639
 msgid "deleted file still has contents"
 msgstr ""
 
-#: builtin/apply.c:1656
+#: builtin/apply.c:1665
 #, c-format
 msgid "corrupt patch at line %d"
 msgstr ""
 
-#: builtin/apply.c:1692
+#: builtin/apply.c:1701
 #, c-format
 msgid "new file %s depends on old contents"
 msgstr ""
 
-#: builtin/apply.c:1694
+#: builtin/apply.c:1703
 #, c-format
 msgid "deleted file %s still has contents"
 msgstr ""
 
-#: builtin/apply.c:1697
+#: builtin/apply.c:1706
 #, c-format
 msgid "** warning: file %s becomes empty but is not deleted"
 msgstr ""
 
-#: builtin/apply.c:1843
+#: builtin/apply.c:1852
 #, c-format
 msgid "corrupt binary patch at line %d: %.*s"
 msgstr ""
 
 #. there has to be one hunk (forward hunk)
-#: builtin/apply.c:1872
+#: builtin/apply.c:1881
 #, c-format
 msgid "unrecognized binary patch at line %d"
 msgstr ""
 
-#: builtin/apply.c:1958
+#: builtin/apply.c:1967
 #, c-format
 msgid "patch with only garbage at line %d"
 msgstr ""
 
-#: builtin/apply.c:2048
+#: builtin/apply.c:2057
 #, c-format
 msgid "unable to read symlink %s"
 msgstr ""
 
-#: builtin/apply.c:2052
+#: builtin/apply.c:2061
 #, c-format
 msgid "unable to open or read %s"
 msgstr ""
 
-#: builtin/apply.c:2123
+#: builtin/apply.c:2132
 msgid "oops"
 msgstr ""
 
-#: builtin/apply.c:2645
+#: builtin/apply.c:2654
 #, c-format
 msgid "invalid start of line: '%c'"
 msgstr ""
 
-#: builtin/apply.c:2763
+#: builtin/apply.c:2772
 #, c-format
 msgid "Hunk #%d succeeded at %d (offset %d line)."
 msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/apply.c:2775
+#: builtin/apply.c:2784
 #, c-format
 msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
 msgstr ""
 
-#: builtin/apply.c:2781
+#: builtin/apply.c:2790
 #, c-format
 msgid ""
 "while searching for:\n"
 "%.*s"
 msgstr ""
 
-#: builtin/apply.c:2800
+#: builtin/apply.c:2809
 #, c-format
 msgid "missing binary patch data for '%s'"
 msgstr ""
 
-#: builtin/apply.c:2903
+#: builtin/apply.c:2912
 #, c-format
 msgid "binary patch does not apply to '%s'"
 msgstr ""
 
-#: builtin/apply.c:2909
+#: builtin/apply.c:2918
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
 msgstr ""
 
-#: builtin/apply.c:2930
+#: builtin/apply.c:2939
 #, c-format
 msgid "patch failed: %s:%ld"
 msgstr ""
 
-#: builtin/apply.c:3045
+#: builtin/apply.c:3061
 #, c-format
-msgid "patch %s has been renamed/deleted"
+msgid "cannot checkout %s"
 msgstr ""
 
-#: builtin/apply.c:3052 builtin/apply.c:3069
+#: builtin/apply.c:3106 builtin/apply.c:3115 builtin/apply.c:3159
 #, c-format
 msgid "read of %s failed"
 msgstr ""
 
-#: builtin/apply.c:3084
-msgid "removal patch leaves file contents"
-msgstr ""
-
-#: builtin/apply.c:3105
+#: builtin/apply.c:3139 builtin/apply.c:3361
 #, c-format
-msgid "%s: already exists in working directory"
+msgid "path %s has been renamed/deleted"
 msgstr ""
 
-#: builtin/apply.c:3143
+#: builtin/apply.c:3220 builtin/apply.c:3375
 #, c-format
-msgid "%s: has been deleted/renamed"
+msgid "%s: does not exist in index"
 msgstr ""
 
-#: builtin/apply.c:3148 builtin/apply.c:3179
+#: builtin/apply.c:3224 builtin/apply.c:3367 builtin/apply.c:3389
 #, c-format
 msgid "%s: %s"
 msgstr ""
 
-#: builtin/apply.c:3159
+#: builtin/apply.c:3229 builtin/apply.c:3383
 #, c-format
-msgid "%s: does not exist in index"
+msgid "%s: does not match index"
 msgstr ""
 
-#: builtin/apply.c:3173
-#, c-format
-msgid "%s: does not match index"
+#: builtin/apply.c:3331
+msgid "removal patch leaves file contents"
 msgstr ""
 
-#: builtin/apply.c:3190
+#: builtin/apply.c:3400
 #, c-format
 msgid "%s: wrong type"
 msgstr ""
 
-#: builtin/apply.c:3192
+#: builtin/apply.c:3402
 #, c-format
 msgid "%s has type %o, expected %o"
 msgstr ""
 
-#: builtin/apply.c:3247
+#: builtin/apply.c:3503
 #, c-format
 msgid "%s: already exists in index"
 msgstr ""
 
-#: builtin/apply.c:3267
+#: builtin/apply.c:3506
+#, c-format
+msgid "%s: already exists in working directory"
+msgstr ""
+
+#: builtin/apply.c:3526
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
 msgstr ""
 
-#: builtin/apply.c:3272
+#: builtin/apply.c:3531
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o) of %s"
 msgstr ""
 
-#: builtin/apply.c:3280
+#: builtin/apply.c:3539
 #, c-format
 msgid "%s: patch does not apply"
 msgstr ""
 
-#: builtin/apply.c:3293
+#: builtin/apply.c:3552
 #, c-format
 msgid "Checking patch %s..."
 msgstr ""
 
-#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
+#: builtin/apply.c:3607 builtin/checkout.c:213 builtin/reset.c:158
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr ""
 
-#: builtin/apply.c:3491
+#: builtin/apply.c:3750
 #, c-format
 msgid "unable to remove %s from index"
 msgstr ""
 
-#: builtin/apply.c:3518
+#: builtin/apply.c:3778
 #, c-format
 msgid "corrupt patch for subproject %s"
 msgstr ""
 
-#: builtin/apply.c:3522
+#: builtin/apply.c:3782
 #, c-format
 msgid "unable to stat newly created file '%s'"
 msgstr ""
 
-#: builtin/apply.c:3527
+#: builtin/apply.c:3787
 #, c-format
 msgid "unable to create backing store for newly created file %s"
 msgstr ""
 
-#: builtin/apply.c:3530
+#: builtin/apply.c:3790 builtin/apply.c:3898
 #, c-format
 msgid "unable to add cache entry for %s"
 msgstr ""
 
-#: builtin/apply.c:3563
+#: builtin/apply.c:3823
 #, c-format
 msgid "closing file '%s'"
 msgstr ""
 
-#: builtin/apply.c:3612
+#: builtin/apply.c:3872
 #, c-format
 msgid "unable to write file '%s' mode %o"
 msgstr ""
 
-#: builtin/apply.c:3668
+#: builtin/apply.c:3959
 #, c-format
 msgid "Applied patch %s cleanly."
 msgstr ""
 
-#: builtin/apply.c:3676
+#: builtin/apply.c:3967
 msgid "internal error"
 msgstr ""
 
 #. Say this even without --verbose
-#: builtin/apply.c:3679
+#: builtin/apply.c:3970
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/apply.c:3689
+#: builtin/apply.c:3980
 #, c-format
 msgid "truncating .rej filename to %.*s.rej"
 msgstr ""
 
-#: builtin/apply.c:3710
+#: builtin/apply.c:4001
 #, c-format
 msgid "Hunk #%d applied cleanly."
 msgstr ""
 
-#: builtin/apply.c:3713
+#: builtin/apply.c:4004
 #, c-format
 msgid "Rejected hunk #%d."
 msgstr ""
 
-#: builtin/apply.c:3844
+#: builtin/apply.c:4154
 msgid "unrecognized input"
 msgstr ""
 
-#: builtin/apply.c:3855
+#: builtin/apply.c:4165
 msgid "unable to read index file"
 msgstr ""
 
-#: builtin/apply.c:3970 builtin/apply.c:3973
+#: builtin/apply.c:4284 builtin/apply.c:4287
 msgid "path"
 msgstr ""
 
-#: builtin/apply.c:3971
+#: builtin/apply.c:4285
 msgid "don't apply changes matching the given path"
 msgstr ""
 
-#: builtin/apply.c:3974
+#: builtin/apply.c:4288
 msgid "apply changes matching the given path"
 msgstr ""
 
-#: builtin/apply.c:3976
+#: builtin/apply.c:4290
 msgid "num"
 msgstr ""
 
-#: builtin/apply.c:3977
+#: builtin/apply.c:4291
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr ""
 
-#: builtin/apply.c:3980
+#: builtin/apply.c:4294
 msgid "ignore additions made by the patch"
 msgstr ""
 
-#: builtin/apply.c:3982
+#: builtin/apply.c:4296
 msgid "instead of applying the patch, output diffstat for the input"
 msgstr ""
 
-#: builtin/apply.c:3986
+#: builtin/apply.c:4300
 msgid "shows number of added and deleted lines in decimal notation"
 msgstr ""
 
-#: builtin/apply.c:3988
+#: builtin/apply.c:4302
 msgid "instead of applying the patch, output a summary for the input"
 msgstr ""
 
-#: builtin/apply.c:3990
+#: builtin/apply.c:4304
 msgid "instead of applying the patch, see if the patch is applicable"
 msgstr ""
 
-#: builtin/apply.c:3992
+#: builtin/apply.c:4306
 msgid "make sure the patch is applicable to the current index"
 msgstr ""
 
-#: builtin/apply.c:3994
+#: builtin/apply.c:4308
 msgid "apply a patch without touching the working tree"
 msgstr ""
 
-#: builtin/apply.c:3996
+#: builtin/apply.c:4310
 msgid "also apply the patch (use with --stat/--summary/--check)"
 msgstr ""
 
-#: builtin/apply.c:3998
+#: builtin/apply.c:4312
+msgid "attempt three-way merge if a patch does not apply"
+msgstr ""
+
+#: builtin/apply.c:4314
 msgid "build a temporary index based on embedded index information"
 msgstr ""
 
-#: builtin/apply.c:4000
+#: builtin/apply.c:4316
 msgid "paths are separated with NUL character"
 msgstr ""
 
-#: builtin/apply.c:4003
+#: builtin/apply.c:4319
 msgid "ensure at least <n> lines of context match"
 msgstr ""
 
-#: builtin/apply.c:4004
+#: builtin/apply.c:4320
 msgid "action"
 msgstr ""
 
-#: builtin/apply.c:4005
+#: builtin/apply.c:4321
 msgid "detect new or modified lines that have whitespace errors"
 msgstr ""
 
-#: builtin/apply.c:4008 builtin/apply.c:4011
+#: builtin/apply.c:4324 builtin/apply.c:4327
 msgid "ignore changes in whitespace when finding context"
 msgstr ""
 
-#: builtin/apply.c:4014
+#: builtin/apply.c:4330
 msgid "apply the patch in reverse"
 msgstr ""
 
-#: builtin/apply.c:4016
+#: builtin/apply.c:4332
 msgid "don't expect at least one line of context"
 msgstr ""
 
-#: builtin/apply.c:4018
+#: builtin/apply.c:4334
 msgid "leave the rejected hunks in corresponding *.rej files"
 msgstr ""
 
-#: builtin/apply.c:4020
+#: builtin/apply.c:4336
 msgid "allow overlapping hunks"
 msgstr ""
 
-#: builtin/apply.c:4021
+#: builtin/apply.c:4337
 msgid "be verbose"
 msgstr ""
 
-#: builtin/apply.c:4023
+#: builtin/apply.c:4339
 msgid "tolerate incorrectly detected missing new-line at the end of file"
 msgstr ""
 
-#: builtin/apply.c:4026
+#: builtin/apply.c:4342
 msgid "do not trust the line counts in the hunk headers"
 msgstr ""
 
-#: builtin/apply.c:4028
+#: builtin/apply.c:4344
 msgid "root"
 msgstr ""
 
-#: builtin/apply.c:4029
+#: builtin/apply.c:4345
 msgid "prepend <root> to all filenames"
 msgstr ""
 
-#: builtin/apply.c:4050
+#: builtin/apply.c:4367
+msgid "--3way outside a repository"
+msgstr ""
+
+#: builtin/apply.c:4375
 msgid "--index outside a repository"
 msgstr ""
 
-#: builtin/apply.c:4053
+#: builtin/apply.c:4378
 msgid "--cached outside a repository"
 msgstr ""
 
-#: builtin/apply.c:4069
+#: builtin/apply.c:4394
 #, c-format
 msgid "can't open patch '%s'"
 msgstr ""
 
-#: builtin/apply.c:4083
+#: builtin/apply.c:4408
 #, c-format
 msgid "squelched %d whitespace error"
 msgid_plural "squelched %d whitespace errors"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/apply.c:4089 builtin/apply.c:4099
+#: builtin/apply.c:4414 builtin/apply.c:4424
 #, c-format
 msgid "%d line adds whitespace errors."
 msgid_plural "%d lines add whitespace errors."
@@ -1733,7 +1995,7 @@ msgstr ""
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr ""
 
-#: builtin/branch.c:788 builtin/clone.c:558
+#: builtin/branch.c:788 builtin/clone.c:561
 msgid "HEAD not found below refs/heads!"
 msgstr ""
 
@@ -1758,99 +2020,99 @@ msgstr ""
 msgid "Need a repository to unbundle."
 msgstr ""
 
-#: builtin/checkout.c:113 builtin/checkout.c:146
+#: builtin/checkout.c:114 builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
 msgstr ""
 
-#: builtin/checkout.c:115 builtin/checkout.c:148
+#: builtin/checkout.c:116 builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
 msgstr ""
 
-#: builtin/checkout.c:131
+#: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
 msgstr ""
 
-#: builtin/checkout.c:175
+#: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
 msgstr ""
 
-#: builtin/checkout.c:192
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr ""
 
-#: builtin/checkout.c:209
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr ""
 
-#: builtin/checkout.c:234 builtin/checkout.c:392
+#: builtin/checkout.c:235 builtin/checkout.c:393
 msgid "corrupt index file"
 msgstr ""
 
-#: builtin/checkout.c:264 builtin/checkout.c:271
+#: builtin/checkout.c:265 builtin/checkout.c:272
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr ""
 
-#: builtin/checkout.c:302 builtin/checkout.c:498 builtin/clone.c:583
+#: builtin/checkout.c:303 builtin/checkout.c:499 builtin/clone.c:586
 #: builtin/merge.c:812
 msgid "unable to write new index file"
 msgstr ""
 
-#: builtin/checkout.c:319 builtin/diff.c:302 builtin/merge.c:408
+#: builtin/checkout.c:320 builtin/diff.c:302 builtin/merge.c:408
 msgid "diff_setup_done failed"
 msgstr ""
 
-#: builtin/checkout.c:414
+#: builtin/checkout.c:415
 msgid "you need to resolve your current index first"
 msgstr ""
 
-#: builtin/checkout.c:533
+#: builtin/checkout.c:534
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:566
+#: builtin/checkout.c:567
 msgid "HEAD is now at"
 msgstr ""
 
-#: builtin/checkout.c:573
+#: builtin/checkout.c:574
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:576
+#: builtin/checkout.c:577
 #, c-format
 msgid "Already on '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:580
+#: builtin/checkout.c:581
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:582
+#: builtin/checkout.c:583
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:584
+#: builtin/checkout.c:585
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:640
+#: builtin/checkout.c:641
 #, c-format
 msgid " ... and %d more.\n"
 msgstr ""
 
 #. The singular version
-#: builtin/checkout.c:646
+#: builtin/checkout.c:647
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -1865,7 +2127,7 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/checkout.c:664
+#: builtin/checkout.c:665
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -1875,96 +2137,96 @@ msgid ""
 "\n"
 msgstr ""
 
-#: builtin/checkout.c:694
+#: builtin/checkout.c:695
 msgid "internal error in revision walk"
 msgstr ""
 
-#: builtin/checkout.c:698
+#: builtin/checkout.c:699
 msgid "Previous HEAD position was"
 msgstr ""
 
-#: builtin/checkout.c:724
+#: builtin/checkout.c:725 builtin/checkout.c:920
 msgid "You are on a branch yet to be born"
 msgstr ""
 
 #. case (1)
-#: builtin/checkout.c:855
+#: builtin/checkout.c:856
 #, c-format
 msgid "invalid reference: %s"
 msgstr ""
 
 #. case (1): want a tree
-#: builtin/checkout.c:894
+#: builtin/checkout.c:895
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr ""
 
-#: builtin/checkout.c:974
+#: builtin/checkout.c:977
 msgid "-B cannot be used with -b"
 msgstr ""
 
-#: builtin/checkout.c:983
+#: builtin/checkout.c:986
 msgid "--patch is incompatible with all other options"
 msgstr ""
 
-#: builtin/checkout.c:986
+#: builtin/checkout.c:989
 msgid "--detach cannot be used with -b/-B/--orphan"
 msgstr ""
 
-#: builtin/checkout.c:988
+#: builtin/checkout.c:991
 msgid "--detach cannot be used with -t"
 msgstr ""
 
-#: builtin/checkout.c:994
+#: builtin/checkout.c:997
 msgid "--track needs a branch name"
 msgstr ""
 
-#: builtin/checkout.c:1001
+#: builtin/checkout.c:1004
 msgid "Missing branch name; try -b"
 msgstr ""
 
-#: builtin/checkout.c:1007
+#: builtin/checkout.c:1010
 msgid "--orphan and -b|-B are mutually exclusive"
 msgstr ""
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1012
 msgid "--orphan cannot be used with -t"
 msgstr ""
 
-#: builtin/checkout.c:1019
+#: builtin/checkout.c:1022
 msgid "git checkout: -f and -m are incompatible"
 msgstr ""
 
-#: builtin/checkout.c:1053
+#: builtin/checkout.c:1056
 msgid "invalid path specification"
 msgstr ""
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, 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:1063
+#: builtin/checkout.c:1066
 msgid "git checkout: updating paths is incompatible with switching branches."
 msgstr ""
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1071
 msgid "git checkout: --detach does not take a path argument"
 msgstr ""
 
-#: builtin/checkout.c:1071
+#: builtin/checkout.c:1074
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
 
-#: builtin/checkout.c:1090
+#: builtin/checkout.c:1093
 msgid "Cannot switch branch to a non-commit."
 msgstr ""
 
-#: builtin/checkout.c:1093
+#: builtin/checkout.c:1096
 msgid "--ours/--theirs is incompatible with switching branches."
 msgstr ""
 
@@ -2013,11 +2275,6 @@ msgstr ""
 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'"
@@ -2058,78 +2315,78 @@ msgstr ""
 msgid "done.\n"
 msgstr ""
 
-#: builtin/clone.c:440
+#: builtin/clone.c:443
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr ""
 
-#: builtin/clone.c:549
+#: builtin/clone.c:552
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 
-#: builtin/clone.c:639
+#: builtin/clone.c:642
 msgid "Too many arguments."
 msgstr ""
 
-#: builtin/clone.c:643
+#: builtin/clone.c:646
 msgid "You must specify a repository to clone."
 msgstr ""
 
-#: builtin/clone.c:654
+#: builtin/clone.c:657
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr ""
 
-#: builtin/clone.c:668
+#: builtin/clone.c:671
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr ""
 
-#: builtin/clone.c:673
+#: builtin/clone.c:676
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr ""
 
-#: builtin/clone.c:683
+#: builtin/clone.c:686
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr ""
 
-#: builtin/clone.c:693
+#: builtin/clone.c:696
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr ""
 
-#: builtin/clone.c:706 builtin/clone.c:720
+#: builtin/clone.c:709 builtin/clone.c:723
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr ""
 
-#: builtin/clone.c:709
+#: builtin/clone.c:712
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr ""
 
-#: builtin/clone.c:728
+#: builtin/clone.c:731
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr ""
 
-#: builtin/clone.c:730
+#: builtin/clone.c:733
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr ""
 
-#: builtin/clone.c:786
+#: builtin/clone.c:789
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr ""
 
-#: builtin/clone.c:835
+#: builtin/clone.c:838
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr ""
 
-#: builtin/clone.c:842
+#: builtin/clone.c:845
 msgid "You appear to have cloned an empty repository."
 msgstr ""
 
@@ -2168,93 +2425,93 @@ msgid ""
 "Otherwise, please use 'git reset'\n"
 msgstr ""
 
-#: builtin/commit.c:253
+#: builtin/commit.c:256
 msgid "failed to unpack HEAD tree object"
 msgstr ""
 
-#: builtin/commit.c:295
+#: builtin/commit.c:298
 msgid "unable to create temporary index"
 msgstr ""
 
-#: builtin/commit.c:301
+#: builtin/commit.c:304
 msgid "interactive add failed"
 msgstr ""
 
-#: builtin/commit.c:334 builtin/commit.c:355 builtin/commit.c:405
+#: builtin/commit.c:337 builtin/commit.c:358 builtin/commit.c:408
 msgid "unable to write new_index file"
 msgstr ""
 
-#: builtin/commit.c:386
+#: builtin/commit.c:389
 msgid "cannot do a partial commit during a merge."
 msgstr ""
 
-#: builtin/commit.c:388
+#: builtin/commit.c:391
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr ""
 
-#: builtin/commit.c:398
+#: builtin/commit.c:401
 msgid "cannot read the index"
 msgstr ""
 
-#: builtin/commit.c:418
+#: builtin/commit.c:421
 msgid "unable to write temporary index file"
 msgstr ""
 
-#: builtin/commit.c:493 builtin/commit.c:499
+#: builtin/commit.c:496 builtin/commit.c:502
 #, c-format
 msgid "invalid commit: %s"
 msgstr ""
 
-#: builtin/commit.c:522
+#: builtin/commit.c:525
 msgid "malformed --author parameter"
 msgstr ""
 
-#: builtin/commit.c:582
+#: builtin/commit.c:585
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr ""
 
-#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
+#: builtin/commit.c:623 builtin/commit.c:656 builtin/commit.c:970
 #, c-format
 msgid "could not lookup commit %s"
 msgstr ""
 
-#: builtin/commit.c:632 builtin/shortlog.c:296
+#: builtin/commit.c:635 builtin/shortlog.c:296
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr ""
 
-#: builtin/commit.c:634
+#: builtin/commit.c:637
 msgid "could not read log from standard input"
 msgstr ""
 
-#: builtin/commit.c:638
+#: builtin/commit.c:641
 #, c-format
 msgid "could not read log file '%s'"
 msgstr ""
 
-#: builtin/commit.c:644
+#: builtin/commit.c:647
 msgid "commit has empty message"
 msgstr ""
 
-#: builtin/commit.c:660
+#: builtin/commit.c:663
 msgid "could not read MERGE_MSG"
 msgstr ""
 
-#: builtin/commit.c:664
+#: builtin/commit.c:667
 msgid "could not read SQUASH_MSG"
 msgstr ""
 
-#: builtin/commit.c:668
+#: builtin/commit.c:671
 #, c-format
 msgid "could not read '%s'"
 msgstr ""
 
-#: builtin/commit.c:720
+#: builtin/commit.c:723
 msgid "could not write commit template"
 msgstr ""
 
-#: builtin/commit.c:731
+#: builtin/commit.c:734
 #, c-format
 msgid ""
 "\n"
@@ -2264,7 +2521,7 @@ msgid ""
 "and try again.\n"
 msgstr ""
 
-#: builtin/commit.c:736
+#: builtin/commit.c:739
 #, c-format
 msgid ""
 "\n"
@@ -2274,171 +2531,171 @@ msgid ""
 "and try again.\n"
 msgstr ""
 
-#: builtin/commit.c:748
+#: builtin/commit.c:751
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 
-#: builtin/commit.c:753
+#: builtin/commit.c:756
 msgid ""
 "Please enter the commit message for your changes. 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:766
+#: builtin/commit.c:769
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr ""
 
-#: builtin/commit.c:773
+#: builtin/commit.c:776
 #, c-format
 msgid "%sCommitter: %s"
 msgstr ""
 
-#: builtin/commit.c:793
+#: builtin/commit.c:796
 msgid "Cannot read index"
 msgstr ""
 
-#: builtin/commit.c:830
+#: builtin/commit.c:833
 msgid "Error building trees"
 msgstr ""
 
-#: builtin/commit.c:845 builtin/tag.c:361
+#: builtin/commit.c:848 builtin/tag.c:361
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr ""
 
-#: builtin/commit.c:942
+#: builtin/commit.c:945
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr ""
 
-#: builtin/commit.c:957 builtin/commit.c:1157
+#: builtin/commit.c:960 builtin/commit.c:1160
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr ""
 
-#: builtin/commit.c:997
+#: builtin/commit.c:1000
 msgid "Using both --reset-author and --author does not make sense"
 msgstr ""
 
-#: builtin/commit.c:1008
+#: builtin/commit.c:1011
 msgid "You have nothing to amend."
 msgstr ""
 
-#: builtin/commit.c:1011
+#: builtin/commit.c:1014
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr ""
 
-#: builtin/commit.c:1013
+#: builtin/commit.c:1016
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr ""
 
-#: builtin/commit.c:1016
+#: builtin/commit.c:1019
 msgid "Options --squash and --fixup cannot be used together"
 msgstr ""
 
-#: builtin/commit.c:1026
+#: builtin/commit.c:1029
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr ""
 
-#: builtin/commit.c:1028
+#: builtin/commit.c:1031
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
 msgstr ""
 
-#: builtin/commit.c:1036
+#: builtin/commit.c:1039
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr ""
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1056
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 
-#: builtin/commit.c:1055
+#: builtin/commit.c:1058
 msgid "No paths with --include/--only does not make sense."
 msgstr ""
 
-#: builtin/commit.c:1057
+#: builtin/commit.c:1060
 msgid "Clever... amending the last one with dirty index."
 msgstr ""
 
-#: builtin/commit.c:1059
+#: builtin/commit.c:1062
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
 msgstr ""
 
-#: builtin/commit.c:1069 builtin/tag.c:577
+#: builtin/commit.c:1072 builtin/tag.c:577
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr ""
 
-#: builtin/commit.c:1074
+#: builtin/commit.c:1077
 msgid "Paths with -a does not make sense."
 msgstr ""
 
-#: builtin/commit.c:1257
+#: builtin/commit.c:1260
 msgid "couldn't look up newly created commit"
 msgstr ""
 
-#: builtin/commit.c:1259
+#: builtin/commit.c:1262
 msgid "could not parse newly created commit"
 msgstr ""
 
-#: builtin/commit.c:1300
+#: builtin/commit.c:1303
 msgid "detached HEAD"
 msgstr ""
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1305
 msgid " (root-commit)"
 msgstr ""
 
-#: builtin/commit.c:1446
+#: builtin/commit.c:1449
 msgid "could not parse HEAD commit"
 msgstr ""
 
-#: builtin/commit.c:1484 builtin/merge.c:509
+#: builtin/commit.c:1487 builtin/merge.c:509
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr ""
 
-#: builtin/commit.c:1491
+#: builtin/commit.c:1494
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr ""
 
-#: builtin/commit.c:1498
+#: builtin/commit.c:1501
 msgid "could not read MERGE_MODE"
 msgstr ""
 
-#: builtin/commit.c:1517
+#: builtin/commit.c:1520
 #, c-format
 msgid "could not read commit message: %s"
 msgstr ""
 
-#: builtin/commit.c:1531
+#: builtin/commit.c:1534
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr ""
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1539
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr ""
 
-#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1554 builtin/merge.c:936 builtin/merge.c:961
 msgid "failed to write commit object"
 msgstr ""
 
-#: builtin/commit.c:1572
+#: builtin/commit.c:1575
 msgid "cannot lock HEAD ref"
 msgstr ""
 
-#: builtin/commit.c:1576
+#: builtin/commit.c:1579
 msgid "cannot update HEAD ref"
 msgstr ""
 
-#: builtin/commit.c:1587
+#: builtin/commit.c:1590
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
@@ -2794,71 +3051,66 @@ msgstr ""
 msgid "both --cached and trees are given."
 msgstr ""
 
-#: builtin/help.c:63
+#: builtin/help.c:65
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr ""
 
-#: builtin/help.c:91
+#: builtin/help.c:93
 msgid "Failed to start emacsclient."
 msgstr ""
 
-#: builtin/help.c:104
+#: builtin/help.c:106
 msgid "Failed to parse emacsclient version."
 msgstr ""
 
-#: builtin/help.c:112
+#: builtin/help.c:114
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr ""
 
-#: builtin/help.c:130 builtin/help.c:158 builtin/help.c:167 builtin/help.c:175
+#: builtin/help.c:132 builtin/help.c:160 builtin/help.c:169 builtin/help.c:177
 #, c-format
 msgid "failed to exec '%s': %s"
 msgstr ""
 
-#: builtin/help.c:215
+#: builtin/help.c:217
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
 "Please consider using 'man.<tool>.cmd' instead."
 msgstr ""
 
-#: builtin/help.c:227
+#: builtin/help.c:229
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
 "Please consider using 'man.<tool>.path' instead."
 msgstr ""
 
-#: builtin/help.c:291
+#: builtin/help.c:299
 msgid "The most commonly used git commands are:"
 msgstr ""
 
-#: builtin/help.c:359
+#: builtin/help.c:367
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr ""
 
-#: builtin/help.c:376
+#: builtin/help.c:384
 msgid "no man viewer handled the request"
 msgstr ""
 
-#: builtin/help.c:384
+#: builtin/help.c:392
 msgid "no info viewer handled the request"
 msgstr ""
 
-#: builtin/help.c:395
-#, c-format
-msgid "'%s': not a documentation directory."
-msgstr ""
-
-#: builtin/help.c:436 builtin/help.c:443
+#: builtin/help.c:447 builtin/help.c:454
 #, c-format
 msgid "usage: %s%s"
 msgstr ""
 
-#: builtin/help.c:459
+#: builtin/help.c:470
 #, c-format
 msgid "`git %s' is aliased to `%s'"
 msgstr ""
@@ -2932,176 +3184,176 @@ msgstr ""
 msgid "unknown object type %d"
 msgstr ""
 
-#: builtin/index-pack.c:531
+#: builtin/index-pack.c:530
 msgid "cannot pread pack file"
 msgstr ""
 
-#: builtin/index-pack.c:533
+#: builtin/index-pack.c:532
 #, c-format
 msgid "premature end of pack file, %lu byte missing"
 msgid_plural "premature end of pack file, %lu bytes missing"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:555
+#: builtin/index-pack.c:558
 msgid "serious inflate inconsistency"
 msgstr ""
 
-#: builtin/index-pack.c:646 builtin/index-pack.c:652 builtin/index-pack.c:675
-#: builtin/index-pack.c:709 builtin/index-pack.c:718
+#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678
+#: builtin/index-pack.c:712 builtin/index-pack.c:721
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr ""
 
-#: builtin/index-pack.c:649 builtin/pack-objects.c:170
+#: builtin/index-pack.c:652 builtin/pack-objects.c:170
 #: builtin/pack-objects.c:262
 #, c-format
 msgid "unable to read %s"
 msgstr ""
 
-#: builtin/index-pack.c:715
+#: builtin/index-pack.c:718
 #, c-format
 msgid "cannot read existing object %s"
 msgstr ""
 
-#: builtin/index-pack.c:729
+#: builtin/index-pack.c:732
 #, c-format
 msgid "invalid blob object %s"
 msgstr ""
 
-#: builtin/index-pack.c:744
+#: builtin/index-pack.c:747
 #, c-format
 msgid "invalid %s"
 msgstr ""
 
-#: builtin/index-pack.c:746
+#: builtin/index-pack.c:749
 msgid "Error in object"
 msgstr ""
 
-#: builtin/index-pack.c:748
+#: builtin/index-pack.c:751
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr ""
 
-#: builtin/index-pack.c:818 builtin/index-pack.c:844
+#: builtin/index-pack.c:821 builtin/index-pack.c:847
 msgid "failed to apply delta"
 msgstr ""
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Receiving objects"
 msgstr ""
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Indexing objects"
 msgstr ""
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1012
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr ""
 
-#: builtin/index-pack.c:1014
+#: builtin/index-pack.c:1017
 msgid "cannot fstat packfile"
 msgstr ""
 
-#: builtin/index-pack.c:1017
+#: builtin/index-pack.c:1020
 msgid "pack has junk at the end"
 msgstr ""
 
-#: builtin/index-pack.c:1028
+#: builtin/index-pack.c:1031
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr ""
 
-#: builtin/index-pack.c:1051
+#: builtin/index-pack.c:1054
 msgid "Resolving deltas"
 msgstr ""
 
-#: builtin/index-pack.c:1102
+#: builtin/index-pack.c:1105
 msgid "confusion beyond insanity"
 msgstr ""
 
-#: builtin/index-pack.c:1121
+#: builtin/index-pack.c:1124
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1149
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr ""
 
-#: builtin/index-pack.c:1225
+#: builtin/index-pack.c:1228
 #, c-format
 msgid "local object %s is corrupt"
 msgstr ""
 
-#: builtin/index-pack.c:1249
+#: builtin/index-pack.c:1252
 msgid "error while closing pack file"
 msgstr ""
 
-#: builtin/index-pack.c:1262
+#: builtin/index-pack.c:1265
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1270
+#: builtin/index-pack.c:1273
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1286
 msgid "cannot store pack file"
 msgstr ""
 
-#: builtin/index-pack.c:1294
+#: builtin/index-pack.c:1297
 msgid "cannot store index file"
 msgstr ""
 
-#: builtin/index-pack.c:1395
+#: builtin/index-pack.c:1398
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1400
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1444
+#: builtin/index-pack.c:1447
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1451
+#: builtin/index-pack.c:1454
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1478
+#: builtin/index-pack.c:1481
 msgid "Cannot come back to cwd"
 msgstr ""
 
-#: builtin/index-pack.c:1522 builtin/index-pack.c:1525
-#: builtin/index-pack.c:1537 builtin/index-pack.c:1541
+#: builtin/index-pack.c:1525 builtin/index-pack.c:1528
+#: builtin/index-pack.c:1540 builtin/index-pack.c:1544
 #, c-format
 msgid "bad %s"
 msgstr ""
 
-#: builtin/index-pack.c:1555
+#: builtin/index-pack.c:1558
 msgid "--fix-thin cannot be used without --stdin"
 msgstr ""
 
-#: builtin/index-pack.c:1559 builtin/index-pack.c:1569
+#: builtin/index-pack.c:1562 builtin/index-pack.c:1572
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr ""
 
-#: builtin/index-pack.c:1578
+#: builtin/index-pack.c:1581
 msgid "--verify with no packfile name given"
 msgstr ""
 
@@ -3175,22 +3427,22 @@ msgstr ""
 msgid "insane git directory %s"
 msgstr ""
 
-#: builtin/init-db.c:322 builtin/init-db.c:325
+#: builtin/init-db.c:323 builtin/init-db.c:326
 #, c-format
 msgid "%s already exists"
 msgstr ""
 
-#: builtin/init-db.c:354
+#: builtin/init-db.c:355
 #, c-format
 msgid "unable to handle file type %d"
 msgstr ""
 
-#: builtin/init-db.c:357
+#: builtin/init-db.c:358
 #, c-format
 msgid "unable to move %s to %s"
 msgstr ""
 
-#: builtin/init-db.c:362
+#: builtin/init-db.c:363
 #, c-format
 msgid "Could not create git link %s"
 msgstr ""
@@ -3200,49 +3452,49 @@ msgstr ""
 #. * existing" or "Initialized empty", the second " shared" or
 #. * "", and the last '%s%s' is the verbatim directory name.
 #.
-#: builtin/init-db.c:419
+#: builtin/init-db.c:420
 #, c-format
 msgid "%s%s Git repository in %s%s\n"
 msgstr ""
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Reinitialized existing"
 msgstr ""
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Initialized empty"
 msgstr ""
 
-#: builtin/init-db.c:421
+#: builtin/init-db.c:422
 msgid " shared"
 msgstr ""
 
-#: builtin/init-db.c:440
+#: builtin/init-db.c:441
 msgid "cannot tell cwd"
 msgstr ""
 
-#: builtin/init-db.c:521 builtin/init-db.c:528
+#: builtin/init-db.c:522 builtin/init-db.c:529
 #, c-format
 msgid "cannot mkdir %s"
 msgstr ""
 
-#: builtin/init-db.c:532
+#: builtin/init-db.c:533
 #, c-format
 msgid "cannot chdir to %s"
 msgstr ""
 
-#: builtin/init-db.c:554
+#: builtin/init-db.c:555
 #, c-format
 msgid ""
 "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
 "dir=<directory>)"
 msgstr ""
 
-#: builtin/init-db.c:578
+#: builtin/init-db.c:579
 msgid "Cannot access current working directory"
 msgstr ""
 
-#: builtin/init-db.c:585
+#: builtin/init-db.c:586
 #, c-format
 msgid "Cannot access work tree '%s'"
 msgstr ""
@@ -3252,95 +3504,95 @@ msgstr ""
 msgid "Final output: %d %s\n"
 msgstr ""
 
-#: builtin/log.c:402 builtin/log.c:490
+#: builtin/log.c:403 builtin/log.c:494
 #, c-format
 msgid "Could not read object %s"
 msgstr ""
 
-#: builtin/log.c:514
+#: builtin/log.c:518
 #, c-format
 msgid "Unknown type: %d"
 msgstr ""
 
-#: builtin/log.c:603
+#: builtin/log.c:608
 msgid "format.headers without value"
 msgstr ""
 
-#: builtin/log.c:677
+#: builtin/log.c:682
 msgid "name of output directory is too long"
 msgstr ""
 
-#: builtin/log.c:688
+#: builtin/log.c:693
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr ""
 
-#: builtin/log.c:702
+#: builtin/log.c:707
 msgid "Need exactly one range."
 msgstr ""
 
-#: builtin/log.c:710
+#: builtin/log.c:715
 msgid "Not a range."
 msgstr ""
 
-#: builtin/log.c:787
+#: builtin/log.c:792
 msgid "Cover letter needs email format"
 msgstr ""
 
-#: builtin/log.c:860
+#: builtin/log.c:865
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr ""
 
-#: builtin/log.c:933
+#: builtin/log.c:938
 msgid "Two output directories?"
 msgstr ""
 
-#: builtin/log.c:1154
+#: builtin/log.c:1160
 #, c-format
 msgid "bogus committer info %s"
 msgstr ""
 
-#: builtin/log.c:1199
+#: builtin/log.c:1205
 msgid "-n and -k are mutually exclusive."
 msgstr ""
 
-#: builtin/log.c:1201
+#: builtin/log.c:1207
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr ""
 
-#: builtin/log.c:1209
+#: builtin/log.c:1215
 msgid "--name-only does not make sense"
 msgstr ""
 
-#: builtin/log.c:1211
+#: builtin/log.c:1217
 msgid "--name-status does not make sense"
 msgstr ""
 
-#: builtin/log.c:1213
+#: builtin/log.c:1219
 msgid "--check does not make sense"
 msgstr ""
 
-#: builtin/log.c:1236
+#: builtin/log.c:1242
 msgid "standard output, or directory, which one?"
 msgstr ""
 
-#: builtin/log.c:1238
+#: builtin/log.c:1244
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr ""
 
-#: builtin/log.c:1391
+#: builtin/log.c:1397
 msgid "Failed to create output files"
 msgstr ""
 
-#: builtin/log.c:1495
+#: builtin/log.c:1501
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
 msgstr ""
 
-#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
+#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531
 #, c-format
 msgid "Unknown commit %s"
 msgstr ""
@@ -3421,10 +3673,6 @@ msgstr ""
 msgid "failed to read the cache"
 msgstr ""
 
-#: builtin/merge.c:697
-msgid "Unable to write index."
-msgstr ""
-
 #: builtin/merge.c:710
 msgid "Not handling anything other than two heads merge."
 msgstr ""
@@ -4379,30 +4627,30 @@ msgstr ""
 msgid "Cannot do a %s reset in the middle of a merge."
 msgstr ""
 
-#: builtin/reset.c:297
+#: builtin/reset.c:303
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr ""
 
-#: builtin/reset.c:302
+#: builtin/reset.c:308
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr ""
 
-#: builtin/reset.c:311
+#: builtin/reset.c:317
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr ""
 
-#: builtin/reset.c:313
+#: builtin/reset.c:319
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr ""
 
-#: builtin/reset.c:325
+#: builtin/reset.c:331
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr ""
 
-#: builtin/reset.c:341
+#: builtin/reset.c:347
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr ""
@@ -4720,9 +4968,9 @@ msgstr ""
 #: git-am.sh:105
 #, sh-format
 msgid ""
-"When you have resolved this problem run \"$cmdline --resolved\".\n"
-"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
-"To restore the original branch and stop patching run \"$cmdline --abort\"."
+"When you have resolved this problem, run \"$cmdline --resolved\".\n"
+"If you prefer to skip this patch, run \"$cmdline --skip\" instead.\n"
+"To restore the original branch and stop patching, run \"$cmdline --abort\"."
 msgstr ""
 
 #: git-am.sh:121
@@ -4733,6 +4981,10 @@ msgstr ""
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
 msgstr ""
 
+#: git-am.sh:139
+msgid "Using index info to reconstruct a base tree..."
+msgstr ""
+
 #: git-am.sh:154
 msgid ""
 "Did you hand edit your patch?\n"
@@ -4743,42 +4995,48 @@ msgstr ""
 msgid "Falling back to patching base and 3-way merge..."
 msgstr ""
 
-#: git-am.sh:275
+#: git-am.sh:179
+msgid "Failed to merge in the changes."
+msgstr ""
+
+#: git-am.sh:274
 msgid "Only one StGIT patch series can be applied at once"
 msgstr ""
 
-#: git-am.sh:362
+#: git-am.sh:361
 #, sh-format
 msgid "Patch format $patch_format is not supported."
 msgstr ""
 
-#: git-am.sh:364
+#: git-am.sh:363
 msgid "Patch format detection failed."
 msgstr ""
 
-#: git-am.sh:418
-msgid "-d option is no longer supported.  Do not use."
+#: git-am.sh:389
+msgid ""
+"The -b/--binary option has been a no-op for long time, and\n"
+"it will be removed. Please do not use it anymore."
 msgstr ""
 
-#: git-am.sh:481
+#: git-am.sh:477
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
 msgstr ""
 
-#: git-am.sh:486
+#: git-am.sh:482
 msgid "Please make up your mind. --skip or --abort?"
 msgstr ""
 
-#: git-am.sh:513
+#: git-am.sh:509
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr ""
 
-#: git-am.sh:579
+#: git-am.sh:575
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
 msgstr ""
 
-#: git-am.sh:671
+#: git-am.sh:679
 #, sh-format
 msgid ""
 "Patch is empty.  Was it split wrong?\n"
@@ -4786,53 +5044,53 @@ msgid ""
 "To restore the original branch and stop patching run \"$cmdline --abort\"."
 msgstr ""
 
-#: git-am.sh:708
+#: git-am.sh:706
 msgid "Patch does not have a valid e-mail address."
 msgstr ""
 
-#: git-am.sh:755
+#: git-am.sh:753
 msgid "cannot be interactive without stdin connected to a terminal."
 msgstr ""
 
-#: git-am.sh:759
+#: git-am.sh:757
 msgid "Commit Body is:"
 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:766
+#: git-am.sh:764
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr ""
 
-#: git-am.sh:802
+#: git-am.sh:800
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr ""
 
-#: git-am.sh:823
+#: git-am.sh:821
 msgid ""
 "No changes - did you forget to use 'git add'?\n"
 "If there is nothing left to stage, chances are that something else\n"
 "already introduced the same changes; you might want to skip this patch."
 msgstr ""
 
-#: git-am.sh:831
+#: git-am.sh:829
 msgid ""
 "You still have unmerged paths in your index\n"
 "did you forget to use 'git add'?"
 msgstr ""
 
-#: git-am.sh:847
+#: git-am.sh:845
 msgid "No changes -- Patch already applied."
 msgstr ""
 
-#: git-am.sh:857
+#: git-am.sh:855
 #, sh-format
 msgid "Patch failed at $msgnum $FIRSTLINE"
 msgstr ""
 
-#: git-am.sh:873
+#: git-am.sh:876
 msgid "applying to an empty history"
 msgstr ""
 
@@ -5015,6 +5273,112 @@ msgstr ""
 msgid "Cannot rebase onto multiple branches"
 msgstr ""
 
+#: git-rebase.sh:52
+msgid ""
+"When you have resolved this problem, run \"git rebase --continue\".\n"
+"If you prefer to skip this patch, run \"git rebase --skip\" instead.\n"
+"To check out the original branch and stop rebasing, run \"git rebase --abort"
+"\"."
+msgstr ""
+
+#: git-rebase.sh:159
+msgid "The pre-rebase hook refused to rebase."
+msgstr ""
+
+#: git-rebase.sh:164
+msgid "It looks like git-am is in progress. Cannot rebase."
+msgstr ""
+
+#: git-rebase.sh:295
+msgid "The --exec option must be used with the --interactive option"
+msgstr ""
+
+#: git-rebase.sh:300
+msgid "No rebase in progress?"
+msgstr ""
+
+#: git-rebase.sh:313
+msgid "Cannot read HEAD"
+msgstr ""
+
+#: git-rebase.sh:316
+msgid ""
+"You must edit all merge conflicts and then\n"
+"mark them as resolved using git add"
+msgstr ""
+
+#: git-rebase.sh:334
+#, sh-format
+msgid "Could not move back to $head_name"
+msgstr ""
+
+#: git-rebase.sh:350
+#, sh-format
+msgid ""
+"It seems that there is already a $state_dir_base directory, and\n"
+"I wonder if you are in the middle of another rebase.  If that is the\n"
+"case, please try\n"
+"\t$cmd_live_rebase\n"
+"If that is not the case, please\n"
+"\t$cmd_clear_stale_rebase\n"
+"and run me again.  I am stopping in case you still have something\n"
+"valuable there."
+msgstr ""
+
+#: git-rebase.sh:395
+#, sh-format
+msgid "invalid upstream $upstream_name"
+msgstr ""
+
+#: git-rebase.sh:419
+#, sh-format
+msgid "$onto_name: there are more than one merge bases"
+msgstr ""
+
+#: git-rebase.sh:422 git-rebase.sh:426
+#, sh-format
+msgid "$onto_name: there is no merge base"
+msgstr ""
+
+#: git-rebase.sh:431
+#, sh-format
+msgid "Does not point to a valid commit: $onto_name"
+msgstr ""
+
+#: git-rebase.sh:454
+#, sh-format
+msgid "fatal: no such branch: $branch_name"
+msgstr ""
+
+#: git-rebase.sh:474
+msgid "Please commit or stash them."
+msgstr ""
+
+#: git-rebase.sh:492
+#, sh-format
+msgid "Current branch $branch_name is up to date."
+msgstr ""
+
+#: git-rebase.sh:495
+#, sh-format
+msgid "Current branch $branch_name is up to date, rebase forced."
+msgstr ""
+
+#: git-rebase.sh:506
+#, sh-format
+msgid "Changes from $mb to $onto:"
+msgstr ""
+
+#. Detach HEAD and reset the tree
+#: git-rebase.sh:515
+msgid "First, rewinding head to replay your work on top of it..."
+msgstr ""
+
+#: git-rebase.sh:523
+#, sh-format
+msgid "Fast-forwarded $branch_name to $onto_name."
+msgstr ""
+
 #: git-stash.sh:51
 msgid "git stash clear with parameters is unimplemented"
 msgstr ""
@@ -5152,27 +5516,27 @@ msgstr ""
 msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:186
+#: git-submodule.sh:189
 #, sh-format
 msgid "Clone of '$url' into submodule path '$sm_path' failed"
 msgstr ""
 
-#: git-submodule.sh:196
+#: git-submodule.sh:201
 #, sh-format
 msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
 msgstr ""
 
-#: git-submodule.sh:285
+#: git-submodule.sh:290
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr ""
 
-#: git-submodule.sh:302
+#: git-submodule.sh:307
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr ""
 
-#: git-submodule.sh:306
+#: git-submodule.sh:311
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -5180,155 +5544,151 @@ msgid ""
 "Use -f if you really want to add it."
 msgstr ""
 
-#: git-submodule.sh:317
+#: git-submodule.sh:322
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr ""
 
-#: git-submodule.sh:319
+#: git-submodule.sh:324
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr ""
 
-#: git-submodule.sh:333
+#: git-submodule.sh:338
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:338
+#: git-submodule.sh:343
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:343
+#: git-submodule.sh:348
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:385
+#: git-submodule.sh:390
 #, sh-format
 msgid "Entering '$prefix$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:399
+#: git-submodule.sh:404
 #, sh-format
 msgid "Stopping at '$sm_path'; script returned non-zero status."
 msgstr ""
 
-#: git-submodule.sh:442
+#: git-submodule.sh:447
 #, sh-format
 msgid "No url found for submodule path '$sm_path' in .gitmodules"
 msgstr ""
 
-#: git-submodule.sh:451
+#: git-submodule.sh:456
 #, sh-format
 msgid "Failed to register url for submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:453
+#: git-submodule.sh:458
 #, sh-format
 msgid "Submodule '$name' ($url) registered for path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:461
+#: git-submodule.sh:466
 #, sh-format
 msgid "Failed to register update mode for submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:560
+#: git-submodule.sh:565
 #, sh-format
 msgid ""
 "Submodule path '$sm_path' not initialized\n"
 "Maybe you want to use 'update --init'?"
 msgstr ""
 
-#: git-submodule.sh:573
+#: git-submodule.sh:578
 #, sh-format
 msgid "Unable to find current revision in submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:592
+#: git-submodule.sh:597
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:606
+#: git-submodule.sh:611
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:607
+#: git-submodule.sh:612
 #, sh-format
 msgid "Submodule path '$sm_path': rebased into '$sha1'"
 msgstr ""
 
-#: git-submodule.sh:612
+#: git-submodule.sh:617
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:613
+#: git-submodule.sh:618
 #, sh-format
 msgid "Submodule path '$sm_path': merged in '$sha1'"
 msgstr ""
 
-#: git-submodule.sh:618
+#: git-submodule.sh:623
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:619
+#: git-submodule.sh:624
 #, sh-format
 msgid "Submodule path '$sm_path': checked out '$sha1'"
 msgstr ""
 
-#: git-submodule.sh:641 git-submodule.sh:964
+#: git-submodule.sh:646 git-submodule.sh:969
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:749
-msgid "--cached cannot be used with --files"
+#: git-submodule.sh:754
+msgid "The --cached option cannot be used with the --files option"
 msgstr ""
 
 #. unexpected type
-#: git-submodule.sh:789
+#: git-submodule.sh:794
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr ""
 
-#: git-submodule.sh:807
+#: git-submodule.sh:812
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_src"
 msgstr ""
 
-#: git-submodule.sh:810
+#: git-submodule.sh:815
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_dst"
 msgstr ""
 
-#: git-submodule.sh:813
+#: git-submodule.sh:818
 #, sh-format
 msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
 
-#: git-submodule.sh:838
+#: git-submodule.sh:843
 msgid "blob"
 msgstr ""
 
-#: git-submodule.sh:839
-msgid "submodule"
-msgstr ""
-
-#: git-submodule.sh:876
+#: git-submodule.sh:881
 msgid "# Submodules changed but not updated:"
 msgstr ""
 
-#: git-submodule.sh:878
+#: git-submodule.sh:883
 msgid "# Submodule changes to be committed:"
 msgstr ""
 
-#: git-submodule.sh:1022
+#: git-submodule.sh:1027
 #, sh-format
 msgid "Synchronizing submodule url for '$name'"
 msgstr ""
index 2635c2cf7b0516eac3df9855058f6c57a086f596..b327a0e8bc71c8fc57d2a64865f1a69dfe68d8e8 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git 1.7.10\n"
+"Project-Id-Version: git 1.7.12\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-07-03 10:23+0800\n"
-"PO-Revision-Date: 2012-07-04 19:33+0100\n"
+"POT-Creation-Date: 2012-08-06 23:47+0800\n"
+"PO-Revision-Date: 2012-08-14 09:58+0100\n"
 "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -48,7 +48,7 @@ msgstr "'%s' ser inte ut som en v2-bundle-fil"
 msgid "unrecognized header: %s%s (%d)"
 msgstr "okänt huvud: %s%s (%d)"
 
-#: bundle.c:89 builtin/commit.c:696
+#: bundle.c:89 builtin/commit.c:699
 #, c-format
 msgid "could not open '%s'"
 msgstr "kunde inte öppna \"%s\""
@@ -58,7 +58,7 @@ msgid "Repository lacks these prerequisite commits:"
 msgstr "Arkivet saknar dessa nödvändiga incheckningar:"
 
 #: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
-#: builtin/log.c:721 builtin/log.c:1310 builtin/log.c:1529 builtin/merge.c:347
+#: builtin/log.c:726 builtin/log.c:1316 builtin/log.c:1535 builtin/merge.c:347
 #: builtin/shortlog.c:181
 msgid "revision walk setup failed"
 msgstr "misslyckades skapa revisionstraversering"
@@ -85,7 +85,7 @@ msgstr[1] "Paketet (bundlen) kräver dessa %d referenser"
 msgid "rev-list died"
 msgstr "rev-list dog"
 
-#: bundle.c:300 builtin/log.c:1206 builtin/shortlog.c:284
+#: bundle.c:300 builtin/log.c:1212 builtin/shortlog.c:284
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "okänt argument: %s"
@@ -231,8 +231,8 @@ msgstr ""
 "%s"
 
 #: diff.c:1400
-msgid " 0 files changed\n"
-msgstr " 0 filer ändrade\n"
+msgid " 0 files changed"
+msgstr " 0 filer ändrade"
 
 #: diff.c:1404
 #, c-format
@@ -255,7 +255,7 @@ msgid_plural ", %d deletions(-)"
 msgstr[0] ", %d borttagning(-)"
 msgstr[1] ", %d borttagningar(-)"
 
-#: diff.c:3478
+#: diff.c:3461
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -291,16 +291,16 @@ msgstr "\"%s\": %s"
 msgid "'%s': short read %s"
 msgstr "\"%s\": kort läsning %s"
 
-#: help.c:208
+#: help.c:212
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "git-kommandon tillgängliga i \"%s\""
 
-#: help.c:215
+#: help.c:219
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "git-kommandon från andra platser i din $PATH"
 
-#: help.c:271
+#: help.c:275
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -309,11 +309,11 @@ msgstr ""
 "\"%s\" verkar vara ett git-kommando, men vi kan inte\n"
 "köra det. Kanske git-%s är trasigt?"
 
-#: help.c:328
+#: help.c:332
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Oj då. Ditt system rapporterar inga Git-kommandon alls."
 
-#: help.c:350
+#: help.c:354
 #, c-format
 msgid ""
 "WARNING: You called a Git command named '%s', which does not exist.\n"
@@ -322,17 +322,17 @@ msgstr ""
 "VARNING: Du anropade ett Git-kommando vid namn \"%s\", som inte finns.\n"
 "Fortsätter under förutsättningen att du menade \"%s\""
 
-#: help.c:355
+#: help.c:359
 #, c-format
 msgid "in %0.1f seconds automatically..."
 msgstr "automatiskt om %0.1f sekunder..."
 
-#: help.c:362
+#: help.c:366
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: \"%s\" är inte ett git-kommando. Se \"git --help\"."
 
-#: help.c:366
+#: help.c:370
 msgid ""
 "\n"
 "Did you mean this?"
@@ -346,35 +346,297 @@ msgstr[1] ""
 "\n"
 "Menade du ett av dessa?"
 
-#: parse-options.c:493
+#: merge-recursive.c:190
+#, c-format
+msgid "(bad commit)\n"
+msgstr "(felaktig incheckning)\n"
+
+#: merge-recursive.c:206
+#, c-format
+msgid "addinfo_cache failed for path '%s'"
+msgstr "addinfo_cache misslyckades för sökvägen \"%s\""
+
+#: merge-recursive.c:268
+msgid "error building trees"
+msgstr "fel vid byggande av träd"
+
+#: merge-recursive.c:497
+msgid "diff setup failed"
+msgstr "misslyckades sätta upp för diff"
+
+#: merge-recursive.c:627
+msgid "merge-recursive: disk full?"
+msgstr "merge-recursive: disk full?"
+
+#: merge-recursive.c:690
+#, c-format
+msgid "failed to create path '%s'%s"
+msgstr "misslyckades skapa sökvägen \"%s\"%s"
+
+#: merge-recursive.c:701
+#, c-format
+msgid "Removing %s to make room for subdirectory\n"
+msgstr "Tar bort %s för att göra plats för underkatalog\n"
+
+#. something else exists
+#. .. but not some other error (who really cares what?)
+#: merge-recursive.c:715 merge-recursive.c:736
+msgid ": perhaps a D/F conflict?"
+msgstr ": kanske en K/F-konflikt?"
+
+#: merge-recursive.c:726
+#, c-format
+msgid "refusing to lose untracked file at '%s'"
+msgstr "vägrar förlora ospårad fil vid \"%s\""
+
+#: merge-recursive.c:766
+#, c-format
+msgid "cannot read object %s '%s'"
+msgstr "kan inte läsa objektet %s: \"%s\""
+
+#: merge-recursive.c:768
+#, c-format
+msgid "blob expected for %s '%s'"
+msgstr "blob förväntades för %s \"%s\""
+
+#: merge-recursive.c:791 builtin/clone.c:302
+#, c-format
+msgid "failed to open '%s'"
+msgstr "misslyckades öppna \"%s\""
+
+#: merge-recursive.c:799
+#, c-format
+msgid "failed to symlink '%s'"
+msgstr "misslyckades ta skapa symboliska länken \"%s\""
+
+#: merge-recursive.c:802
+#, c-format
+msgid "do not know what to do with %06o %s '%s'"
+msgstr "vet inte hur %06o %s \"%s\" skall hanteras"
+
+#: merge-recursive.c:939
+msgid "Failed to execute internal merge"
+msgstr "Misslyckades exekvera intern sammanslagning"
+
+#: merge-recursive.c:943
+#, c-format
+msgid "Unable to add %s to database"
+msgstr "Kunde inte lägga till %s till databasen"
+
+#: merge-recursive.c:959
+msgid "unsupported object type in the tree"
+msgstr "objekttyp som ej stöds upptäcktes i trädet"
+
+#: merge-recursive.c:1038 merge-recursive.c:1052
+#, c-format
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree."
+msgstr ""
+"KONFLIKT (%s/radera): %s raderad i %s och %s i %s. Versionen %s av %s lämnad "
+"i trädet."
+
+#: merge-recursive.c:1044 merge-recursive.c:1057
+#, c-format
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree at %s."
+msgstr ""
+"KONFLIKT (%s/radera): %s raderad i %s och %s i %s. Versionen %s av %s lämnad "
+"i trädet vid %s."
+
+#: merge-recursive.c:1098
+msgid "rename"
+msgstr "namnbyte"
+
+#: merge-recursive.c:1098
+msgid "renamed"
+msgstr "namnbytt"
+
+#: merge-recursive.c:1154
+#, c-format
+msgid "%s is a directory in %s adding as %s instead"
+msgstr "%s är en katalog i %s lägger till som %s istället"
+
+#: merge-recursive.c:1176
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
+"\"->\"%s\" in \"%s\"%s"
+msgstr ""
+"KONFLIKT (namnbyte/namnbyte): Namnbyte \"%s\"->\"%s\" på grenen \"%s\" "
+"namnbyte \"%s\"->\"%s\" i \"%s\"%s"
+
+#: merge-recursive.c:1181
+msgid " (left unresolved)"
+msgstr " (lämnad olöst)"
+
+#: merge-recursive.c:1235
+#, c-format
+msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
+msgstr ""
+"KONFLIKT (namnbyte/namnbyte): Namnbyte %s->%s i %s. Namnbyte %s->%s i %s"
+
+#: merge-recursive.c:1265
+#, c-format
+msgid "Renaming %s to %s and %s to %s instead"
+msgstr "Byter namn på %s till %s och %s till %s istället"
+
+#: merge-recursive.c:1464
+#, c-format
+msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
+msgstr "KONFLIKT (namnbyte/tillägg): Namnbyte %s->%s i %s. %s tillagd i %s"
+
+#: merge-recursive.c:1474
+#, c-format
+msgid "Adding merged %s"
+msgstr "Lägger till sammanslagen %s"
+
+#: merge-recursive.c:1479 merge-recursive.c:1677
+#, c-format
+msgid "Adding as %s instead"
+msgstr "Lägger till som %s iställer"
+
+#: merge-recursive.c:1530
+#, c-format
+msgid "cannot read object %s"
+msgstr "kan inte läsa objektet %s"
+
+#: merge-recursive.c:1533
+#, c-format
+msgid "object %s is not a blob"
+msgstr "objektet %s är inte en blob"
+
+#: merge-recursive.c:1581
+msgid "modify"
+msgstr "ändra"
+
+#: merge-recursive.c:1581
+msgid "modified"
+msgstr "ändrad"
+
+#: merge-recursive.c:1591
+msgid "content"
+msgstr "innehåll"
+
+#: merge-recursive.c:1598
+msgid "add/add"
+msgstr "tillägg/tillägg"
+
+#: merge-recursive.c:1632
+#, c-format
+msgid "Skipped %s (merged same as existing)"
+msgstr "Hoppade över %s (sammanslagen samma som befintlig)"
+
+#: merge-recursive.c:1646
+#, c-format
+msgid "Auto-merging %s"
+msgstr "Slår ihop %s automatiskt"
+
+#: merge-recursive.c:1650 git-submodule.sh:844
+msgid "submodule"
+msgstr "undermodul"
+
+#: merge-recursive.c:1651
+#, c-format
+msgid "CONFLICT (%s): Merge conflict in %s"
+msgstr "KONFLIKT (%s): Sammanslagningskonflikt i %s"
+
+#: merge-recursive.c:1741
+#, c-format
+msgid "Removing %s"
+msgstr "Tar bort %s"
+
+#: merge-recursive.c:1766
+msgid "file/directory"
+msgstr "fil/katalog"
+
+#: merge-recursive.c:1772
+msgid "directory/file"
+msgstr "katalog/fil"
+
+#: merge-recursive.c:1777
+#, c-format
+msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
+msgstr ""
+"KONFLIKT (%s): Det finns en katalog med namnet %s i %s. Lägger till %s som %s"
+
+#: merge-recursive.c:1787
+#, c-format
+msgid "Adding %s"
+msgstr "Lägger till %s"
+
+#: merge-recursive.c:1804
+msgid "Fatal merge failure, shouldn't happen."
+msgstr "Ödesdigert sammanslagningsfel, borde inte inträffa."
+
+#: merge-recursive.c:1823
+msgid "Already up-to-date!"
+msgstr "Redan à jour!"
+
+#: merge-recursive.c:1832
+#, c-format
+msgid "merging of trees %s and %s failed"
+msgstr "sammanslagning av träden %s och %s misslyckades"
+
+#: merge-recursive.c:1862
+#, c-format
+msgid "Unprocessed path??? %s"
+msgstr "Obehandlad sökväg??? %s"
+
+#: merge-recursive.c:1907
+msgid "Merging:"
+msgstr "Slår ihop:"
+
+#: merge-recursive.c:1920
+#, c-format
+msgid "found %u common ancestor:"
+msgid_plural "found %u common ancestors:"
+msgstr[0] "hittade %u gemensam förfader:"
+msgstr[1] "hittade %u gemensamma förfäder:"
+
+#: merge-recursive.c:1957
+msgid "merge returned no commit"
+msgstr "sammanslagningen returnerade ingen incheckning"
+
+#: merge-recursive.c:2014
+#, c-format
+msgid "Could not parse object '%s'"
+msgstr "Kunde inte tolka objektet \"%s\""
+
+#: merge-recursive.c:2026 builtin/merge.c:697
+msgid "Unable to write index."
+msgstr "Kunde inte skriva indexet."
+
+#: parse-options.c:494
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:511
+#: parse-options.c:512
 #, c-format
 msgid "usage: %s"
 msgstr "användning: %s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:515
+#: parse-options.c:516
 #, c-format
 msgid "   or: %s"
 msgstr "     eller: %s"
 
-#: parse-options.c:518
+#: parse-options.c:519
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: remote.c:1629
+#: remote.c:1632
 #, 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] "Din gren ligger före \"%s\" med %d incheckning.\n"
 msgstr[1] "Din gren ligger före \"%s\" med %d incheckningar.\n"
 
-#: remote.c:1635
+#: remote.c:1638
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -384,7 +646,7 @@ msgstr[0] ""
 msgstr[1] ""
 "Din gren ligger efter \"%s\" med %d incheckningar, och kan snabbspolas.\n"
 
-#: remote.c:1643
+#: remote.c:1646
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -608,7 +870,7 @@ msgstr "kan inte bestämma HEAD"
 msgid "cannot abort from a branch yet to be born"
 msgstr "kan inte avbryta från en gren som ännu inte är född"
 
-#: sequencer.c:805 builtin/apply.c:3697
+#: sequencer.c:805 builtin/apply.c:3988
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "kan inte öppna %s: %s"
@@ -640,21 +902,21 @@ msgstr "Kan inte ångra som första incheckning"
 msgid "Can't cherry-pick into empty head"
 msgstr "Kan inte göra \"cherry-pick\" i ett tomt huvud"
 
-#: sha1_name.c:864
+#: sha1_name.c:1044
 msgid "HEAD does not point to a branch"
 msgstr "HEAD pekar inte på en gren"
 
-#: sha1_name.c:867
+#: sha1_name.c:1047
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "Okänd gren: \"%s\""
 
-#: sha1_name.c:869
+#: sha1_name.c:1049
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "Ingen standarduppström angiven för grenen \"%s\""
 
-#: sha1_name.c:872
+#: sha1_name.c:1052
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "Uppströmsgrenen \"%s\" är inte lagrad som en fjärrspårande gren"
@@ -668,343 +930,343 @@ msgstr "kan inte slå upp aktuell användare i passwd-filen: %s"
 msgid "no such user"
 msgstr "okänd användare"
 
-#: wt-status.c:141
+#: wt-status.c:140
 msgid "Unmerged paths:"
 msgstr "Ej sammanslagna sökvägar:"
 
-#: wt-status.c:168 wt-status.c:195
+#: wt-status.c:167 wt-status.c:194
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (använd \"git reset %s <fil>...\" för att ta bort från kö)"
 
-#: wt-status.c:170 wt-status.c:197
+#: wt-status.c:169 wt-status.c:196
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (använd \"git rm --cached <fil>...\" för att ta bort från kö)"
 
-#: wt-status.c:174
+#: wt-status.c:173
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (använd \"git add <fil>...\" för att ange lösning)"
 
-#: wt-status.c:176 wt-status.c:180
+#: wt-status.c:175 wt-status.c:179
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr "  (använd \"git add/rm <fil>...\" som lämpligt för att ange lösning)"
 
-#: wt-status.c:178
+#: wt-status.c:177
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (använd \"git rm <fil>...\" för att ange lösning)"
 
-#: wt-status.c:189
+#: wt-status.c:188
 msgid "Changes to be committed:"
 msgstr "Ändringar att checka in:"
 
-#: wt-status.c:207
+#: wt-status.c:206
 msgid "Changes not staged for commit:"
 msgstr "Ändringar ej i incheckningskön:"
 
-#: wt-status.c:211
+#: wt-status.c:210
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 "  (använd \"git add <fil>...\" för att uppdatera vad som skall checkas in)"
 
-#: wt-status.c:213
+#: wt-status.c:212
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 "  (använd \"git add/rm <fil>...\" för att uppdatera vad som skall checkas in)"
 
-#: wt-status.c:214
+#: wt-status.c:213
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (använd \"git checkout -- <fil>...\" för att förkasta ändringar i "
 "arbetskatalogen)"
 
-#: wt-status.c:216
+#: wt-status.c:215
 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"); lägg till ett -e.
-#: wt-status.c:225
+#: wt-status.c:224
 #, c-format
 msgid "%s files:"
 msgstr "%se filer:"
 
-#: wt-status.c:228
+#: wt-status.c:227
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
-"  (använd \"git %s <fil>...\" för att ta med i vad som skall checkas in)"
+"  (använd \"git %s <fil>...\" för att ta med i det som skall checkas in)"
 
-#: wt-status.c:245
+#: wt-status.c:244
 msgid "bug"
 msgstr "programfel"
 
-#: wt-status.c:250
+#: wt-status.c:249
 msgid "both deleted:"
 msgstr "borttaget av bägge:"
 
-#: wt-status.c:251
+#: wt-status.c:250
 msgid "added by us:"
 msgstr "tillagt av oss:"
 
-#: wt-status.c:252
+#: wt-status.c:251
 msgid "deleted by them:"
 msgstr "borttaget av dem:"
 
-#: wt-status.c:253
+#: wt-status.c:252
 msgid "added by them:"
 msgstr "tillagt av dem:"
 
-#: wt-status.c:254
+#: wt-status.c:253
 msgid "deleted by us:"
 msgstr "borttaget av oss:"
 
-#: wt-status.c:255
+#: wt-status.c:254
 msgid "both added:"
 msgstr "tillagt av bägge:"
 
-#: wt-status.c:256
+#: wt-status.c:255
 msgid "both modified:"
 msgstr "ändrat av bägge:"
 
-#: wt-status.c:286
+#: wt-status.c:285
 msgid "new commits, "
 msgstr "nya incheckningar, "
 
-#: wt-status.c:288
+#: wt-status.c:287
 msgid "modified content, "
 msgstr "ändrat innehåll, "
 
-#: wt-status.c:290
+#: wt-status.c:289
 msgid "untracked content, "
 msgstr "ospårat innehåll, "
 
-#: wt-status.c:304
+#: wt-status.c:303
 #, c-format
 msgid "new file:   %s"
 msgstr "ny fil:     %s"
 
-#: wt-status.c:307
+#: wt-status.c:306
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "kopierad:   %s -> %s"
 
-#: wt-status.c:310
+#: wt-status.c:309
 #, c-format
 msgid "deleted:    %s"
 msgstr "borttagen:  %s"
 
-#: wt-status.c:313
+#: wt-status.c:312
 #, c-format
 msgid "modified:   %s"
 msgstr "ändrad:     %s"
 
-#: wt-status.c:316
+#: wt-status.c:315
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "namnbyte:   %s -> %s"
 
-#: wt-status.c:319
+#: wt-status.c:318
 #, c-format
 msgid "typechange: %s"
 msgstr "typbyte:    %s"
 
-#: wt-status.c:322
+#: wt-status.c:321
 #, c-format
 msgid "unknown:    %s"
 msgstr "okänd:      %s"
 
-#: wt-status.c:325
+#: wt-status.c:324
 #, c-format
 msgid "unmerged:   %s"
 msgstr "osammansl.: %s"
 
-#: wt-status.c:328
+#: wt-status.c:327
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr "programfel: diff-status %c ej hanterad"
 
-#: wt-status.c:786
+#: wt-status.c:785
 msgid "You have unmerged paths."
 msgstr "Du har ej sammanslagna sökvägar."
 
-#: wt-status.c:789 wt-status.c:913
+#: wt-status.c:788 wt-status.c:912
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (rätta konflikter och kör \"git commit\")"
 
-#: wt-status.c:792
+#: wt-status.c:791
 msgid "All conflicts fixed but you are still merging."
 msgstr "Alla konflikter har rättats men du är fortfarande i en sammanslagning."
 
-#: wt-status.c:795
+#: wt-status.c:794
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (använd \"git commit\" för att slutföra sammanslagningen)"
 
-#: wt-status.c:805
+#: wt-status.c:804
 msgid "You are in the middle of an am session."
 msgstr "Du är i mitten av en körning av \"git am\"."
 
-#: wt-status.c:808
+#: wt-status.c:807
 msgid "The current patch is empty."
 msgstr "Aktuell patch är tom."
 
-#: wt-status.c:812
+#: wt-status.c:811
 msgid "  (fix conflicts and then run \"git am --resolved\")"
 msgstr "  (rätta konflikter och kör sedan \"git am --resolved\")"
 
-#: wt-status.c:814
+#: wt-status.c:813
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (använd \"git am --skip\" för att hoppa över patchen)"
 
-#: wt-status.c:816
+#: wt-status.c:815
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (använd \"git am --abort\" för att återställa ursprungsgrenen)"
 
-#: wt-status.c:874 wt-status.c:884
+#: wt-status.c:873 wt-status.c:883
 msgid "You are currently rebasing."
 msgstr "Du håller på med en ombasering."
 
-#: wt-status.c:877
+#: wt-status.c:876
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git rebase --continue\")"
 
-#: wt-status.c:879
+#: wt-status.c:878
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (använd \"git rebase --skip\" för att hoppa över patchen)"
 
-#: wt-status.c:881
+#: wt-status.c:880
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (använd \"git rebase --abort\" för att checka ut ursprungsgrenen)"
 
-#: wt-status.c:887
+#: wt-status.c:886
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (alla konflikter rättade: kör \"git rebase --continue\")"
 
-#: wt-status.c:889
+#: wt-status.c:888
 msgid "You are currently splitting a commit during a rebase."
 msgstr "Du håller på att dela upp en incheckning i en ombasering."
 
-#: wt-status.c:892
+#: wt-status.c:891
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr "  (Så fort din arbetskatalog är ren, kör \"git rebase --continue\")"
 
-#: wt-status.c:894
+#: wt-status.c:893
 msgid "You are currently editing a commit during a rebase."
 msgstr "Du håller på att redigera en incheckning under en ombasering."
 
-#: wt-status.c:897
+#: wt-status.c:896
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
 "  (använd \"git commit --amend\" för att lägga till på aktuell incheckning)"
 
-#: wt-status.c:899
+#: wt-status.c:898
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr "  (använd \"git rebase --continue\" när du är nöjd med dina ändringar)"
 
-#: wt-status.c:909
+#: wt-status.c:908
 msgid "You are currently cherry-picking."
 msgstr "Du håller på med en \"cherry-pick\"."
 
-#: wt-status.c:916
+#: wt-status.c:915
 msgid "  (all conflicts fixed: run \"git commit\")"
 msgstr "  (alla konflikter har rättats: kör \"git commit\")"
 
-#: wt-status.c:925
+#: wt-status.c:924
 msgid "You are currently bisecting."
 msgstr "Du håller på med en \"bisect\"."
 
-#: wt-status.c:928
+#: wt-status.c:927
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr ""
 "  (använd \"git bisect reset\" för att komma tillbaka till ursprungsgrenen)"
 
-#: wt-status.c:979
+#: wt-status.c:978
 msgid "On branch "
 msgstr "På grenen "
 
-#: wt-status.c:986
+#: wt-status.c:985
 msgid "Not currently on any branch."
 msgstr "Inte på någon gren för närvarande."
 
-#: wt-status.c:998
+#: wt-status.c:997
 msgid "Initial commit"
 msgstr "Första incheckning"
 
-#: wt-status.c:1012
+#: wt-status.c:1011
 msgid "Untracked"
 msgstr "Ospårad"
 
-#: wt-status.c:1014
+#: wt-status.c:1013
 msgid "Ignored"
 msgstr "Ignorerad"
 
 # %s är nästa sträng eller tom.
-#: wt-status.c:1016
+#: wt-status.c:1015
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Ospårade filer visas ej%s"
 
-#: wt-status.c:1018
+#: wt-status.c:1017
 msgid " (use -u option to show untracked files)"
 msgstr " (använd flaggan -u för att visa ospårade filer)"
 
-#: wt-status.c:1024
+#: wt-status.c:1023
 msgid "No changes"
 msgstr "Inga ändringar"
 
-#: wt-status.c:1028
+#: wt-status.c:1027
 #, c-format
 msgid "no changes added to commit%s\n"
 msgstr "inga ändringar att checka in%s\n"
 
-#: wt-status.c:1030
+#: wt-status.c:1029
 msgid " (use \"git add\" and/or \"git commit -a\")"
 msgstr " (använd \"git add\" och/eller \"git commit -a\")"
 
-#: wt-status.c:1032
+#: wt-status.c:1031
 #, c-format
 msgid "nothing added to commit but untracked files present%s\n"
 msgstr "inget köat för incheckning, men ospårade filer finns%s\n"
 
-#: wt-status.c:1034
+#: wt-status.c:1033
 msgid " (use \"git add\" to track)"
-msgstr " (använd \"git add\" för att spåra)"
+msgstr " (spåra med \"git add\")"
 
-#: wt-status.c:1036 wt-status.c:1039 wt-status.c:1042
+#: wt-status.c:1035 wt-status.c:1038 wt-status.c:1041
 #, c-format
 msgid "nothing to commit%s\n"
 msgstr "inget att checka in%s\n"
 
-#: wt-status.c:1037
+#: wt-status.c:1036
 msgid " (create/copy files and use \"git add\" to track)"
-msgstr " (skapa/kopiera filer och använd \"git add\" för att spåra)"
+msgstr " (skapa/kopiera filer och spåra med \"git add\")"
 
-#: wt-status.c:1040
+#: wt-status.c:1039
 msgid " (use -u to show untracked files)"
 msgstr " (använd -u för att visa ospårade filer)"
 
-#: wt-status.c:1043
+#: wt-status.c:1042
 msgid " (working directory clean)"
 msgstr " (arbetskatalogen ren)"
 
-#: wt-status.c:1151
+#: wt-status.c:1150
 msgid "HEAD (no branch)"
 msgstr "HEAD (ingen gren)"
 
-#: wt-status.c:1157
+#: wt-status.c:1156
 msgid "Initial commit on "
 msgstr "Första incheckning på "
 
-#: wt-status.c:1172
+#: wt-status.c:1171
 msgid "behind "
 msgstr "efter "
 
-#: wt-status.c:1175 wt-status.c:1178
+#: wt-status.c:1174 wt-status.c:1177
 msgid "ahead "
 msgstr "före "
 
-#: wt-status.c:1180
+#: wt-status.c:1179
 msgid ", behind "
 msgstr ", efter "
 
@@ -1013,7 +1275,7 @@ msgstr ", efter "
 msgid "unexpected diff status %c"
 msgstr "diff-status %c förväntades inte"
 
-#: builtin/add.c:67 builtin/commit.c:226
+#: builtin/add.c:67 builtin/commit.c:229
 msgid "updating files failed"
 msgstr "misslyckades uppdatera filer"
 
@@ -1103,75 +1365,75 @@ msgstr "Inget angivet, inget tillagt.\n"
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Kanske menade du att skriva \"git add .\"?\n"
 
-#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:286 builtin/mv.c:82
+#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:289 builtin/mv.c:82
 #: builtin/rm.c:162
 msgid "index file corrupt"
 msgstr "indexfilen trasig"
 
-#: builtin/add.c:480 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4433 builtin/mv.c:229 builtin/rm.c:260
 msgid "Unable to write new index file"
 msgstr "Kunde inte skriva ny indexfil"
 
-#: builtin/apply.c:53
+#: builtin/apply.c:57
 msgid "git apply [options] [<patch>...]"
 msgstr "git apply [flaggor] [<patch>...]"
 
-#: builtin/apply.c:106
+#: builtin/apply.c:110
 #, c-format
 msgid "unrecognized whitespace option '%s'"
 msgstr "okänt alternativ för whitespace: \"%s\""
 
-#: builtin/apply.c:121
+#: builtin/apply.c:125
 #, c-format
 msgid "unrecognized whitespace ignore option '%s'"
 msgstr "okänt alternativ för ignore-whitespace: \"%s\""
 
-#: builtin/apply.c:815
+#: builtin/apply.c:824
 #, c-format
 msgid "Cannot prepare timestamp regexp %s"
 msgstr "Kan inte förbereda reguljärt uttryck för tidsstämpeln %s"
 
-#: builtin/apply.c:824
+#: builtin/apply.c:833
 #, c-format
 msgid "regexec returned %d for input: %s"
 msgstr "regexec returnerade %d för indata: %s"
 
-#: builtin/apply.c:905
+#: builtin/apply.c:914
 #, c-format
 msgid "unable to find filename in patch at line %d"
 msgstr "kan inte hitta filnamn i patchen på rad %d"
 
-#: builtin/apply.c:937
+#: builtin/apply.c:946
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
 msgstr "git apply: dålig git-diff - förväntade /dev/null, fick %s på rad %d"
 
-#: builtin/apply.c:941
+#: builtin/apply.c:950
 #, c-format
 msgid "git apply: bad git-diff - inconsistent new filename on line %d"
 msgstr "git apply: dålig git-diff - motsägande nytt filnamn på rad %d"
 
-#: builtin/apply.c:942
+#: builtin/apply.c:951
 #, c-format
 msgid "git apply: bad git-diff - inconsistent old filename on line %d"
 msgstr "git apply: dålig git-diff - motsägande gammalt filnamn på rad %d"
 
-#: builtin/apply.c:949
+#: builtin/apply.c:958
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null on line %d"
 msgstr "git apply: dålig git-diff - förväntade /dev/null på rad %d"
 
-#: builtin/apply.c:1394
+#: builtin/apply.c:1403
 #, c-format
 msgid "recount: unexpected line: %.*s"
 msgstr "recount: förväntade rad: %.*s"
 
-#: builtin/apply.c:1451
+#: builtin/apply.c:1460
 #, c-format
 msgid "patch fragment without header at line %d: %.*s"
 msgstr "patch-fragment utan huvud på rad %d: %.*s"
 
-#: builtin/apply.c:1468
+#: builtin/apply.c:1477
 #, c-format
 msgid ""
 "git diff header lacks filename information when removing %d leading pathname "
@@ -1187,82 +1449,82 @@ msgstr[1] ""
 "sökvägskomponenter\n"
 "tas bort (rad %d)"
 
-#: builtin/apply.c:1628
+#: builtin/apply.c:1637
 msgid "new file depends on old contents"
 msgstr "ny fil beror på gammalt innehåll"
 
-#: builtin/apply.c:1630
+#: builtin/apply.c:1639
 msgid "deleted file still has contents"
 msgstr "borttagen fil har fortfarande innehåll"
 
-#: builtin/apply.c:1656
+#: builtin/apply.c:1665
 #, c-format
 msgid "corrupt patch at line %d"
 msgstr "trasig patch på rad %d"
 
-#: builtin/apply.c:1692
+#: builtin/apply.c:1701
 #, c-format
 msgid "new file %s depends on old contents"
 msgstr "nya filen %s beror på gammalt innehåll"
 
-#: builtin/apply.c:1694
+#: builtin/apply.c:1703
 #, c-format
 msgid "deleted file %s still has contents"
 msgstr "borttagna filen %s har fortfarande innehåll"
 
-#: builtin/apply.c:1697
+#: builtin/apply.c:1706
 #, c-format
 msgid "** warning: file %s becomes empty but is not deleted"
 msgstr "** varning: filen %s blir tom men har inte tagits bort"
 
-#: builtin/apply.c:1843
+#: builtin/apply.c:1852
 #, c-format
 msgid "corrupt binary patch at line %d: %.*s"
 msgstr "trasig binärpatch på rad %d: %.*s"
 
 #. there has to be one hunk (forward hunk)
-#: builtin/apply.c:1872
+#: builtin/apply.c:1881
 #, c-format
 msgid "unrecognized binary patch at line %d"
 msgstr "binärpatchen på rad %d känns inte igen"
 
-#: builtin/apply.c:1958
+#: builtin/apply.c:1967
 #, c-format
 msgid "patch with only garbage at line %d"
 msgstr "patch med bara skräp på rad %d"
 
-#: builtin/apply.c:2048
+#: builtin/apply.c:2057
 #, c-format
 msgid "unable to read symlink %s"
 msgstr "kunde inte läsa symboliska länken %s"
 
-#: builtin/apply.c:2052
+#: builtin/apply.c:2061
 #, c-format
 msgid "unable to open or read %s"
 msgstr "kunde inte öppna eller läsa %s"
 
-#: builtin/apply.c:2123
+#: builtin/apply.c:2132
 msgid "oops"
 msgstr "hoppsan"
 
-#: builtin/apply.c:2645
+#: builtin/apply.c:2654
 #, c-format
 msgid "invalid start of line: '%c'"
 msgstr "felaktig inledning på rad: \"%c\""
 
-#: builtin/apply.c:2763
+#: builtin/apply.c:2772
 #, c-format
 msgid "Hunk #%d succeeded at %d (offset %d line)."
 msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
 msgstr[0] "Stycke %d lyckades på %d (offset %d rad)."
 msgstr[1] "Stycke %d lyckades på %d (offset %d rader)."
 
-#: builtin/apply.c:2775
+#: builtin/apply.c:2784
 #, c-format
 msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
 msgstr "Sammanhang reducerat till (%ld/%ld) för att tillämpa fragment vid %d"
 
-#: builtin/apply.c:2781
+#: builtin/apply.c:2790
 #, c-format
 msgid ""
 "while searching for:\n"
@@ -1271,313 +1533,321 @@ msgstr ""
 "vid sökning efter:\n"
 "%.*s"
 
-#: builtin/apply.c:2800
+#: builtin/apply.c:2809
 #, c-format
 msgid "missing binary patch data for '%s'"
 msgstr "saknar binära patchdata för \"%s\""
 
-#: builtin/apply.c:2903
+#: builtin/apply.c:2912
 #, c-format
 msgid "binary patch does not apply to '%s'"
 msgstr "binärpatchen kan inte tillämpas på \"%s\""
 
-#: builtin/apply.c:2909
+#: builtin/apply.c:2918
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
 msgstr "binärpatchen på \"%s\" ger felaktigt resultat (förväntade %s, fick %s)"
 
-#: builtin/apply.c:2930
+#: builtin/apply.c:2939
 #, c-format
 msgid "patch failed: %s:%ld"
 msgstr "patch misslyckades: %s:%ld"
 
-#: builtin/apply.c:3045
+#: builtin/apply.c:3061
 #, c-format
-msgid "patch %s has been renamed/deleted"
-msgstr "patchen %s har ändrat namn/tagits bort"
+msgid "cannot checkout %s"
+msgstr "kan inte checka ut %s"
 
-#: builtin/apply.c:3052 builtin/apply.c:3069
+#: builtin/apply.c:3106 builtin/apply.c:3115 builtin/apply.c:3159
 #, c-format
 msgid "read of %s failed"
 msgstr "misslyckades läsa %s"
 
-#: builtin/apply.c:3084
-msgid "removal patch leaves file contents"
-msgstr "patch för borttagning lämnar kvar filinnehåll"
-
-#: builtin/apply.c:3105
+#: builtin/apply.c:3139 builtin/apply.c:3361
 #, c-format
-msgid "%s: already exists in working directory"
-msgstr "%s: finns redan i arbetskatalogen"
+msgid "path %s has been renamed/deleted"
+msgstr "sökvägen %s har ändrat namn/tagits bort"
 
-#: builtin/apply.c:3143
+#: builtin/apply.c:3220 builtin/apply.c:3375
 #, c-format
-msgid "%s: has been deleted/renamed"
-msgstr "%s: har tagits bort/ändrat namn"
+msgid "%s: does not exist in index"
+msgstr "%s: finns inte i indexet"
 
-#: builtin/apply.c:3148 builtin/apply.c:3179
+#: builtin/apply.c:3224 builtin/apply.c:3367 builtin/apply.c:3389
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: builtin/apply.c:3159
-#, c-format
-msgid "%s: does not exist in index"
-msgstr "%s: finns inte i indexet"
-
-#: builtin/apply.c:3173
+#: builtin/apply.c:3229 builtin/apply.c:3383
 #, c-format
 msgid "%s: does not match index"
 msgstr "%s: motsvarar inte indexet"
 
-#: builtin/apply.c:3190
+#: builtin/apply.c:3331
+msgid "removal patch leaves file contents"
+msgstr "patch för borttagning lämnar kvar filinnehåll"
+
+#: builtin/apply.c:3400
 #, c-format
 msgid "%s: wrong type"
 msgstr "%s: fel typ"
 
-#: builtin/apply.c:3192
+#: builtin/apply.c:3402
 #, c-format
 msgid "%s has type %o, expected %o"
 msgstr "%s har typen %o, förväntade %o"
 
-#: builtin/apply.c:3247
+#: builtin/apply.c:3503
 #, c-format
 msgid "%s: already exists in index"
 msgstr "%s: finns redan i indexet"
 
-#: builtin/apply.c:3267
+#: builtin/apply.c:3506
+#, c-format
+msgid "%s: already exists in working directory"
+msgstr "%s: finns redan i arbetskatalogen"
+
+#: builtin/apply.c:3526
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
 msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o)"
 
-#: builtin/apply.c:3272
+#: builtin/apply.c:3531
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o) of %s"
 msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o) för %s"
 
-#: builtin/apply.c:3280
+#: builtin/apply.c:3539
 #, c-format
 msgid "%s: patch does not apply"
 msgstr "%s: patchen kan inte tillämpas"
 
-#: builtin/apply.c:3293
+#: builtin/apply.c:3552
 #, c-format
 msgid "Checking patch %s..."
 msgstr "Kontrollerar patchen %s..."
 
-#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
+#: builtin/apply.c:3607 builtin/checkout.c:213 builtin/reset.c:158
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr "make_cache_entry misslyckades för sökvägen \"%s\""
 
-#: builtin/apply.c:3491
+#: builtin/apply.c:3750
 #, c-format
 msgid "unable to remove %s from index"
 msgstr "kan inte ta bort %s från indexet"
 
-#: builtin/apply.c:3518
+#: builtin/apply.c:3778
 #, c-format
 msgid "corrupt patch for subproject %s"
 msgstr "trasig patch för underprojektet %s"
 
-#: builtin/apply.c:3522
+#: builtin/apply.c:3782
 #, c-format
 msgid "unable to stat newly created file '%s'"
 msgstr "kan inte ta status på nyligen skapade filen \"%s\""
 
-#: builtin/apply.c:3527
+#: builtin/apply.c:3787
 #, c-format
 msgid "unable to create backing store for newly created file %s"
 msgstr "kan inte skapa säkerhetsminne för nyligen skapade filen %s"
 
-#: builtin/apply.c:3530
+#: builtin/apply.c:3790 builtin/apply.c:3898
 #, c-format
 msgid "unable to add cache entry for %s"
 msgstr "kan inte lägga till cachepost för %s"
 
-#: builtin/apply.c:3563
+#: builtin/apply.c:3823
 #, c-format
 msgid "closing file '%s'"
 msgstr "stänger filen \"%s\""
 
-#: builtin/apply.c:3612
+#: builtin/apply.c:3872
 #, c-format
 msgid "unable to write file '%s' mode %o"
 msgstr "kan inte skriva filen \"%s\" läge %o"
 
-#: builtin/apply.c:3668
+#: builtin/apply.c:3959
 #, c-format
 msgid "Applied patch %s cleanly."
 msgstr "Tillämpade patchen %s rent."
 
-#: builtin/apply.c:3676
+#: builtin/apply.c:3967
 msgid "internal error"
 msgstr "internt fel"
 
 #. Say this even without --verbose
-#: builtin/apply.c:3679
+#: builtin/apply.c:3970
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
 msgstr[0] "Tillämpade patchen %%s med %d refuserad..."
 msgstr[1] "Tillämpade patchen %%s med %d refuserade..."
 
-#: builtin/apply.c:3689
+#: builtin/apply.c:3980
 #, c-format
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "trunkerar .rej-filnamnet till %.*s.rej"
 
-#: builtin/apply.c:3710
+#: builtin/apply.c:4001
 #, c-format
 msgid "Hunk #%d applied cleanly."
 msgstr "Stycke %d tillämpades rent."
 
-#: builtin/apply.c:3713
+#: builtin/apply.c:4004
 #, c-format
 msgid "Rejected hunk #%d."
 msgstr "Refuserar stycke %d."
 
-#: builtin/apply.c:3844
+#: builtin/apply.c:4154
 msgid "unrecognized input"
 msgstr "indata känns inte igen"
 
-#: builtin/apply.c:3855
+#: builtin/apply.c:4165
 msgid "unable to read index file"
 msgstr "kan inte läsa indexfilen"
 
-#: builtin/apply.c:3970 builtin/apply.c:3973
+#: builtin/apply.c:4284 builtin/apply.c:4287
 msgid "path"
 msgstr "sökväg"
 
-#: builtin/apply.c:3971
+#: builtin/apply.c:4285
 msgid "don't apply changes matching the given path"
 msgstr "tillämpa inte ändringar som motsvarar given sökväg"
 
-#: builtin/apply.c:3974
+#: builtin/apply.c:4288
 msgid "apply changes matching the given path"
 msgstr "tillämpa ändringar som motsvarar given sökväg"
 
-#: builtin/apply.c:3976
+#: builtin/apply.c:4290
 msgid "num"
 msgstr "antal"
 
-#: builtin/apply.c:3977
+#: builtin/apply.c:4291
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr "ta bort <antal> inledande snedstreck från traditionella diff-sökvägar"
 
-#: builtin/apply.c:3980
+#: builtin/apply.c:4294
 msgid "ignore additions made by the patch"
 msgstr "ignorera tillägg gjorda av patchen"
 
-#: builtin/apply.c:3982
+#: builtin/apply.c:4296
 msgid "instead of applying the patch, output diffstat for the input"
 msgstr "istället för att tillämpa patchen, skriv ut diffstat för indata"
 
-#: builtin/apply.c:3986
+#: builtin/apply.c:4300
 msgid "shows number of added and deleted lines in decimal notation"
 msgstr "visar antal tillagda och borttagna rader decimalt"
 
-#: builtin/apply.c:3988
+#: builtin/apply.c:4302
 msgid "instead of applying the patch, output a summary for the input"
 msgstr "istället för att tillämpa patchen, skriv ut en summering av indata"
 
-#: builtin/apply.c:3990
+#: builtin/apply.c:4304
 msgid "instead of applying the patch, see if the patch is applicable"
 msgstr "istället för att tillämpa patchen, se om patchen kan tillämpas"
 
-#: builtin/apply.c:3992
+#: builtin/apply.c:4306
 msgid "make sure the patch is applicable to the current index"
 msgstr "se till att patchen kan tillämpas på aktuellt index"
 
-#: builtin/apply.c:3994
+#: builtin/apply.c:4308
 msgid "apply a patch without touching the working tree"
 msgstr "tillämpa en patch utan att röra arbetskatalogen"
 
-#: builtin/apply.c:3996
+#: builtin/apply.c:4310
 msgid "also apply the patch (use with --stat/--summary/--check)"
 msgstr "tillämpa också patchen (använd med --stat/--summary/--check)"
 
-#: builtin/apply.c:3998
+#: builtin/apply.c:4312
+msgid "attempt three-way merge if a patch does not apply"
+msgstr "försök en trevägssammanslagning om patchen inte kan tillämpas"
+
+#: builtin/apply.c:4314
 msgid "build a temporary index based on embedded index information"
 msgstr "bygg ett temporärt index baserat på inbyggd indexinformation"
 
-#: builtin/apply.c:4000
+#: builtin/apply.c:4316
 msgid "paths are separated with NUL character"
 msgstr "sökvägar avdelas med NUL-tecken"
 
-#: builtin/apply.c:4003
+#: builtin/apply.c:4319
 msgid "ensure at least <n> lines of context match"
 msgstr "se till att åtminstone <n> rader sammanhang är lika"
 
-#: builtin/apply.c:4004
+#: builtin/apply.c:4320
 msgid "action"
 msgstr "åtgärd"
 
-#: builtin/apply.c:4005
+#: builtin/apply.c:4321
 msgid "detect new or modified lines that have whitespace errors"
 msgstr "detektera nya eller ändrade rader som har fel i blanktecken"
 
-#: builtin/apply.c:4008 builtin/apply.c:4011
+#: builtin/apply.c:4324 builtin/apply.c:4327
 msgid "ignore changes in whitespace when finding context"
 msgstr "ignorera ändringar i blanktecken för sammanhang"
 
-#: builtin/apply.c:4014
+#: builtin/apply.c:4330
 msgid "apply the patch in reverse"
 msgstr "tillämpa patchen baklänges"
 
-#: builtin/apply.c:4016
+#: builtin/apply.c:4332
 msgid "don't expect at least one line of context"
 msgstr "förvänta inte minst en rad sammanhang"
 
-#: builtin/apply.c:4018
+#: builtin/apply.c:4334
 msgid "leave the rejected hunks in corresponding *.rej files"
 msgstr "lämna refuserade stycken i motsvarande *.rej-filer"
 
-#: builtin/apply.c:4020
+#: builtin/apply.c:4336
 msgid "allow overlapping hunks"
 msgstr "tillåt överlappande stycken"
 
-#: builtin/apply.c:4021
+#: builtin/apply.c:4337
 msgid "be verbose"
 msgstr "var pratsam"
 
-#: builtin/apply.c:4023
+#: builtin/apply.c:4339
 msgid "tolerate incorrectly detected missing new-line at the end of file"
 msgstr "tolerera felaktigt detekterade saknade nyradstecken vid filslut"
 
-#: builtin/apply.c:4026
+#: builtin/apply.c:4342
 msgid "do not trust the line counts in the hunk headers"
 msgstr "lite inte på antalet linjer i styckehuvuden"
 
-#: builtin/apply.c:4028
+#: builtin/apply.c:4344
 msgid "root"
 msgstr "rot"
 
-#: builtin/apply.c:4029
+#: builtin/apply.c:4345
 msgid "prepend <root> to all filenames"
 msgstr "lägg till <rot> i alla filnamn"
 
-#: builtin/apply.c:4050
+#: builtin/apply.c:4367
+msgid "--3way outside a repository"
+msgstr "--3way utanför arkiv"
+
+#: builtin/apply.c:4375
 msgid "--index outside a repository"
 msgstr "--index utanför arkiv"
 
-#: builtin/apply.c:4053
+#: builtin/apply.c:4378
 msgid "--cached outside a repository"
 msgstr "--cached utanför arkiv"
 
-#: builtin/apply.c:4069
+#: builtin/apply.c:4394
 #, c-format
 msgid "can't open patch '%s'"
 msgstr "kan inte öppna patchen \"%s\""
 
-#: builtin/apply.c:4083
+#: builtin/apply.c:4408
 #, c-format
 msgid "squelched %d whitespace error"
 msgid_plural "squelched %d whitespace errors"
 msgstr[0] "undertryckte %d fel i blanksteg"
 msgstr[1] "undertryckte %d fel i blanksteg"
 
-#: builtin/apply.c:4089 builtin/apply.c:4099
+#: builtin/apply.c:4414 builtin/apply.c:4424
 #, c-format
 msgid "%d line adds whitespace errors."
 msgid_plural "%d lines add whitespace errors."
@@ -1783,7 +2053,7 @@ msgstr "kunde inte skriva grenbeskrivningsmall: %s"
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Misslyckades slå upp HEAD som giltig referens"
 
-#: builtin/branch.c:788 builtin/clone.c:558
+#: builtin/branch.c:788 builtin/clone.c:561
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD hittades inte under refs/heads!"
 
@@ -1810,99 +2080,99 @@ msgstr "Behöver ett arkiv för att skapa ett paket (bundle)."
 msgid "Need a repository to unbundle."
 msgstr "Behöver ett arkiv för att packa upp ett paket (bundle)."
 
-#: builtin/checkout.c:113 builtin/checkout.c:146
+#: builtin/checkout.c:114 builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
 msgstr "sökvägen \"%s\" har inte vår version"
 
-#: builtin/checkout.c:115 builtin/checkout.c:148
+#: builtin/checkout.c:116 builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
 msgstr "sökvägen \"%s\" har inte deras version"
 
-#: builtin/checkout.c:131
+#: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
 msgstr "sökvägen \"%s\" innehåller inte alla nödvändiga versioner"
 
-#: builtin/checkout.c:175
+#: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
 msgstr "sökvägen \"%s\" innehåller inte nödvändiga versioner"
 
-#: builtin/checkout.c:192
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr "sökväg \"%s\": kan inte slå ihop"
 
-#: builtin/checkout.c:209
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr "Kunde inte lägga till sammanslagningsresultat för \"%s\""
 
-#: builtin/checkout.c:234 builtin/checkout.c:392
+#: builtin/checkout.c:235 builtin/checkout.c:393
 msgid "corrupt index file"
 msgstr "indexfilen är trasig"
 
-#: builtin/checkout.c:264 builtin/checkout.c:271
+#: builtin/checkout.c:265 builtin/checkout.c:272
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "sökvägen \"%s\" har inte slagits ihop"
 
-#: builtin/checkout.c:302 builtin/checkout.c:498 builtin/clone.c:583
+#: builtin/checkout.c:303 builtin/checkout.c:499 builtin/clone.c:586
 #: builtin/merge.c:812
 msgid "unable to write new index file"
 msgstr "kunde inte skriva ny indexfil"
 
-#: builtin/checkout.c:319 builtin/diff.c:302 builtin/merge.c:408
+#: builtin/checkout.c:320 builtin/diff.c:302 builtin/merge.c:408
 msgid "diff_setup_done failed"
 msgstr "diff_setup_done misslyckades"
 
-#: builtin/checkout.c:414
+#: builtin/checkout.c:415
 msgid "you need to resolve your current index first"
 msgstr "du måste lösa ditt befintliga index först"
 
-#: builtin/checkout.c:533
+#: builtin/checkout.c:534
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr "Kan inte skapa referenslog för \"%s\"\n"
 
-#: builtin/checkout.c:566
+#: builtin/checkout.c:567
 msgid "HEAD is now at"
 msgstr "HEAD är nu på"
 
-#: builtin/checkout.c:573
+#: builtin/checkout.c:574
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Återställ gren \"%s\"\n"
 
-#: builtin/checkout.c:576
+#: builtin/checkout.c:577
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Redan på \"%s\"\n"
 
-#: builtin/checkout.c:580
+#: builtin/checkout.c:581
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Växlade till och nollställde grenen \"%s\"\n"
 
-#: builtin/checkout.c:582
+#: builtin/checkout.c:583
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Växlade till en ny gren \"%s\"\n"
 
-#: builtin/checkout.c:584
+#: builtin/checkout.c:585
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Växlade till grenen \"%s\"\n"
 
-#: builtin/checkout.c:640
+#: builtin/checkout.c:641
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... och %d till.\n"
 
 #. The singular version
-#: builtin/checkout.c:646
+#: builtin/checkout.c:647
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -1925,7 +2195,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:664
+#: builtin/checkout.c:665
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -1940,71 +2210,71 @@ msgstr ""
 " git branch nytt_grennamn %s\n"
 "\n"
 
-#: builtin/checkout.c:694
+#: builtin/checkout.c:695
 msgid "internal error in revision walk"
 msgstr "internt fel vid genomgång av revisioner (revision walk)"
 
-#: builtin/checkout.c:698
+#: builtin/checkout.c:699
 msgid "Previous HEAD position was"
 msgstr "Tidigare position för HEAD var"
 
-#: builtin/checkout.c:724
+#: builtin/checkout.c:725 builtin/checkout.c:920
 msgid "You are on a branch yet to be born"
 msgstr "Du är på en gren som ännu inte är född"
 
 #. case (1)
-#: builtin/checkout.c:855
+#: builtin/checkout.c:856
 #, c-format
 msgid "invalid reference: %s"
 msgstr "felaktig referens: %s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:894
+#: builtin/checkout.c:895
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "referensen är inte ett träd: %s"
 
-#: builtin/checkout.c:974
+#: builtin/checkout.c:977
 msgid "-B cannot be used with -b"
 msgstr "-B kan inte användas med -b"
 
-#: builtin/checkout.c:983
+#: builtin/checkout.c:986
 msgid "--patch is incompatible with all other options"
 msgstr "--patch är inkompatibel med alla andra flaggor"
 
-#: builtin/checkout.c:986
+#: builtin/checkout.c:989
 msgid "--detach cannot be used with -b/-B/--orphan"
 msgstr "--detcah kan inte användas med -b/-B/--orphan"
 
-#: builtin/checkout.c:988
+#: builtin/checkout.c:991
 msgid "--detach cannot be used with -t"
 msgstr "--detach kan inte användas med -t"
 
-#: builtin/checkout.c:994
+#: builtin/checkout.c:997
 msgid "--track needs a branch name"
 msgstr "--track behöver ett namn på en gren"
 
-#: builtin/checkout.c:1001
+#: builtin/checkout.c:1004
 msgid "Missing branch name; try -b"
 msgstr "Grennamn saknas; försök med -b"
 
-#: builtin/checkout.c:1007
+#: builtin/checkout.c:1010
 msgid "--orphan and -b|-B are mutually exclusive"
 msgstr "--orphan och -b|-B kan inte användas samtidigt"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1012
 msgid "--orphan cannot be used with -t"
 msgstr "--orphan kan inte användas med -t"
 
-#: builtin/checkout.c:1019
+#: builtin/checkout.c:1022
 msgid "git checkout: -f and -m are incompatible"
 msgstr "git checkout: -f och -m är inkompatibla"
 
-#: builtin/checkout.c:1053
+#: builtin/checkout.c:1056
 msgid "invalid path specification"
 msgstr "felaktig sökvägsangivelse"
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid ""
 "git checkout: updating paths is incompatible with switching branches.\n"
@@ -2013,15 +2283,15 @@ msgstr ""
 "git checkout: uppdatera sökvägar är inkompatibelt med att växla gren.\n"
 "Ville du checka ut \"%s\" som inte kan lösas som en sammanslaning?"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1066
 msgid "git checkout: updating paths is incompatible with switching branches."
 msgstr "git checkout: uppdatera sökvägar är inkompatibelt med att växla gren."
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1071
 msgid "git checkout: --detach does not take a path argument"
 msgstr "git checkout: --detach tar inte en sökväg som argument"
 
-#: builtin/checkout.c:1071
+#: builtin/checkout.c:1074
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -2029,11 +2299,11 @@ msgstr ""
 "git checkout: --ours/--theirs, --force och --merge är inkompatibla när\n"
 "du checkar ut från indexet."
 
-#: builtin/checkout.c:1090
+#: builtin/checkout.c:1093
 msgid "Cannot switch branch to a non-commit."
 msgstr "Kan inte växla gren på en icke-incheckning."
 
-#: builtin/checkout.c:1093
+#: builtin/checkout.c:1096
 msgid "--ours/--theirs is incompatible with switching branches."
 msgstr "--ours/--theirs är inkompatibla med att byta gren."
 
@@ -2086,11 +2356,6 @@ msgstr "Tar inte bort %s\n"
 msgid "reference repository '%s' is not a local directory."
 msgstr "referensarkivet \"%s\" är inte en lokal katalog."
 
-#: builtin/clone.c:302
-#, c-format
-msgid "failed to open '%s'"
-msgstr "misslyckades öppna \"%s\""
-
 #: builtin/clone.c:306
 #, c-format
 msgid "failed to create directory '%s'"
@@ -2131,79 +2396,79 @@ msgstr "misslyckades kopiera filen till \"%s\""
 msgid "done.\n"
 msgstr "klart.\n"
 
-#: builtin/clone.c:440
+#: builtin/clone.c:443
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "Kunde inte hitta fjärrgrenen %s för att klona."
 
-#: builtin/clone.c:549
+#: builtin/clone.c:552
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 "HEAD hos fjärren pekar på en obefintlig referens, kan inte checka ut.\n"
 
-#: builtin/clone.c:639
+#: builtin/clone.c:642
 msgid "Too many arguments."
 msgstr "För många argument."
 
-#: builtin/clone.c:643
+#: builtin/clone.c:646
 msgid "You must specify a repository to clone."
 msgstr "Du måste ange ett arkiv att klona."
 
-#: builtin/clone.c:654
+#: builtin/clone.c:657
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "flaggorna --bare och --origin %s är inkompatibla."
 
-#: builtin/clone.c:668
+#: builtin/clone.c:671
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "arkivet \"%s\" finns inte"
 
-#: builtin/clone.c:673
+#: builtin/clone.c:676
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr "--depth ignoreras i lokala kloningar; använd file:// istället"
 
-#: builtin/clone.c:683
+#: builtin/clone.c:686
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "destinationssökvägen \"%s\" finns redan och är inte en tom katalog."
 
-#: builtin/clone.c:693
+#: builtin/clone.c:696
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "arbetsträdet \"%s\" finns redan."
 
-#: builtin/clone.c:706 builtin/clone.c:720
+#: builtin/clone.c:709 builtin/clone.c:723
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "kunde inte skapa inledande kataloger för \"%s\""
 
-#: builtin/clone.c:709
+#: builtin/clone.c:712
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr "kunde inte skapa arbetskatalogen \"%s\""
 
-#: builtin/clone.c:728
+#: builtin/clone.c:731
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Klonar till ett naket arkiv \"%s\"...\n"
 
-#: builtin/clone.c:730
+#: builtin/clone.c:733
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Klonar till \"%s\"...\n"
 
-#: builtin/clone.c:786
+#: builtin/clone.c:789
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr "Vet inte hur man klonar %s"
 
-#: builtin/clone.c:835
+#: builtin/clone.c:838
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr "Fjärrgrenen %s hittades inte i uppströmsarkivet %s"
 
-#: builtin/clone.c:842
+#: builtin/clone.c:845
 msgid "You appear to have cloned an empty repository."
 msgstr "Du verkar ha klonat ett tomt arkiv."
 
@@ -2262,93 +2527,93 @@ msgstr ""
 "\n"
 "Annars använder du \"git reset\"\n"
 
-#: builtin/commit.c:253
+#: builtin/commit.c:256
 msgid "failed to unpack HEAD tree object"
 msgstr "misslyckades packa upp HEAD:s trädobjekt"
 
-#: builtin/commit.c:295
+#: builtin/commit.c:298
 msgid "unable to create temporary index"
 msgstr "kunde inte skapa temporär indexfil"
 
-#: builtin/commit.c:301
+#: builtin/commit.c:304
 msgid "interactive add failed"
 msgstr "interaktiv tilläggning misslyckades"
 
-#: builtin/commit.c:334 builtin/commit.c:355 builtin/commit.c:405
+#: builtin/commit.c:337 builtin/commit.c:358 builtin/commit.c:408
 msgid "unable to write new_index file"
 msgstr "kunde inte skriva filen new_index"
 
-#: builtin/commit.c:386
+#: builtin/commit.c:389
 msgid "cannot do a partial commit during a merge."
 msgstr "kan inte utföra en delvis incheckning under en sammanslagning."
 
-#: builtin/commit.c:388
+#: builtin/commit.c:391
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "kan inte utföra en delvis incheckning under en cherry-pick."
 
-#: builtin/commit.c:398
+#: builtin/commit.c:401
 msgid "cannot read the index"
 msgstr "kan inte läsa indexet"
 
-#: builtin/commit.c:418
+#: builtin/commit.c:421
 msgid "unable to write temporary index file"
 msgstr "kunde inte skriva temporär indexfil"
 
-#: builtin/commit.c:493 builtin/commit.c:499
+#: builtin/commit.c:496 builtin/commit.c:502
 #, c-format
 msgid "invalid commit: %s"
 msgstr "felaktig incheckning: %s"
 
-#: builtin/commit.c:522
+#: builtin/commit.c:525
 msgid "malformed --author parameter"
 msgstr "felformad \"--author\"-flagga"
 
-#: builtin/commit.c:582
+#: builtin/commit.c:585
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "Felaktig indragningssträng: \"%s\""
 
-#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
+#: builtin/commit.c:623 builtin/commit.c:656 builtin/commit.c:970
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "kunde inte slå upp incheckningen %s"
 
-#: builtin/commit.c:632 builtin/shortlog.c:296
+#: builtin/commit.c:635 builtin/shortlog.c:296
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(läser loggmeddelande från standard in)\n"
 
-#: builtin/commit.c:634
+#: builtin/commit.c:637
 msgid "could not read log from standard input"
 msgstr "kunde inte läsa logg från standard in"
 
-#: builtin/commit.c:638
+#: builtin/commit.c:641
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "kunde inte läsa loggfilen \"%s\""
 
-#: builtin/commit.c:644
+#: builtin/commit.c:647
 msgid "commit has empty message"
 msgstr "incheckningen har ett tomt meddelande"
 
-#: builtin/commit.c:660
+#: builtin/commit.c:663
 msgid "could not read MERGE_MSG"
 msgstr "kunde inte läsa MERGE_MSG"
 
-#: builtin/commit.c:664
+#: builtin/commit.c:667
 msgid "could not read SQUASH_MSG"
 msgstr "kunde inte läsa SQUASH_MSG"
 
-#: builtin/commit.c:668
+#: builtin/commit.c:671
 #, c-format
 msgid "could not read '%s'"
 msgstr "kunde inte läsa \"%s\""
 
-#: builtin/commit.c:720
+#: builtin/commit.c:723
 msgid "could not write commit template"
 msgstr "kunde inte skriva incheckningsmall"
 
-#: builtin/commit.c:731
+#: builtin/commit.c:734
 #, c-format
 msgid ""
 "\n"
@@ -2363,7 +2628,7 @@ msgstr ""
 "\t%s\n"
 "och försöker igen.\n"
 
-#: builtin/commit.c:736
+#: builtin/commit.c:739
 #, c-format
 msgid ""
 "\n"
@@ -2378,7 +2643,7 @@ msgstr ""
 "\t%s\n"
 "och försöker igen.\n"
 
-#: builtin/commit.c:748
+#: builtin/commit.c:751
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be ignored, and an empty message aborts the commit.\n"
@@ -2386,7 +2651,7 @@ msgstr ""
 "Ange incheckningsmeddelandet för dina ändringar. Rader som inleds\n"
 "med \"#\" kommer ignoreras, och ett tomt meddelande avbryter incheckningen.\n"
 
-#: builtin/commit.c:753
+#: builtin/commit.c:756
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be kept; you may remove them yourself if you want to.\n"
@@ -2396,159 +2661,159 @@ msgstr ""
 "med \"#\" kommer behållas; du kan själv ta bort dem om du vill.\n"
 "Ett tomt meddelande avbryter incheckningen.\n"
 
-#: builtin/commit.c:766
+#: builtin/commit.c:769
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%sFörfattare: %s"
 
-#: builtin/commit.c:773
+#: builtin/commit.c:776
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%sIncheckare: %s"
 
-#: builtin/commit.c:793
+#: builtin/commit.c:796
 msgid "Cannot read index"
 msgstr "Kan inte läsa indexet"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:833
 msgid "Error building trees"
 msgstr "Fel vid byggande av träd"
 
-#: builtin/commit.c:845 builtin/tag.c:361
+#: builtin/commit.c:848 builtin/tag.c:361
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Ange meddelandet en av flaggorna -m eller -F.\n"
 
-#: builtin/commit.c:942
+#: builtin/commit.c:945
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "Hittade ingen befintlig författare med \"%s\""
 
-#: builtin/commit.c:957 builtin/commit.c:1157
+#: builtin/commit.c:960 builtin/commit.c:1160
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Ogiltigt läge för ospårade filer: \"%s\""
 
-#: builtin/commit.c:997
+#: builtin/commit.c:1000
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "Kan inte använda både --reset-author och --author"
 
-#: builtin/commit.c:1008
+#: builtin/commit.c:1011
 msgid "You have nothing to amend."
 msgstr "Du har inget att utöka."
 
-#: builtin/commit.c:1011
+#: builtin/commit.c:1014
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "Du är i mitten av en sammanslagning -- kan inte utöka."
 
-#: builtin/commit.c:1013
+#: builtin/commit.c:1016
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "Du är i mitten av en cherry-pick -- kan inte utöka."
 
-#: builtin/commit.c:1016
+#: builtin/commit.c:1019
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "Flaggorna --squash och --fixup kan inte användas samtidigt"
 
-#: builtin/commit.c:1026
+#: builtin/commit.c:1029
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Endast en av -c/-C/-F/--fixup kan användas."
 
-#: builtin/commit.c:1028
+#: builtin/commit.c:1031
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
 msgstr "Flaggan -m kan inte kombineras med -c/-C/-F/--fixup."
 
-#: builtin/commit.c:1036
+#: builtin/commit.c:1039
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author kan endast användas med -C, -c eller --amend."
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1056
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 "Endast en av --include/--only/--all/--interactive/--patch kan användas."
 
-#: builtin/commit.c:1055
+#: builtin/commit.c:1058
 msgid "No paths with --include/--only does not make sense."
 msgstr "Du måste ange sökvägar tillsammans med --include/--only."
 
-#: builtin/commit.c:1057
+#: builtin/commit.c:1060
 msgid "Clever... amending the last one with dirty index."
 msgstr "Smart... utöka den senaste med smutsigt index."
 
-#: builtin/commit.c:1059
+#: builtin/commit.c:1062
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
 msgstr "Explicita sökvägar angavs utan -i eller -o; antar --only sökvägar..."
 
-#: builtin/commit.c:1069 builtin/tag.c:577
+#: builtin/commit.c:1072 builtin/tag.c:577
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Felaktigt städningsläge %s"
 
-#: builtin/commit.c:1074
+#: builtin/commit.c:1077
 msgid "Paths with -a does not make sense."
 msgstr "Kan inte ange sökvägar med -a."
 
-#: builtin/commit.c:1257
+#: builtin/commit.c:1260
 msgid "couldn't look up newly created commit"
 msgstr "kunde inte slå upp en precis skapad incheckning"
 
-#: builtin/commit.c:1259
+#: builtin/commit.c:1262
 msgid "could not parse newly created commit"
 msgstr "kunde inte tolka en precis skapad incheckning"
 
-#: builtin/commit.c:1300
+#: builtin/commit.c:1303
 msgid "detached HEAD"
 msgstr "frånkopplad HEAD"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1305
 msgid " (root-commit)"
 msgstr " (rotincheckning)"
 
-#: builtin/commit.c:1446
+#: builtin/commit.c:1449
 msgid "could not parse HEAD commit"
 msgstr "kunde inte tolka HEAD:s incheckning"
 
-#: builtin/commit.c:1484 builtin/merge.c:509
+#: builtin/commit.c:1487 builtin/merge.c:509
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "kunde inte öppna \"%s\" för läsning"
 
-#: builtin/commit.c:1491
+#: builtin/commit.c:1494
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Trasig MERGE_HEAD-fil (%s)"
 
-#: builtin/commit.c:1498
+#: builtin/commit.c:1501
 msgid "could not read MERGE_MODE"
 msgstr "kunde inte läsa MERGE_MODE"
 
-#: builtin/commit.c:1517
+#: builtin/commit.c:1520
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "kunde inte läsa incheckningsmeddelande: %s"
 
-#: builtin/commit.c:1531
+#: builtin/commit.c:1534
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Avbryter incheckning; meddelandet inte redigerat.\n"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1539
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Avbryter på grund av tomt incheckningsmeddelande.\n"
 
-#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1554 builtin/merge.c:936 builtin/merge.c:961
 msgid "failed to write commit object"
 msgstr "kunde inte skriva incheckningsobjekt"
 
-#: builtin/commit.c:1572
+#: builtin/commit.c:1575
 msgid "cannot lock HEAD ref"
 msgstr "kunde inte låsa HEAD-referens"
 
-#: builtin/commit.c:1576
+#: builtin/commit.c:1579
 msgid "cannot update HEAD ref"
 msgstr "kunde inte uppdatera HEAD-referens"
 
-#: builtin/commit.c:1587
+#: builtin/commit.c:1590
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
@@ -2922,30 +3187,30 @@ msgstr "--[no-]exclude-standard kan inte användas för spårat innehåll."
 msgid "both --cached and trees are given."
 msgstr "både --cached och träd angavs."
 
-#: builtin/help.c:63
+#: builtin/help.c:65
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "okänt hjälpformat: %s"
 
-#: builtin/help.c:91
+#: builtin/help.c:93
 msgid "Failed to start emacsclient."
 msgstr "Misslyckades starta emacsclient."
 
-#: builtin/help.c:104
+#: builtin/help.c:106
 msgid "Failed to parse emacsclient version."
 msgstr "Kunde inte tolka emacsclient-version."
 
-#: builtin/help.c:112
+#: builtin/help.c:114
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "emacsclient version \"%d\" för gammal (< 22)."
 
-#: builtin/help.c:130 builtin/help.c:158 builtin/help.c:167 builtin/help.c:175
+#: builtin/help.c:132 builtin/help.c:160 builtin/help.c:169 builtin/help.c:177
 #, c-format
 msgid "failed to exec '%s': %s"
 msgstr "exec misslyckades för \"%s\": %s"
 
-#: builtin/help.c:215
+#: builtin/help.c:217
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -2954,7 +3219,7 @@ msgstr ""
 "\"%s\": sökväg för man-visare som ej stöds.\n"
 "Använd \"man.<verktyg>.cmd\" istället."
 
-#: builtin/help.c:227
+#: builtin/help.c:229
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -2963,34 +3228,29 @@ msgstr ""
 "\"%s\": kommando för man-visare som stöds.\n"
 "Använd \"man.<verktyg>.path\" istället."
 
-#: builtin/help.c:291
+#: builtin/help.c:299
 msgid "The most commonly used git commands are:"
 msgstr "De mest använda git-kommandona är:"
 
-#: builtin/help.c:359
+#: builtin/help.c:367
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "\"%s\": okänd man-visare."
 
-#: builtin/help.c:376
+#: builtin/help.c:384
 msgid "no man viewer handled the request"
 msgstr "ingen man-visare hanterade förfrågan"
 
-#: builtin/help.c:384
+#: builtin/help.c:392
 msgid "no info viewer handled the request"
 msgstr "ingen info-visare hanterade förfrågan"
 
-#: builtin/help.c:395
-#, c-format
-msgid "'%s': not a documentation directory."
-msgstr "\"%s\": inte en dokumentationskatalog."
-
-#: builtin/help.c:436 builtin/help.c:443
+#: builtin/help.c:447 builtin/help.c:454
 #, c-format
 msgid "usage: %s%s"
 msgstr "användning: %s%s"
 
-#: builtin/help.c:459
+#: builtin/help.c:470
 #, c-format
 msgid "`git %s' is aliased to `%s'"
 msgstr "\"git %s\" är ett alias för \"%s\""
@@ -3064,176 +3324,176 @@ msgstr "deltabasindex utanför gränsen"
 msgid "unknown object type %d"
 msgstr "okänd objekttyp %d"
 
-#: builtin/index-pack.c:531
+#: builtin/index-pack.c:530
 msgid "cannot pread pack file"
 msgstr "kan inte utföra \"pread\" på paketfil"
 
-#: builtin/index-pack.c:533
+#: builtin/index-pack.c:532
 #, c-format
 msgid "premature end of pack file, %lu byte missing"
 msgid_plural "premature end of pack file, %lu bytes missing"
 msgstr[0] "för tidigt slut på paketfilen, %lu byte saknas"
 msgstr[1] "för tidigt slut på paketfilen, %lu byte saknas"
 
-#: builtin/index-pack.c:555
+#: builtin/index-pack.c:558
 msgid "serious inflate inconsistency"
 msgstr "allvarlig inflate-inkonsekvens"
 
-#: builtin/index-pack.c:646 builtin/index-pack.c:652 builtin/index-pack.c:675
-#: builtin/index-pack.c:709 builtin/index-pack.c:718
+#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678
+#: builtin/index-pack.c:712 builtin/index-pack.c:721
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SHA1-KOLLISION UPPTÄCKT VID %s !"
 
-#: builtin/index-pack.c:649 builtin/pack-objects.c:170
+#: builtin/index-pack.c:652 builtin/pack-objects.c:170
 #: builtin/pack-objects.c:262
 #, c-format
 msgid "unable to read %s"
 msgstr "kunde inte läsa %s"
 
-#: builtin/index-pack.c:715
+#: builtin/index-pack.c:718
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "kan inte läsa befintligt objekt %s"
 
-#: builtin/index-pack.c:729
+#: builtin/index-pack.c:732
 #, c-format
 msgid "invalid blob object %s"
 msgstr "ogiltigt blob-objekt %s"
 
-#: builtin/index-pack.c:744
+#: builtin/index-pack.c:747
 #, c-format
 msgid "invalid %s"
 msgstr "ogiltigt %s"
 
-#: builtin/index-pack.c:746
+#: builtin/index-pack.c:749
 msgid "Error in object"
 msgstr "Fel i objekt"
 
-#: builtin/index-pack.c:748
+#: builtin/index-pack.c:751
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "Inte alla barnobjekt för %s kan nås"
 
-#: builtin/index-pack.c:818 builtin/index-pack.c:844
+#: builtin/index-pack.c:821 builtin/index-pack.c:847
 msgid "failed to apply delta"
 msgstr "misslyckades tillämpa delta"
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Receiving objects"
-msgstr "Tar bort objeckt"
+msgstr "Tar bort objekt"
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Indexing objects"
 msgstr "Skapar index för objekt"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1012
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "paketet är trasigt (SHA1 stämmer inte)"
 
-#: builtin/index-pack.c:1014
+#: builtin/index-pack.c:1017
 msgid "cannot fstat packfile"
 msgstr "kan inte utföra \"fstat\" på paketfil"
 
-#: builtin/index-pack.c:1017
+#: builtin/index-pack.c:1020
 msgid "pack has junk at the end"
 msgstr "paket har skräp i slutet"
 
-#: builtin/index-pack.c:1028
+#: builtin/index-pack.c:1031
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "förvirrad bortom vanvett i parse_pack_objects()"
 
-#: builtin/index-pack.c:1051
+#: builtin/index-pack.c:1054
 msgid "Resolving deltas"
 msgstr "Analyserar delta"
 
-#: builtin/index-pack.c:1102
+#: builtin/index-pack.c:1105
 msgid "confusion beyond insanity"
 msgstr "förvirrad bortom vanvett"
 
-#: builtin/index-pack.c:1121
+#: builtin/index-pack.c:1124
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "paketet har %d oanalyserat delta"
 msgstr[1] "paketet har %d oanalyserade delta"
 
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1149
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "kunde inte utföra \"deflate\" på tillagt objekt (%d)"
 
-#: builtin/index-pack.c:1225
+#: builtin/index-pack.c:1228
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "lokalt objekt %s är trasigt"
 
-#: builtin/index-pack.c:1249
+#: builtin/index-pack.c:1252
 msgid "error while closing pack file"
 msgstr "fel vid stängning av paketfil"
 
-#: builtin/index-pack.c:1262
+#: builtin/index-pack.c:1265
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr "kan inte ta skriva \"keep\"-fil \"%s\""
 
-#: builtin/index-pack.c:1270
+#: builtin/index-pack.c:1273
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr "akn inte stänga skriven \"keep\"-fil \"%s\""
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1286
 msgid "cannot store pack file"
 msgstr "kan inte spara paketfil"
 
-#: builtin/index-pack.c:1294
+#: builtin/index-pack.c:1297
 msgid "cannot store index file"
 msgstr "kan inte spara indexfil"
 
-#: builtin/index-pack.c:1395
+#: builtin/index-pack.c:1398
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Kan inte öppna befintlig paketfil \"%s\""
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1400
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "Kan inte öppna befintligt paket-idx-fil för \"%s\""
 
-#: builtin/index-pack.c:1444
+#: builtin/index-pack.c:1447
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "icke-delta: %d objekt"
 msgstr[1] "icke-delta: %d objekt"
 
-#: builtin/index-pack.c:1451
+#: builtin/index-pack.c:1454
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "kedjelängd = %d: %lu objekt"
 msgstr[1] "kedjelängd = %d: %lu objekt"
 
-#: builtin/index-pack.c:1478
+#: builtin/index-pack.c:1481
 msgid "Cannot come back to cwd"
 msgstr "Kan inte gå tillbaka till arbetskatalogen (cwd)"
 
-#: builtin/index-pack.c:1522 builtin/index-pack.c:1525
-#: builtin/index-pack.c:1537 builtin/index-pack.c:1541
+#: builtin/index-pack.c:1525 builtin/index-pack.c:1528
+#: builtin/index-pack.c:1540 builtin/index-pack.c:1544
 #, c-format
 msgid "bad %s"
 msgstr "felaktig %s"
 
-#: builtin/index-pack.c:1555
+#: builtin/index-pack.c:1558
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin kan inte användas med --stdin"
 
-#: builtin/index-pack.c:1559 builtin/index-pack.c:1569
+#: builtin/index-pack.c:1562 builtin/index-pack.c:1572
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "paketfilnamnet \"%s\" slutar inte med \".pack\""
 
-#: builtin/index-pack.c:1578
+#: builtin/index-pack.c:1581
 msgid "--verify with no packfile name given"
 msgstr "--verify angavs utan paketfilnamn"
 
@@ -3307,22 +3567,22 @@ msgstr "kopierade inte mallar från felaktig formatversion %d från \"%s\""
 msgid "insane git directory %s"
 msgstr "tokig git-katalog %s"
 
-#: builtin/init-db.c:322 builtin/init-db.c:325
+#: builtin/init-db.c:323 builtin/init-db.c:326
 #, c-format
 msgid "%s already exists"
 msgstr "%s finns redan"
 
-#: builtin/init-db.c:354
+#: builtin/init-db.c:355
 #, c-format
 msgid "unable to handle file type %d"
 msgstr "kan inte hantera filtyp %d"
 
-#: builtin/init-db.c:357
+#: builtin/init-db.c:358
 #, c-format
 msgid "unable to move %s to %s"
 msgstr "kan inte flytta %s till %s"
 
-#: builtin/init-db.c:362
+#: builtin/init-db.c:363
 #, c-format
 msgid "Could not create git link %s"
 msgstr "Kunde inte skapa gitlänk %s"
@@ -3332,38 +3592,38 @@ msgstr "Kunde inte skapa gitlänk %s"
 #. * existing" or "Initialized empty", the second " shared" or
 #. * "", and the last '%s%s' is the verbatim directory name.
 #.
-#: builtin/init-db.c:419
+#: builtin/init-db.c:420
 #, c-format
 msgid "%s%s Git repository in %s%s\n"
 msgstr "%s%s Git-arkiv i %s%s\n"
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Reinitialized existing"
 msgstr "Ominitierade befintligt"
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Initialized empty"
 msgstr "Initierade tomt"
 
-#: builtin/init-db.c:421
+#: builtin/init-db.c:422
 msgid " shared"
 msgstr " delat"
 
-#: builtin/init-db.c:440
+#: builtin/init-db.c:441
 msgid "cannot tell cwd"
 msgstr "kan inte läsa aktuell katalog (cwd)"
 
-#: builtin/init-db.c:521 builtin/init-db.c:528
+#: builtin/init-db.c:522 builtin/init-db.c:529
 #, c-format
 msgid "cannot mkdir %s"
 msgstr "kan inte skapa katalogen (mkdir) %s"
 
-#: builtin/init-db.c:532
+#: builtin/init-db.c:533
 #, c-format
 msgid "cannot chdir to %s"
 msgstr "kan inte byta katalog (chdir) till %s"
 
-#: builtin/init-db.c:554
+#: builtin/init-db.c:555
 #, c-format
 msgid ""
 "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
@@ -3372,11 +3632,11 @@ msgstr ""
 "%s (eller --work-tree=<katalog>) inte tillåtet utan att ange %s (eller --git-"
 "dir=<katalog>)"
 
-#: builtin/init-db.c:578
+#: builtin/init-db.c:579
 msgid "Cannot access current working directory"
 msgstr "Kan inte komma åt aktuell arbetskatalog"
 
-#: builtin/init-db.c:585
+#: builtin/init-db.c:586
 #, c-format
 msgid "Cannot access work tree '%s'"
 msgstr "Kan inte komma åt arbetskatalogen \"%s\""
@@ -3386,95 +3646,95 @@ msgstr "Kan inte komma åt arbetskatalogen \"%s\""
 msgid "Final output: %d %s\n"
 msgstr "Slututdata: %d %s\n"
 
-#: builtin/log.c:402 builtin/log.c:490
+#: builtin/log.c:403 builtin/log.c:494
 #, c-format
 msgid "Could not read object %s"
 msgstr "Kunde inte läsa objektet %s"
 
-#: builtin/log.c:514
+#: builtin/log.c:518
 #, c-format
 msgid "Unknown type: %d"
 msgstr "Okänd typ: %d"
 
-#: builtin/log.c:603
+#: builtin/log.c:608
 msgid "format.headers without value"
 msgstr "format.headers utan värde"
 
-#: builtin/log.c:677
+#: builtin/log.c:682
 msgid "name of output directory is too long"
 msgstr "namnet på utdatakatalogen är för långt"
 
-#: builtin/log.c:688
+#: builtin/log.c:693
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr "Kan inte öppna patchfilen %s"
 
-#: builtin/log.c:702
+#: builtin/log.c:707
 msgid "Need exactly one range."
 msgstr "Behöver precis ett intervall."
 
-#: builtin/log.c:710
+#: builtin/log.c:715
 msgid "Not a range."
 msgstr "Inte ett intervall."
 
-#: builtin/log.c:787
+#: builtin/log.c:792
 msgid "Cover letter needs email format"
 msgstr "Omslagsbrevet behöver e-postformat"
 
-#: builtin/log.c:860
+#: builtin/log.c:865
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr "tokigt in-reply-to: %s"
 
-#: builtin/log.c:933
+#: builtin/log.c:938
 msgid "Two output directories?"
 msgstr "Två utdatakataloger?"
 
-#: builtin/log.c:1154
+#: builtin/log.c:1160
 #, c-format
 msgid "bogus committer info %s"
 msgstr "felaktig incheckarinformation %s"
 
-#: builtin/log.c:1199
+#: builtin/log.c:1205
 msgid "-n and -k are mutually exclusive."
 msgstr "-n och -k kan inte användas samtidigt."
 
-#: builtin/log.c:1201
+#: builtin/log.c:1207
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr "--subject-prefix och -k kan inte användas samtidigt."
 
-#: builtin/log.c:1209
+#: builtin/log.c:1215
 msgid "--name-only does not make sense"
 msgstr "kan inte använda --name-only"
 
-#: builtin/log.c:1211
+#: builtin/log.c:1217
 msgid "--name-status does not make sense"
 msgstr "kan inte använda --name-status"
 
-#: builtin/log.c:1213
+#: builtin/log.c:1219
 msgid "--check does not make sense"
 msgstr "kan inte använda --check"
 
-#: builtin/log.c:1236
+#: builtin/log.c:1242
 msgid "standard output, or directory, which one?"
 msgstr "standard ut, eller katalog, vilken skall det vara?"
 
-#: builtin/log.c:1238
+#: builtin/log.c:1244
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "Kunde inte skapa katalogen \"%s\""
 
-#: builtin/log.c:1391
+#: builtin/log.c:1397
 msgid "Failed to create output files"
 msgstr "Misslyckades skapa utdatafiler"
 
-#: builtin/log.c:1495
+#: builtin/log.c:1501
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
 msgstr "Kunde inte hitta en spårad fjärrgren, ange <uppström> manuellt.\n"
 
-#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
+#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531
 #, c-format
 msgid "Unknown commit %s"
 msgstr "Okänd incheckning %s"
@@ -3555,10 +3815,6 @@ msgstr "git write-tree misslyckades skriva ett träd"
 msgid "failed to read the cache"
 msgstr "misslyckads läsa cachen"
 
-#: builtin/merge.c:697
-msgid "Unable to write index."
-msgstr "Kunde inte skriva indexet."
-
 #: builtin/merge.c:710
 msgid "Not handling anything other than two heads merge."
 msgstr "Hanterar inte något annat än en sammanslagning av två huvuden."
@@ -4590,31 +4846,31 @@ msgstr "Oköade ändringar efter återställning:"
 msgid "Cannot do a %s reset in the middle of a merge."
 msgstr "Kan inte utföra en %s återställning mitt i en sammanslagning."
 
-#: builtin/reset.c:297
+#: builtin/reset.c:303
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "Kan inte tolka objektet \"%s\""
 
-#: builtin/reset.c:302
+#: builtin/reset.c:308
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch är inkompatibel med --{hard,mixed,soft}"
 
-#: builtin/reset.c:311
+#: builtin/reset.c:317
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr ""
 "--mixed rekommenderas inte med sökvägar; använd \"git reset -- <sökvägar>\"."
 
-#: builtin/reset.c:313
+#: builtin/reset.c:319
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "Kan inte göra %s återställning med sökvägar."
 
-#: builtin/reset.c:325
+#: builtin/reset.c:331
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr "%s återställning tillåts inte i ett naket arkiv"
 
-#: builtin/reset.c:341
+#: builtin/reset.c:347
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "Kunde inte återställa indexfilen till versionen \"%s\"."
@@ -4936,7 +5192,7 @@ msgstr "Visa status för arbetskatalogen"
 
 #: common-cmds.h:28
 msgid "Create, list, delete or verify a tag object signed with GPG"
-msgstr "Skapa, visa, ta bort eller verifiera ett taggobjekt signerat med GPG"
+msgstr "Skapa, visa, ta bort eller verifiera GPG-signerat taggobjekt"
 
 #: git-am.sh:50
 msgid "You need to set your committer info first"
@@ -4953,9 +5209,9 @@ msgstr ""
 #: git-am.sh:105
 #, sh-format
 msgid ""
-"When you have resolved this problem run \"$cmdline --resolved\".\n"
-"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
-"To restore the original branch and stop patching run \"$cmdline --abort\"."
+"When you have resolved this problem, run \"$cmdline --resolved\".\n"
+"If you prefer to skip this patch, run \"$cmdline --skip\" instead.\n"
+"To restore the original branch and stop patching, run \"$cmdline --abort\"."
 msgstr ""
 "När du har löst problemet kör du \"$cmdline --resolved\".\n"
 "Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n"
@@ -4971,6 +5227,10 @@ msgstr ""
 "Arkivet saknar objekt som behövs för att falla tillbaka på 3-"
 "vägssammanslagning."
 
+#: git-am.sh:139
+msgid "Using index info to reconstruct a base tree..."
+msgstr "Använder indexinfo för att åteskapa ett basträd..."
+
 #: git-am.sh:154
 msgid ""
 "Did you hand edit your patch?\n"
@@ -4984,42 +5244,50 @@ msgid "Falling back to patching base and 3-way merge..."
 msgstr ""
 "Faller tillbaka på att pacha grundversionen och trevägssammanslagning..."
 
-#: git-am.sh:275
+#: git-am.sh:179
+msgid "Failed to merge in the changes."
+msgstr "Misslyckads slå ihop ändringarna."
+
+#: git-am.sh:274
 msgid "Only one StGIT patch series can be applied at once"
 msgstr "Endast en StGIT-patchserie kan tillämpas åt gången"
 
-#: git-am.sh:362
+#: git-am.sh:361
 #, sh-format
 msgid "Patch format $patch_format is not supported."
 msgstr "Patchformatet $patch_format stöds inte."
 
-#: git-am.sh:364
+#: git-am.sh:363
 msgid "Patch format detection failed."
 msgstr "Misslyckades detektera patchformat."
 
-#: git-am.sh:418
-msgid "-d option is no longer supported.  Do not use."
-msgstr "Flaggan -d stöds inte lägre. Använd inte."
+#: git-am.sh:389
+msgid ""
+"The -b/--binary option has been a no-op for long time, and\n"
+"it will be removed. Please do not use it anymore."
+msgstr ""
+"Flaggan -b/--binary har varit utan funktion länge, och\n"
+"kommer tas bort. Vi ber dig att inte använda den längre."
 
-#: git-am.sh:481
+#: git-am.sh:477
 #, 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:486
+#: git-am.sh:482
 msgid "Please make up your mind. --skip or --abort?"
 msgstr "Bestäm dig. --skip eller --abort?"
 
-#: git-am.sh:513
+#: git-am.sh:509
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr "Lösningsoperation pågår inte, vi återupptar inte."
 
-#: git-am.sh:579
+#: git-am.sh:575
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
 msgstr "Smutsigt index: kan inte tillämpa patchar (smutsiga: $files)"
 
-#: git-am.sh:671
+#: git-am.sh:679
 #, sh-format
 msgid ""
 "Patch is empty.  Was it split wrong?\n"
@@ -5030,32 +5298,32 @@ msgstr ""
 "Om du vill hoppa över patchen kör du istället \"$cmdline --skip\".\n"
 "För att återställa originalgrenen och avbryta kör du \"$cmdline --abort\"."
 
-#: git-am.sh:708
+#: git-am.sh:706
 msgid "Patch does not have a valid e-mail address."
 msgstr "Patchen har inte någon giltig e-postadress."
 
-#: git-am.sh:755
+#: git-am.sh:753
 msgid "cannot be interactive without stdin connected to a terminal."
 msgstr ""
 "kan inte vara interaktiv om standard in inte är ansluten till en terminal."
 
-#: git-am.sh:759
+#: git-am.sh:757
 msgid "Commit Body is:"
 msgstr "Incheckningskroppen är:"
 
 #. 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:766
+#: git-am.sh:764
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr "Tillämpa? Y=ja/N=nej/E=redigera/V=visa patch/A=godta alla "
 
-#: git-am.sh:802
+#: git-am.sh:800
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr "Tillämpar: $FIRSTLINE"
 
-#: git-am.sh:823
+#: git-am.sh:821
 msgid ""
 "No changes - did you forget to use 'git add'?\n"
 "If there is nothing left to stage, chances are that something else\n"
@@ -5065,7 +5333,7 @@ msgstr ""
 "Om det inte är något kvar att köa kan det hända att något annat redan\n"
 "introducerat samma ändringar; kanske du bör hoppa över patchen."
 
-#: git-am.sh:831
+#: git-am.sh:829
 msgid ""
 "You still have unmerged paths in your index\n"
 "did you forget to use 'git add'?"
@@ -5073,16 +5341,16 @@ msgstr ""
 "Du har fortfarande sökvägar som inte slagits samman i ditt index\n"
 "glömde du använda \"git add\"?"
 
-#: git-am.sh:847
+#: git-am.sh:845
 msgid "No changes -- Patch already applied."
 msgstr "Inga ändringar -- Patchen har redan tillämpats."
 
-#: git-am.sh:857
+#: git-am.sh:855
 #, sh-format
 msgid "Patch failed at $msgnum $FIRSTLINE"
 msgstr "Patchen misslyckades vid $msgnum $FIRSTLINE"
 
-#: git-am.sh:873
+#: git-am.sh:876
 msgid "applying to an empty history"
 msgstr "tillämpar på en tom historik"
 
@@ -5285,6 +5553,126 @@ msgstr "Kan inte slå ihop flera grenar i ett tomt huvud."
 msgid "Cannot rebase onto multiple branches"
 msgstr "Kan inte utföra en \"rebase\" ovanpå flera grenar"
 
+#: git-rebase.sh:52
+msgid ""
+"When you have resolved this problem, run \"git rebase --continue\".\n"
+"If you prefer to skip this patch, run \"git rebase --skip\" instead.\n"
+"To check out the original branch and stop rebasing, run \"git rebase --abort"
+"\"."
+msgstr ""
+"När du har löst problemet kör du \"git rebase --continue\".\n"
+"Om du vill hoppa över patchen kör du istället \"git rebase --skip\".\n"
+"För att återställa originalgrenen och avbryta kör du \"git rebase --abort\"."
+
+#: git-rebase.sh:159
+msgid "The pre-rebase hook refused to rebase."
+msgstr "Kroken pre-rebase vägrade ombaseringen."
+
+#: git-rebase.sh:164
+msgid "It looks like git-am is in progress. Cannot rebase."
+msgstr "Det verkar som en git-am körs. Kan inte ombasera."
+
+#: git-rebase.sh:295
+msgid "The --exec option must be used with the --interactive option"
+msgstr "Flaggan --exec måste användas tillsammans med flaggan --interactive"
+
+#: git-rebase.sh:300
+msgid "No rebase in progress?"
+msgstr "Ingen ombasering pågår?"
+
+#: git-rebase.sh:313
+msgid "Cannot read HEAD"
+msgstr "Kan inte läsa HEAD"
+
+#: git-rebase.sh:316
+msgid ""
+"You must edit all merge conflicts and then\n"
+"mark them as resolved using git add"
+msgstr ""
+"Du måste redigera alla sammanslagningskonflikter och\n"
+"därefter markera dem som lösta med git add"
+
+#: git-rebase.sh:334
+#, sh-format
+msgid "Could not move back to $head_name"
+msgstr "Kunde inte flytta tillbaka till $head_name"
+
+#: git-rebase.sh:350
+#, sh-format
+msgid ""
+"It seems that there is already a $state_dir_base directory, and\n"
+"I wonder if you are in the middle of another rebase.  If that is the\n"
+"case, please try\n"
+"\t$cmd_live_rebase\n"
+"If that is not the case, please\n"
+"\t$cmd_clear_stale_rebase\n"
+"and run me again.  I am stopping in case you still have something\n"
+"valuable there."
+msgstr ""
+"Det verkar som katalogen $state_dir_base redan existerar, och\n"
+"jag undrar om du redan är mitt i en annan ombasering. Om så är\n"
+"fallet, försök\n"
+"\t$cmd_live_rebase\n"
+"Om så inte är fallet, kör\n"
+"\t$cmd_clear_stale_rebase\n"
+"och kör programmet igen. Jag avslutar ifall du fortfarande har\n"
+"något av värde där."
+
+#: git-rebase.sh:395
+#, sh-format
+msgid "invalid upstream $upstream_name"
+msgstr "ogiltig uppström $upstream_name"
+
+#: git-rebase.sh:419
+#, sh-format
+msgid "$onto_name: there are more than one merge bases"
+msgstr "$onto_name: mer än en sammanslagningsbas finns"
+
+#: git-rebase.sh:422 git-rebase.sh:426
+#, sh-format
+msgid "$onto_name: there is no merge base"
+msgstr "$onto_name: ingen sammanslagningsbas finns"
+
+#: git-rebase.sh:431
+#, sh-format
+msgid "Does not point to a valid commit: $onto_name"
+msgstr "Peka på en giltig incheckning: $onto_name"
+
+#: git-rebase.sh:454
+#, sh-format
+msgid "fatal: no such branch: $branch_name"
+msgstr "ödesdigert: ingen sådan gren: $branch_name"
+
+#: git-rebase.sh:474
+msgid "Please commit or stash them."
+msgstr "Checka in eller använd \"stash\" på dem."
+
+#: git-rebase.sh:492
+#, sh-format
+msgid "Current branch $branch_name is up to date."
+msgstr "Aktuell gren $branch_name är à jour."
+
+#: git-rebase.sh:495
+#, sh-format
+msgid "Current branch $branch_name is up to date, rebase forced."
+msgstr "Aktuell gren $branch_name är à jour, ombasering framtvingad."
+
+#: git-rebase.sh:506
+#, sh-format
+msgid "Changes from $mb to $onto:"
+msgstr "Ändringar från $mb till $onto:"
+
+#. Detach HEAD and reset the tree
+#: git-rebase.sh:515
+msgid "First, rewinding head to replay your work on top of it..."
+msgstr ""
+"Först, spolar tillbaka huvudet för att spela av ditt arbete ovanpå det..."
+
+#: git-rebase.sh:523
+#, sh-format
+msgid "Fast-forwarded $branch_name to $onto_name."
+msgstr "Snabbspolade $branch_name till $onto_name."
+
 #: git-stash.sh:51
 msgid "git stash clear with parameters is unimplemented"
 msgstr "\"git stash clear\" med parametrar har inte implementerats"
@@ -5425,27 +5813,27 @@ msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
 msgstr ""
 "Hittade ingen undermodulmappning i .gitmodules för sökvägen \"$sm_path\""
 
-#: git-submodule.sh:186
+#: git-submodule.sh:189
 #, sh-format
 msgid "Clone of '$url' into submodule path '$sm_path' failed"
 msgstr "Misslyckades klona \"$url\" till undermodulsökvägen \"$sm_path\""
 
-#: git-submodule.sh:196
+#: git-submodule.sh:201
 #, 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:285
+#: git-submodule.sh:290
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "arkiv-URL: \"$repo\" måste vara absolut eller börja med ./|../"
 
-#: git-submodule.sh:302
+#: git-submodule.sh:307
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "\"$sm_path\" finns redan i indexet"
 
-#: git-submodule.sh:306
+#: git-submodule.sh:311
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -5456,64 +5844,64 @@ msgstr ""
 "$sm_path\n"
 "Använd -f om du verkligen vill lägga till den"
 
-#: git-submodule.sh:317
+#: git-submodule.sh:322
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "Lägger till befintligt arkiv i \"$sm_path\" i indexet"
 
-#: git-submodule.sh:319
+#: git-submodule.sh:324
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "\"$sm_path\" finns redan och är inte ett giltigt git-arkiv"
 
-#: git-submodule.sh:333
+#: git-submodule.sh:338
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "Kan inte checka ut undermodulen \"$sm_path\""
 
-#: git-submodule.sh:338
+#: git-submodule.sh:343
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "Misslyckades lägga till undermodulen \"$sm_path\""
 
-#: git-submodule.sh:343
+#: git-submodule.sh:348
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "Misslyckades registrera undermodulen \"$sm_path\""
 
-#: git-submodule.sh:385
+#: git-submodule.sh:390
 #, sh-format
 msgid "Entering '$prefix$sm_path'"
 msgstr "Går in i \"$prefix$sm_path\""
 
-#: git-submodule.sh:399
+#: git-submodule.sh:404
 #, sh-format
 msgid "Stopping at '$sm_path'; script returned non-zero status."
 msgstr ""
 "Stoppar på \"$sm_path\"; skriptet returnerade en status skild från noll."
 
-#: git-submodule.sh:442
+#: git-submodule.sh:447
 #, sh-format
 msgid "No url found for submodule path '$sm_path' in .gitmodules"
 msgstr "Hittade ingen url för undermodulsökvägen \"$sm_path\" i .gitmodules"
 
-#: git-submodule.sh:451
+#: git-submodule.sh:456
 #, sh-format
 msgid "Failed to register url for submodule path '$sm_path'"
 msgstr "Misslyckades registrera url för underkatalogsökväg \"$sm_path\""
 
-#: git-submodule.sh:453
+#: git-submodule.sh:458
 #, sh-format
 msgid "Submodule '$name' ($url) registered for path '$sm_path'"
 msgstr "Undermodulen \"$name\" ($url) registrerad för sökvägen \"$sm_path\""
 
-#: git-submodule.sh:461
+#: git-submodule.sh:466
 #, sh-format
 msgid "Failed to register update mode for submodule path '$sm_path'"
 msgstr ""
 "Misslyckades registrera uppdateringsläge för undermodulsökväg \"$sm_path\""
 
-#: git-submodule.sh:560
+#: git-submodule.sh:565
 #, sh-format
 msgid ""
 "Submodule path '$sm_path' not initialized\n"
@@ -5522,97 +5910,102 @@ msgstr ""
 "Undermodulen \"$sm_path\" har inte initierats\n"
 "Kanske du vill köra \"update --init\"?"
 
-#: git-submodule.sh:573
+#: git-submodule.sh:578
 #, sh-format
 msgid "Unable to find current revision in submodule path '$sm_path'"
 msgstr "Kan inte hitta aktuell revision i undermodulsökväg \"$sm_path\""
 
-#: git-submodule.sh:592
+#: git-submodule.sh:597
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "Kan inte hämta i undermodulsökväg \"$sm_path\""
 
-#: git-submodule.sh:606
+#: git-submodule.sh:611
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
 msgstr "Kan inte ombasera \"$sha1\" i undermodulsökväg \"$sm_path\""
 
-#: git-submodule.sh:607
+#: git-submodule.sh:612
 #, sh-format
 msgid "Submodule path '$sm_path': rebased into '$sha1'"
 msgstr "Undermodulsökvägen \"$sm_path\": ombaserade in i \"$sha1\""
 
-#: git-submodule.sh:612
+#: git-submodule.sh:617
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
 msgstr "Kan inte slå ihop \"$sha1\" i undermodulsökvägen \"$sm_path\""
 
-#: git-submodule.sh:613
+#: git-submodule.sh:618
 #, sh-format
 msgid "Submodule path '$sm_path': merged in '$sha1'"
 msgstr "Undermodulsökvägen \"$sm_path\": sammanslagen i \"$sha1\""
 
-#: git-submodule.sh:618
+#: git-submodule.sh:623
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
 msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$sm_path\""
 
-#: git-submodule.sh:619
+#: git-submodule.sh:624
 #, sh-format
 msgid "Submodule path '$sm_path': checked out '$sha1'"
 msgstr "Undermodulsökvägen \"$sm_path\": checkade ut \"$sha1\""
 
-#: git-submodule.sh:641 git-submodule.sh:964
+#: git-submodule.sh:646 git-submodule.sh:969
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr "Misslyckades rekursera in i undermodulsökvägen \"$sm_path\""
 
-#: git-submodule.sh:749
-msgid "--cached cannot be used with --files"
-msgstr "--cached kan inte användas med --files"
+#: git-submodule.sh:754
+msgid "The --cached option cannot be used with the --files option"
+msgstr "Flaggan --cached kan inte användas med flaggan --files"
 
 #. unexpected type
-#: git-submodule.sh:789
+#: git-submodule.sh:794
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "oväntat läge $mod_dst"
 
-#: git-submodule.sh:807
+#: git-submodule.sh:812
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_src"
 msgstr "  Varning: $name innehåller inte incheckning $sha1_src"
 
-#: git-submodule.sh:810
+#: git-submodule.sh:815
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_dst"
 msgstr "  Varning: $name innehåller inte incheckning $sha1_dst"
 
-#: git-submodule.sh:813
+#: git-submodule.sh:818
 #, sh-format
 msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr "  Varning: $name innehåller inte incheckningar $sha1_src och $sha1_dst"
 
-#: git-submodule.sh:838
+#: git-submodule.sh:843
 msgid "blob"
 msgstr "blob"
 
-#: git-submodule.sh:839
-msgid "submodule"
-msgstr "undermodul"
-
-#: git-submodule.sh:876
+#: git-submodule.sh:881
 msgid "# Submodules changed but not updated:"
 msgstr "# Undermoduler ändrade men inte uppdaterade:"
 
-#: git-submodule.sh:878
+#: git-submodule.sh:883
 msgid "# Submodule changes to be committed:"
 msgstr "# Undermodulers ändringar att checka in:"
 
-#: git-submodule.sh:1022
+#: git-submodule.sh:1027
 #, sh-format
 msgid "Synchronizing submodule url for '$name'"
 msgstr "Synkroniserar undermodul-url för \"$name\""
 
+#~ msgid "%s: has been deleted/renamed"
+#~ msgstr "%s: har tagits bort/ändrat namn"
+
+#~ msgid "'%s': not a documentation directory."
+#~ msgstr "\"%s\": inte en dokumentationskatalog."
+
+#~ msgid "-d option is no longer supported.  Do not use."
+#~ msgstr "Flaggan -d stöds inte lägre. Använd inte."
+
 #~ msgid "cherry-pick"
 #~ msgstr "cherry-pick"
 
index 9c8c6fe174e0240806e11b011b9121c7ce713460..f2c77ec33f54ef0d92c5f6b0d5595dfd412aa4db 100644 (file)
--- a/po/vi.po
+++ b/po/vi.po
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git-1.7.11.1-107-g72601\n"
+"Project-Id-Version: git-1.7.12-rc1-18-ge0453\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-07-03 10:23+0800\n"
-"PO-Revision-Date: 2012-07-03 14:21+0700\n"
+"POT-Creation-Date: 2012-08-06 23:47+0800\n"
+"PO-Revision-Date: 2012-08-07 07:11+0700\n"
 "Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
 "Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
 "MIME-Version: 1.0\n"
@@ -53,7 +53,7 @@ msgid "unrecognized header: %s%s (%d)"
 msgstr "phần đầu (header) không được thừa nhận: %s%s (%d)"
 
 #: bundle.c:89
-#: builtin/commit.c:696
+#: builtin/commit.c:699
 #, c-format
 msgid "could not open '%s'"
 msgstr "không thể mở '%s'"
@@ -66,9 +66,9 @@ msgstr "Khó chứa thiếu những lần chuyển giao (commit) cần trước
 #: sequencer.c:550
 #: sequencer.c:982
 #: builtin/log.c:290
-#: builtin/log.c:721
-#: builtin/log.c:1310
-#: builtin/log.c:1529
+#: builtin/log.c:726
+#: builtin/log.c:1316
+#: builtin/log.c:1535
 #: builtin/merge.c:347
 #: builtin/shortlog.c:181
 msgid "revision walk setup failed"
@@ -97,7 +97,7 @@ msgid "rev-list died"
 msgstr "rev-list bị chết"
 
 #: bundle.c:300
-#: builtin/log.c:1206
+#: builtin/log.c:1212
 #: builtin/shortlog.c:284
 #, c-format
 msgid "unrecognized argument: %s"
@@ -246,8 +246,8 @@ msgstr ""
 "%s"
 
 #: diff.c:1400
-msgid " 0 files changed\n"
-msgstr " 0 tập tin nào bị thay đổi\n"
+msgid " 0 files changed"
+msgstr " 0 có tập tin nào bị sửa đổi"
 
 #: diff.c:1404
 #, c-format
@@ -270,7 +270,7 @@ msgid_plural ", %d deletions(-)"
 msgstr[0] ", %d bị xóa(-)"
 msgstr[1] ", %d bị xóa(-)"
 
-#: diff.c:3478
+#: diff.c:3461
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -306,16 +306,16 @@ msgstr "'%s': %s"
 msgid "'%s': short read %s"
 msgstr "'%s': đọc ngắn %s"
 
-#: help.c:208
+#: help.c:212
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "các lệnh git sẵn sàng để dùng trong '%s'"
 
-#: help.c:215
+#: help.c:219
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "các lệnh git sẵn sàng để dùng từ một nơi khác trong $PATH của bạn"
 
-#: help.c:271
+#: help.c:275
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -324,11 +324,11 @@ msgstr ""
 "'%s' trông như là một lệnh git, nhưng chúng tôi không\n"
 "thể thực thi nó. Có lẽ là lệnh git-%s đã bị hỏng?"
 
-#: help.c:328
+#: help.c:332
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Ối chà. Hệ thống của bạn báo rằng chẳng có lệnh Git nào cả."
 
-#: help.c:350
+#: help.c:354
 #, c-format
 msgid ""
 "WARNING: You called a Git command named '%s', which does not exist.\n"
@@ -337,17 +337,17 @@ msgstr ""
 "CẢNH BÁO: Bạn đã gọi lệnh Git có tên '%s', mà nó lại không sẵn có.\n"
 "Giả định rằng ý bạn là '%s'"
 
-#: help.c:355
+#: help.c:359
 #, c-format
 msgid "in %0.1f seconds automatically..."
 msgstr "trong %0.1f giây một cách tự động..."
 
-#: help.c:362
+#: help.c:366
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: '%s' không phải là một lệnh của git. Xem thêm 'git --help'."
 
-#: help.c:366
+#: help.c:370
 msgid ""
 "\n"
 "Did you mean this?"
@@ -361,42 +361,297 @@ msgstr[1] ""
 "\n"
 "Có phải ý bạn là một trong số những cái này không?"
 
-#: parse-options.c:493
+#: merge-recursive.c:190
+#, c-format
+msgid "(bad commit)\n"
+msgstr "(commit sai)\n"
+
+#: merge-recursive.c:206
+#, c-format
+msgid "addinfo_cache failed for path '%s'"
+msgstr "addinfo_cache gặp lỗi đối với đường dẫn '%s'"
+
+#: merge-recursive.c:268
+msgid "error building trees"
+msgstr "gặp lỗi khi xây dựng cây"
+
+#: merge-recursive.c:497
+msgid "diff setup failed"
+msgstr "cài đặt diff gặp lỗi"
+
+#: merge-recursive.c:627
+msgid "merge-recursive: disk full?"
+msgstr "merge-recursive: đĩa bị đầy?"
+
+#: merge-recursive.c:690
+#, c-format
+msgid "failed to create path '%s'%s"
+msgstr "gặp lỗi khi tạo đường dẫn '%s'%s"
+
+#: merge-recursive.c:701
+#, c-format
+msgid "Removing %s to make room for subdirectory\n"
+msgstr "Gỡ bỏ %s để tạo chỗ (room) cho thư mục con\n"
+
+#. something else exists
+#. .. but not some other error (who really cares what?)
+#: merge-recursive.c:715
+#: merge-recursive.c:736
+msgid ": perhaps a D/F conflict?"
+msgstr ": có lẽ là một xung đột D/F?"
+
+#: merge-recursive.c:726
+#, c-format
+msgid "refusing to lose untracked file at '%s'"
+msgstr "từ chối đóng tập tin không được theo vết tại '%s'"
+
+#: merge-recursive.c:766
+#, c-format
+msgid "cannot read object %s '%s'"
+msgstr "không thể đọc đối tượng %s '%s'"
+
+#: merge-recursive.c:768
+#, c-format
+msgid "blob expected for %s '%s'"
+msgstr "đối tượng blob được mong đợi cho %s '%s'"
+
+#: merge-recursive.c:791
+#: builtin/clone.c:302
+#, c-format
+msgid "failed to open '%s'"
+msgstr "gặp lỗi khi mở '%s'"
+
+#: merge-recursive.c:799
+#, c-format
+msgid "failed to symlink '%s'"
+msgstr "gặp lỗi khi tạo liên kết tượng trưng symlink '%s'"
+
+#: merge-recursive.c:802
+#, c-format
+msgid "do not know what to do with %06o %s '%s'"
+msgstr "không hiểu phải làm gì với %06o %s '%s'"
+
+#: merge-recursive.c:939
+msgid "Failed to execute internal merge"
+msgstr "Gặp lỗi khi thực hiện trộn nội bộ"
+
+#: merge-recursive.c:943
+#, c-format
+msgid "Unable to add %s to database"
+msgstr "Không thể thêm %s vào cơ sở dữ liệu"
+
+#: merge-recursive.c:959
+msgid "unsupported object type in the tree"
+msgstr "kiểu đối tượng không được hỗ trợ trong cây (tree)"
+
+#: merge-recursive.c:1038
+#: merge-recursive.c:1052
+#, c-format
+msgid "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left in tree."
+msgstr "XUNG ĐỘT (%s/xóa): %s bị xóa trong %s và %s trong %s. Phiên bản %s của %s còn lại trong cây (tree)."
+
+#: merge-recursive.c:1044
+#: merge-recursive.c:1057
+#, c-format
+msgid "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left in tree at %s."
+msgstr "XUNG ĐỘT (%s/xóa): %s bị xóa trong %s và %s trong %s. Phiên bản %s của %s còn lại trong cây (tree) tại %s."
+
+#: merge-recursive.c:1098
+msgid "rename"
+msgstr "đổi tên"
+
+#: merge-recursive.c:1098
+msgid "renamed"
+msgstr "đã đổi tên"
+
+#: merge-recursive.c:1154
+#, c-format
+msgid "%s is a directory in %s adding as %s instead"
+msgstr "%s là một thư mục trong %s thay vào đó thêm vào như là %s"
+
+#: merge-recursive.c:1176
+#, c-format
+msgid "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s\"->\"%s\" in \"%s\"%s"
+msgstr "XUNG ĐỘT (đổi tên/đổi tên): Đổi tên \"%s\"->\"%s\" trong nhánh \"%s\" đổi tên \"%s\"->\"%s\" trong \"%s\"%s"
+
+#: merge-recursive.c:1181
+msgid " (left unresolved)"
+msgstr " (cần giải quyết)"
+
+#: merge-recursive.c:1235
+#, c-format
+msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
+msgstr "XUNG ĐỘT (đổi tên/đổi tên): Đổi tên %s->%s trong %s. Đổi tên %s->%s trong %s"
+
+#: merge-recursive.c:1265
+#, c-format
+msgid "Renaming %s to %s and %s to %s instead"
+msgstr "Đang đổi tên %s thành %s thay vì %s thành %s"
+
+#: merge-recursive.c:1464
+#, c-format
+msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
+msgstr "XUNG ĐỘT (đổi tên/thêm): Đổi tên %s->%s trong %s. %s được thêm vào trong %s"
+
+#: merge-recursive.c:1474
+#, c-format
+msgid "Adding merged %s"
+msgstr "Thêm hòa trộn %s"
+
+#: merge-recursive.c:1479
+#: merge-recursive.c:1677
+#, c-format
+msgid "Adding as %s instead"
+msgstr "Thay vào đó thêm vào %s"
+
+#: merge-recursive.c:1530
+#, c-format
+msgid "cannot read object %s"
+msgstr "không thể đọc đối tượng %s"
+
+#: merge-recursive.c:1533
+#, c-format
+msgid "object %s is not a blob"
+msgstr "đối tượng %s không phải là một blob"
+
+#: merge-recursive.c:1581
+msgid "modify"
+msgstr "sửa đổi"
+
+#: merge-recursive.c:1581
+msgid "modified"
+msgstr "đã sửa"
+
+#: merge-recursive.c:1591
+msgid "content"
+msgstr "nội dung"
+
+#: merge-recursive.c:1598
+msgid "add/add"
+msgstr "thêm/thêm"
+
+#: merge-recursive.c:1632
+#, c-format
+msgid "Skipped %s (merged same as existing)"
+msgstr "Đã bỏ qua %s (đã sẵn có lần hòa trộn này)"
+
+#: merge-recursive.c:1646
+#, c-format
+msgid "Auto-merging %s"
+msgstr "Tự-động-hòa-trộn %s"
+
+#: merge-recursive.c:1650
+#: git-submodule.sh:844
+msgid "submodule"
+msgstr "mô-đun con"
+
+#: merge-recursive.c:1651
+#, c-format
+msgid "CONFLICT (%s): Merge conflict in %s"
+msgstr "XUNG ĐỘT (%s): Xung đột hòa trộn trong %s"
+
+#: merge-recursive.c:1741
+#, c-format
+msgid "Removing %s"
+msgstr "Đang xóa %s"
+
+#: merge-recursive.c:1766
+msgid "file/directory"
+msgstr "tập-tin/thư-mục"
+
+#: merge-recursive.c:1772
+msgid "directory/file"
+msgstr "thư-mục/tập tin"
+
+#: merge-recursive.c:1777
+#, c-format
+msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
+msgstr "XUNG ĐỘT (%s): Ở đây không có thư mục nào có tên %s trong %s. Thêm %s như là %s"
+
+#: merge-recursive.c:1787
+#, c-format
+msgid "Adding %s"
+msgstr "Đang thêm \"%s\""
+
+#: merge-recursive.c:1804
+msgid "Fatal merge failure, shouldn't happen."
+msgstr "Việc hòa trộn hỏng nghiêm trọng, không nên để xảy ra."
+
+#: merge-recursive.c:1823
+msgid "Already up-to-date!"
+msgstr "Đã cập nhật rồi!"
+
+#: merge-recursive.c:1832
+#, c-format
+msgid "merging of trees %s and %s failed"
+msgstr "hòa trộn cây (tree) %s và %s gặp lỗi"
+
+#: merge-recursive.c:1862
+#, c-format
+msgid "Unprocessed path??? %s"
+msgstr "Đường dẫn chưa được xử lý??? %s"
+
+#: merge-recursive.c:1907
+msgid "Merging:"
+msgstr "Đang trộn:"
+
+#: merge-recursive.c:1920
+#, c-format
+msgid "found %u common ancestor:"
+msgid_plural "found %u common ancestors:"
+msgstr[0] "tìm thấy %u tổ tiên chung:"
+msgstr[1] "tìm thấy %u tổ tiên chung:"
+
+#: merge-recursive.c:1957
+msgid "merge returned no commit"
+msgstr "hòa trộn không trả về lần chuyển giao (commit) nào"
+
+#: merge-recursive.c:2014
+#, c-format
+msgid "Could not parse object '%s'"
+msgstr "Không thể phân tích đối tượng '%s'"
+
+#: merge-recursive.c:2026
+#: builtin/merge.c:697
+msgid "Unable to write index."
+msgstr "Không thể ghi bảng mục lục"
+
+#: parse-options.c:494
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:511
+#: parse-options.c:512
 #, c-format
 msgid "usage: %s"
 msgstr "cách sử dụng: %s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:515
+#: parse-options.c:516
 #, c-format
 msgid "   or: %s"
 msgstr "   hoặc: %s"
 
-#: parse-options.c:518
+#: parse-options.c:519
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: remote.c:1629
+#: remote.c:1632
 #, 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] "Nhánh của bạn là đầu của '%s' bởi %d lần chuyển giao (commit).\n"
 msgstr[1] "Nhánh của bạn là đầu của '%s' bởi %d lần chuyển giao (commit).\n"
 
-#: remote.c:1635
+#: remote.c:1638
 #, 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] "Nhánh của bạn thì ở đằng sau '%s' bởi %d lần chuyển giao (commit), và có thể được fast-forward.\n"
 msgstr[1] "Nhánh của bạn thì ở đằng sau '%s' bởi %d lần chuyển giao (commit), và có thể được fast-forward.\n"
 
-#: remote.c:1643
+#: remote.c:1646
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -632,7 +887,7 @@ msgid "cannot abort from a branch yet to be born"
 msgstr "không thể hủy bỏ từ một nhánh mà nó còn chưa được tạo ra"
 
 #: sequencer.c:805
-#: builtin/apply.c:3697
+#: builtin/apply.c:3988
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "không thể mở %s: %s"
@@ -664,21 +919,21 @@ msgstr "Không thể revert một lần chuyển giao (commit) khởi tạo"
 msgid "Can't cherry-pick into empty head"
 msgstr "Không thể cherry-pick vào một đầu (head) trống rỗng"
 
-#: sha1_name.c:864
+#: sha1_name.c:1044
 msgid "HEAD does not point to a branch"
 msgstr "HEAD không chỉ đến một nhánh nào cả"
 
-#: sha1_name.c:867
+#: sha1_name.c:1047
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "Không có nhánh nào như thế: '%s'"
 
-#: sha1_name.c:869
+#: sha1_name.c:1049
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "Không có dòng ngược (upstream) được cấu hình cho nhánh '%s'"
 
-#: sha1_name.c:872
+#: sha1_name.c:1052
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "Nhánh dòng ngược (upstream) '%s' không được lưu lại như là một nhánh 'remote-tracking'"
@@ -692,339 +947,339 @@ msgstr "không tìm thấy người dùng hiện tại trong tập tin passwd: %
 msgid "no such user"
 msgstr "không có người dùng như vậy"
 
-#: wt-status.c:141
+#: wt-status.c:140
 msgid "Unmerged paths:"
 msgstr "Những đường dẫn chưa được hòa trộn:"
 
-#: wt-status.c:168
-#: wt-status.c:195
+#: wt-status.c:167
+#: wt-status.c:194
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (sử dụng \"git reset %s <tập-tin>...\" để bỏ một stage (trạng thái))"
 
-#: wt-status.c:170
-#: wt-status.c:197
+#: wt-status.c:169
+#: wt-status.c:196
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (sử dụng \"git rm --cached <tập-tin>...\" để bỏ trạng thái (stage))"
 
-#: wt-status.c:174
+#: wt-status.c:173
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (sử dụng \"git add <tập-tin>...\" để đánh dấu là cần giải quyết)"
 
-#: wt-status.c:176
-#: wt-status.c:180
+#: wt-status.c:175
+#: wt-status.c:179
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr "  (sử dụng \"git add/rm <tập-tin>...\" như là một cách  thích hợp để đánh dấu là cần được giải quyết)"
 
-#: wt-status.c:178
+#: wt-status.c:177
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (sử dụng \"git rm <tập-tin>...\" để đánh dấu là cần giải quyết)"
 
-#: wt-status.c:189
+#: wt-status.c:188
 msgid "Changes to be committed:"
 msgstr "Những thay đổi sẽ được chuyển giao:"
 
-#: wt-status.c:207
+#: wt-status.c:206
 msgid "Changes not staged for commit:"
 msgstr "Các thay đổi không được đặt trạng thái (stage) cho lần chuyển giao (commit):"
 
-#: wt-status.c:211
+#: wt-status.c:210
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr "  (sử dụng \"git add <tập-tin>...\" để cập nhật những gì cần chuyển giao (commit))"
 
-#: wt-status.c:213
+#: wt-status.c:212
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr "  (sử dụng \"git add/rm <tập_tin>...\" để cập nhật những gì sẽ được chuyển giao)"
 
-#: wt-status.c:214
+#: wt-status.c:213
 msgid "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr "  (sử dụng \"git checkout -- <tập_tin>...\" để loại bỏ những thay đổi trong thư mục làm việc)"
 
-#: wt-status.c:216
+#: wt-status.c:215
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr "  (chuyển giao (commit) hoặc là loại bỏ các nội dung không-bị-theo-vết hay đã bị chỉnh sửa trong mô-đun-con)"
 
-#: wt-status.c:225
+#: wt-status.c:224
 #, c-format
 msgid "%s files:"
 msgstr "%s tệp tin:"
 
-#: wt-status.c:228
+#: wt-status.c:227
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr "  (sử dụng \"git %s <tập-tin>...\" để bao gồm thêm vào những gì cần chuyển giao (commit))"
 
-#: wt-status.c:245
+#: wt-status.c:244
 msgid "bug"
 msgstr "lỗi"
 
-#: wt-status.c:250
+#: wt-status.c:249
 msgid "both deleted:"
 msgstr "bị xóa bởi cả hai:"
 
-#: wt-status.c:251
+#: wt-status.c:250
 msgid "added by us:"
 msgstr "được thêm vào bởi chúng tôi:"
 
-#: wt-status.c:252
+#: wt-status.c:251
 msgid "deleted by them:"
 msgstr "bị xóa đi bởi họ:"
 
-#: wt-status.c:253
+#: wt-status.c:252
 msgid "added by them:"
 msgstr "được thêm vào bởi họ:"
 
-#: wt-status.c:254
+#: wt-status.c:253
 msgid "deleted by us:"
 msgstr "bị xóa bởi chúng tôi:"
 
-#: wt-status.c:255
+#: wt-status.c:254
 msgid "both added:"
 msgstr "được thêm vào bởi cả hai:"
 
-#: wt-status.c:256
+#: wt-status.c:255
 msgid "both modified:"
 msgstr "bị sửa bởi cả hai:"
 
-#: wt-status.c:286
+#: wt-status.c:285
 msgid "new commits, "
 msgstr " lần chuyển giao (commit) mới, "
 
-#: wt-status.c:288
+#: wt-status.c:287
 msgid "modified content, "
 msgstr "nội dung được sửa đổi,"
 
-#: wt-status.c:290
+#: wt-status.c:289
 msgid "untracked content, "
 msgstr "nội dung chưa được theo dõi"
 
-#: wt-status.c:304
+#: wt-status.c:303
 #, c-format
 msgid "new file:   %s"
 msgstr "tập tin mới:   %s"
 
-#: wt-status.c:307
+#: wt-status.c:306
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "đã sao chép:     %s -> %s"
 
-#: wt-status.c:310
+#: wt-status.c:309
 #, c-format
 msgid "deleted:    %s"
 msgstr "bị xóa:    %s"
 
-#: wt-status.c:313
+#: wt-status.c:312
 #, c-format
 msgid "modified:   %s"
 msgstr "bị sửa đổi:   %s"
 
-#: wt-status.c:316
+#: wt-status.c:315
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "đã đổi tên:    %s -> %s"
 
-#: wt-status.c:319
+#: wt-status.c:318
 #, c-format
 msgid "typechange: %s"
 msgstr "đổi-kiểu: %s"
 
-#: wt-status.c:322
+#: wt-status.c:321
 #, c-format
 msgid "unknown:    %s"
 msgstr "không rõ:    %s"
 
-#: wt-status.c:325
+#: wt-status.c:324
 #, c-format
 msgid "unmerged:   %s"
 msgstr "chưa hòa trộn:   %s"
 
-#: wt-status.c:328
+#: wt-status.c:327
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr "lỗi: không lấy được trạng thái lệnh diff %c"
 
-#: wt-status.c:786
+#: wt-status.c:785
 msgid "You have unmerged paths."
 msgstr "Bạn có những đường dẫn chưa được hòa trộn."
 
-#: wt-status.c:789
-#: wt-status.c:913
+#: wt-status.c:788
+#: wt-status.c:912
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (sửa các xung đột sau đó chạy \"git commit\")"
 
-#: wt-status.c:792
+#: wt-status.c:791
 msgid "All conflicts fixed but you are still merging."
 msgstr "Tất cả các xung đột đã được giải quyết nhưng bạn vẫn đang hòa trộn."
 
-#: wt-status.c:795
+#: wt-status.c:794
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (sử dụng \"git commit\" để hoàn tất việc hòa trộn)"
 
-#: wt-status.c:805
+#: wt-status.c:804
 msgid "You are in the middle of an am session."
 msgstr "Bạn đang ở giữa của một phiên 'am'."
 
-#: wt-status.c:808
+#: wt-status.c:807
 msgid "The current patch is empty."
 msgstr "Miếng vá hiện tại bị trống rỗng."
 
-#: wt-status.c:812
+#: wt-status.c:811
 msgid "  (fix conflicts and then run \"git am --resolved\")"
 msgstr "  (sửa các xung đột và sau đó chạy lệnh \"git am --resolved\")"
 
-#: wt-status.c:814
+#: wt-status.c:813
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (sử dụng \"git am --skip\" để bỏ qua lần vá này)"
 
-#: wt-status.c:816
+#: wt-status.c:815
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (sử dụng \"git am --abort\" để phục hồi lại nhánh nguyên thủy)"
 
-#: wt-status.c:874
-#: wt-status.c:884
+#: wt-status.c:873
+#: wt-status.c:883
 msgid "You are currently rebasing."
 msgstr "Bạn hiện nay đang thực hiện việc rebase (tái cấu trúc)."
 
-#: wt-status.c:877
+#: wt-status.c:876
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (sửa các xung đột và sau đó chạy lệnh \"git rebase --continue\")"
 
-#: wt-status.c:879
+#: wt-status.c:878
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (sử dụng \"git rebase --skip\" để bỏ qua lần vá này)"
 
-#: wt-status.c:881
+#: wt-status.c:880
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (sử dụng \"git rebase --abort\" để check-out nhánh nguyên thủy)"
 
-#: wt-status.c:887
+#: wt-status.c:886
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git rebase --continue\")"
 
-#: wt-status.c:889
+#: wt-status.c:888
 msgid "You are currently splitting a commit during a rebase."
 msgstr "Bạn hiện tại đang cắt đôi một lần chuyển giao trong khi đang thực hiện việc rebase."
 
-#: wt-status.c:892
+#: wt-status.c:891
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr "  (Một khi thư mục làm việc của bạn đã gọn gàng, chạy \"git rebase --continue\")"
 
-#: wt-status.c:894
+#: wt-status.c:893
 msgid "You are currently editing a commit during a rebase."
 msgstr "Bạn hiện đang sửa một lần chuyển giao trong khi bạn thực hiện rebase."
 
-#: wt-status.c:897
+#: wt-status.c:896
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (sử dụng \"git commit --amend\" để tu bổ lần chuyển giao (commit) hiện tại)"
 
-#: wt-status.c:899
+#: wt-status.c:898
 msgid "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr "  (sử dụng \"git rebase --continue\" một khi bạn cảm thấy hài lòng về những thay đổi của mình)"
 
-#: wt-status.c:909
+#: wt-status.c:908
 msgid "You are currently cherry-picking."
 msgstr "Bạn hiện nay đang thực hiện việc cherry-pick."
 
-#: wt-status.c:916
+#: wt-status.c:915
 msgid "  (all conflicts fixed: run \"git commit\")"
 msgstr "  (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git commit\")"
 
-#: wt-status.c:925
+#: wt-status.c:924
 msgid "You are currently bisecting."
 msgstr "Bạn hiện tại đang thực hiện việc bisect (chia đôi)."
 
-#: wt-status.c:928
+#: wt-status.c:927
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (sử dụng \"git bisect reset\" để quay trở lại nhánh nguyên thủy)"
 
-#: wt-status.c:979
+#: wt-status.c:978
 msgid "On branch "
 msgstr "Trên nhánh"
 
-#: wt-status.c:986
+#: wt-status.c:985
 msgid "Not currently on any branch."
 msgstr "Hiện tại chẳng ở nhánh nào cả."
 
-#: wt-status.c:998
+#: wt-status.c:997
 msgid "Initial commit"
 msgstr "Lần chuyển giao (commit) khởi đầu"
 
-#: wt-status.c:1012
+#: wt-status.c:1011
 msgid "Untracked"
 msgstr "Không được theo vết"
 
-#: wt-status.c:1014
+#: wt-status.c:1013
 msgid "Ignored"
 msgstr "Bị bỏ qua"
 
-#: wt-status.c:1016
+#: wt-status.c:1015
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Những tập tin không bị theo vết không được liệt kê ra %s"
 
-#: wt-status.c:1018
+#: wt-status.c:1017
 msgid " (use -u option to show untracked files)"
 msgstr " (sử dụng tùy chọn -u để hiển thị các tập tin chưa được theo dõi)"
 
-#: wt-status.c:1024
+#: wt-status.c:1023
 msgid "No changes"
 msgstr "Không có thay đổi nào"
 
-#: wt-status.c:1028
+#: wt-status.c:1027
 #, c-format
 msgid "no changes added to commit%s\n"
 msgstr "không có thay đổi nào được thêm vào lần chuyển giao (commit)%s\n"
 
-#: wt-status.c:1030
+#: wt-status.c:1029
 msgid " (use \"git add\" and/or \"git commit -a\")"
 msgstr " (sử dụng \"git add\" và/hoặc \"git commit -a\")"
 
-#: wt-status.c:1032
+#: wt-status.c:1031
 #, c-format
 msgid "nothing added to commit but untracked files present%s\n"
 msgstr "không có gì được thêm vào lần chuyển giao (commit) nhưng có những tập tin không được theo dấu vết hiện diện%s\n"
 
-#: wt-status.c:1034
+#: wt-status.c:1033
 msgid " (use \"git add\" to track)"
 msgstr " (sử dụng \"git add\" để theo dõi dấu vết)"
 
-#: wt-status.c:1036
-#: wt-status.c:1039
-#: wt-status.c:1042
+#: wt-status.c:1035
+#: wt-status.c:1038
+#: wt-status.c:1041
 #, c-format
 msgid "nothing to commit%s\n"
 msgstr "không có gì để chuyển giao (commit) %s\n"
 
-#: wt-status.c:1037
+#: wt-status.c:1036
 msgid " (create/copy files and use \"git add\" to track)"
 msgstr " (tạo/sao-chép các tập tin và sử dụng \"git add\" để theo dõi dấu vết)"
 
-#: wt-status.c:1040
+#: wt-status.c:1039
 msgid " (use -u to show untracked files)"
 msgstr " (sử dụng tùy chọn -u để hiển thị các tập tin chưa được theo dõi)"
 
-#: wt-status.c:1043
+#: wt-status.c:1042
 msgid " (working directory clean)"
 msgstr " (thư mục làm việc sạch sẽ)"
 
-#: wt-status.c:1151
+#: wt-status.c:1150
 msgid "HEAD (no branch)"
 msgstr "HEAD (chưa có nhánh nào)"
 
-#: wt-status.c:1157
+#: wt-status.c:1156
 msgid "Initial commit on "
 msgstr "Lần chuyển giao (commit)  khởi tạo trên"
 
-#: wt-status.c:1172
+#: wt-status.c:1171
 msgid "behind "
 msgstr "đằng sau"
 
-#: wt-status.c:1175
-#: wt-status.c:1178
+#: wt-status.c:1174
+#: wt-status.c:1177
 msgid "ahead "
 msgstr "phía trước"
 
-#: wt-status.c:1180
+#: wt-status.c:1179
 msgid ", behind "
 msgstr ", đằng sau"
 
@@ -1034,7 +1289,7 @@ msgid "unexpected diff status %c"
 msgstr "trạng thái lệnh diff không như mong đợi %c"
 
 #: builtin/add.c:67
-#: builtin/commit.c:226
+#: builtin/commit.c:229
 msgid "updating files failed"
 msgstr "Cập nhật tập tin gặp lỗi"
 
@@ -1128,161 +1383,161 @@ msgstr "Có lẽ bạn muốn nói là 'git add .' phải không?\n"
 
 #: builtin/add.c:420
 #: builtin/clean.c:95
-#: builtin/commit.c:286
+#: builtin/commit.c:289
 #: builtin/mv.c:82
 #: builtin/rm.c:162
 msgid "index file corrupt"
 msgstr "tập tin ghi bảng mục lục bị hỏng"
 
 #: builtin/add.c:480
-#: builtin/apply.c:4108
+#: builtin/apply.c:4433
 #: builtin/mv.c:229
 #: builtin/rm.c:260
 msgid "Unable to write new index file"
 msgstr "Không thể ghi tập tin lưu bảng mục lục mới"
 
-#: builtin/apply.c:53
+#: builtin/apply.c:57
 msgid "git apply [options] [<patch>...]"
 msgstr "git apply [các-tùy-chọn] [<miếng-vá>...]"
 
-#: builtin/apply.c:106
+#: builtin/apply.c:110
 #, c-format
 msgid "unrecognized whitespace option '%s'"
 msgstr "không nhận ra tùy chọn về khoảng trắng '%s'"
 
-#: builtin/apply.c:121
+#: builtin/apply.c:125
 #, c-format
 msgid "unrecognized whitespace ignore option '%s'"
 msgstr "không nhận ra tùy chọn bỏ qua khoảng trắng '%s'"
 
-#: builtin/apply.c:815
+#: builtin/apply.c:824
 #, c-format
 msgid "Cannot prepare timestamp regexp %s"
 msgstr "Không thể chuẩn bị biểu thức chính qui dấu vết thời gian (timestamp regexp) %s"
 
-#: builtin/apply.c:824
+#: builtin/apply.c:833
 #, c-format
 msgid "regexec returned %d for input: %s"
 msgstr "thi hành biểu thức chính quy trả về %d cho kết xuất: %s"
 
-#: builtin/apply.c:905
+#: builtin/apply.c:914
 #, c-format
 msgid "unable to find filename in patch at line %d"
 msgstr "không thể tìm thấy tên tập tin trong miếng vá tại dòng %d"
 
-#: builtin/apply.c:937
+#: builtin/apply.c:946
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
 msgstr "git apply: git-diff sai - mong đợi /dev/null, đã nhận %s trên dòng %d"
 
-#: builtin/apply.c:941
+#: builtin/apply.c:950
 #, c-format
 msgid "git apply: bad git-diff - inconsistent new filename on line %d"
 msgstr "git apply: git-diff sai - tên tập tin mới mâu thuấn trên dòng %d"
 
-#: builtin/apply.c:942
+#: builtin/apply.c:951
 #, c-format
 msgid "git apply: bad git-diff - inconsistent old filename on line %d"
 msgstr "git apply: git-diff sai - tên tập tin cũ mâu thuấn trên dòng %d"
 
-#: builtin/apply.c:949
+#: builtin/apply.c:958
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null on line %d"
 msgstr "git apply: git-diff sai - mong đợi /dev/null trên dòng %d"
 
-#: builtin/apply.c:1394
+#: builtin/apply.c:1403
 #, c-format
 msgid "recount: unexpected line: %.*s"
 msgstr "chi tiết: dòng không được mong đợi: %.*s"
 
-#: builtin/apply.c:1451
+#: builtin/apply.c:1460
 #, c-format
 msgid "patch fragment without header at line %d: %.*s"
 msgstr "miếng vá phân mảnh mà không có phần đầu tại dòng %d: %.*s"
 
-#: builtin/apply.c:1468
+#: builtin/apply.c:1477
 #, c-format
 msgid "git diff header lacks filename information when removing %d leading pathname component (line %d)"
 msgid_plural "git diff header lacks filename information when removing %d leading pathname components (line %d)"
 msgstr[0] "phần đầu diff cho git  thiếu thông tin tên tập tin khi gỡ bỏ đi %d trong thành phần dẫn đầu tên của đường dẫn (dòng %d)"
 msgstr[1] "phần đầu diff cho git  thiếu thông tin tên tập tin khi gỡ bỏ đi %d trong thành phần dẫn đầu tên của đường dẫn (dòng %d)"
 
-#: builtin/apply.c:1628
+#: builtin/apply.c:1637
 msgid "new file depends on old contents"
 msgstr "tập tin mới phụ thuộc vào nội dung cũ"
 
-#: builtin/apply.c:1630
+#: builtin/apply.c:1639
 msgid "deleted file still has contents"
 msgstr "tập tin đã xóa vẫn còn nội dung"
 
-#: builtin/apply.c:1656
+#: builtin/apply.c:1665
 #, c-format
 msgid "corrupt patch at line %d"
 msgstr "miếng vá hỏng tại dòng %d"
 
-#: builtin/apply.c:1692
+#: builtin/apply.c:1701
 #, c-format
 msgid "new file %s depends on old contents"
 msgstr "tập tin mới %s phụ thuộc vào nội dung cũ"
 
-#: builtin/apply.c:1694
+#: builtin/apply.c:1703
 #, c-format
 msgid "deleted file %s still has contents"
 msgstr "tập tin đã xóa %s vẫn còn nội dung"
 
-#: builtin/apply.c:1697
+#: builtin/apply.c:1706
 #, c-format
 msgid "** warning: file %s becomes empty but is not deleted"
 msgstr "** cảnh báo: tập tin %s trở nên trống rỗng nhưng không bị xóa"
 
-#: builtin/apply.c:1843
+#: builtin/apply.c:1852
 #, c-format
 msgid "corrupt binary patch at line %d: %.*s"
 msgstr "miếng vá định dạng nhị phân sai hỏng tại dòng %d: %.*s"
 
 #. there has to be one hunk (forward hunk)
-#: builtin/apply.c:1872
+#: builtin/apply.c:1881
 #, c-format
 msgid "unrecognized binary patch at line %d"
 msgstr "miếng vá định dạng nhị phân không được nhận ra tại dòng %d"
 
-#: builtin/apply.c:1958
+#: builtin/apply.c:1967
 #, c-format
 msgid "patch with only garbage at line %d"
 msgstr "vá chỉ với 'garbage' tại dòng %d"
 
-#: builtin/apply.c:2048
+#: builtin/apply.c:2057
 #, c-format
 msgid "unable to read symlink %s"
 msgstr "không thể đọc liên kết tượng trưng %s"
 
-#: builtin/apply.c:2052
+#: builtin/apply.c:2061
 #, c-format
 msgid "unable to open or read %s"
 msgstr "không thể mở để đọc hay ghi %s"
 
-#: builtin/apply.c:2123
+#: builtin/apply.c:2132
 msgid "oops"
 msgstr "ôi?"
 
-#: builtin/apply.c:2645
+#: builtin/apply.c:2654
 #, c-format
 msgid "invalid start of line: '%c'"
 msgstr "sai khởi đầu dòng: '%c'"
 
-#: builtin/apply.c:2763
+#: builtin/apply.c:2772
 #, c-format
 msgid "Hunk #%d succeeded at %d (offset %d line)."
 msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
 msgstr[0] "Khối dữ liệu #%d thành công tại %d (offset %d dòng)."
 msgstr[1] "Khối dữ liệu #%d thành công tại %d (offset %d dòng)."
 
-#: builtin/apply.c:2775
+#: builtin/apply.c:2784
 #, c-format
 msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
 msgstr "Nội dung được giảm xuống (%ld/%ld) để áp dụng mảnh dữ liệu tại %d"
 
-#: builtin/apply.c:2781
+#: builtin/apply.c:2790
 #, c-format
 msgid ""
 "while searching for:\n"
@@ -1291,320 +1546,334 @@ msgstr ""
 "Trong khi đang tìm kiếm cho:\n"
 "%.*s"
 
-#: builtin/apply.c:2800
+#: builtin/apply.c:2809
 #, c-format
 msgid "missing binary patch data for '%s'"
 msgstr "thiếu dữ liệu của miếng vá định dạng nhị phân cho '%s'"
 
-#: builtin/apply.c:2903
+#: builtin/apply.c:2912
 #, c-format
 msgid "binary patch does not apply to '%s'"
 msgstr "miếng vá định dạng nhị phân không được áp dụng cho '%s'"
 
-#: builtin/apply.c:2909
+#: builtin/apply.c:2918
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
 msgstr "vá nhị phân cho '%s' tạo ra kết quả không chính xác (đang chờ %s, đã nhận %s)"
 
-#: builtin/apply.c:2930
+#: builtin/apply.c:2939
 #, c-format
 msgid "patch failed: %s:%ld"
 msgstr "vá gặp lỗi: %s:%ld"
 
-#: builtin/apply.c:3045
+#: builtin/apply.c:3061
 #, c-format
-msgid "patch %s has been renamed/deleted"
-msgstr "miếng vá %s đã bị xóa/đổi tên"
+msgid "cannot checkout %s"
+msgstr "không thể \"checkout\" %s"
 
-#: builtin/apply.c:3052
-#: builtin/apply.c:3069
+#: builtin/apply.c:3106
+#: builtin/apply.c:3115
+#: builtin/apply.c:3159
 #, c-format
 msgid "read of %s failed"
 msgstr "đọc %s gặp lỗi"
 
-#: builtin/apply.c:3084
-msgid "removal patch leaves file contents"
-msgstr "loại bỏ miếng vá để lại nội dung tập tin"
-
-#: builtin/apply.c:3105
+#: builtin/apply.c:3139
+#: builtin/apply.c:3361
 #, c-format
-msgid "%s: already exists in working directory"
-msgstr "%s: đã sẵn có trong thư mục đang làm việc"
+msgid "path %s has been renamed/deleted"
+msgstr "đường dẫn %s đã bị xóa/đổi tên"
 
-#: builtin/apply.c:3143
+#: builtin/apply.c:3220
+#: builtin/apply.c:3375
 #, c-format
-msgid "%s: has been deleted/renamed"
-msgstr "%s: đã được xóa/thay-tên"
+msgid "%s: does not exist in index"
+msgstr "%s: không tồn tại trong bảng mục lục"
 
-#: builtin/apply.c:3148
-#: builtin/apply.c:3179
+#: builtin/apply.c:3224
+#: builtin/apply.c:3367
+#: builtin/apply.c:3389
 #, c-format
 msgid "%s: %s"
 msgstr "%s: %s"
 
-#: builtin/apply.c:3159
-#, c-format
-msgid "%s: does not exist in index"
-msgstr "%s: không tồn tại trong bảng mục lục"
-
-#: builtin/apply.c:3173
+#: builtin/apply.c:3229
+#: builtin/apply.c:3383
 #, c-format
 msgid "%s: does not match index"
 msgstr "%s: không khớp trong mục lục"
 
-#: builtin/apply.c:3190
+#: builtin/apply.c:3331
+msgid "removal patch leaves file contents"
+msgstr "loại bỏ miếng vá để lại nội dung tập tin"
+
+#: builtin/apply.c:3400
 #, c-format
 msgid "%s: wrong type"
 msgstr "%s: sai kiểu"
 
-#: builtin/apply.c:3192
+#: builtin/apply.c:3402
 #, c-format
 msgid "%s has type %o, expected %o"
 msgstr "%s có kiểu %o, mong chờ %o"
 
-#: builtin/apply.c:3247
+#: builtin/apply.c:3503
 #, c-format
 msgid "%s: already exists in index"
 msgstr "%s: đã có từ trước trong bảng mục lục"
 
-#: builtin/apply.c:3267
+#: builtin/apply.c:3506
+#, c-format
+msgid "%s: already exists in working directory"
+msgstr "%s: đã sẵn có trong thư mục đang làm việc"
+
+#: builtin/apply.c:3526
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
 msgstr "chế độ mới (%o) của %s không khớp với chế độ cũ (%o)"
 
-#: builtin/apply.c:3272
+#: builtin/apply.c:3531
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o) of %s"
 msgstr "chế độ mới (%o) của %s không khớp với chế độ cũ (%o) của %s"
 
-#: builtin/apply.c:3280
+#: builtin/apply.c:3539
 #, c-format
 msgid "%s: patch does not apply"
 msgstr "%s: miếng vá không được áp dụng"
 
-#: builtin/apply.c:3293
+#: builtin/apply.c:3552
 #, c-format
 msgid "Checking patch %s..."
 msgstr "Đang kiểm tra miếng vá %s..."
 
-#: builtin/apply.c:3348
-#: builtin/checkout.c:212
+#: builtin/apply.c:3607
+#: builtin/checkout.c:213
 #: builtin/reset.c:158
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr "make_cache_entry gặp lỗi đối với đường dẫn '%s'"
 
-#: builtin/apply.c:3491
+#: builtin/apply.c:3750
 #, c-format
 msgid "unable to remove %s from index"
 msgstr "không thể gỡ bỏ %s từ mục lục"
 
-#: builtin/apply.c:3518
+#: builtin/apply.c:3778
 #, c-format
 msgid "corrupt patch for subproject %s"
 msgstr "miếng vá sai hỏng cho dự án con (subproject) %s"
 
-#: builtin/apply.c:3522
+#: builtin/apply.c:3782
 #, c-format
 msgid "unable to stat newly created file '%s'"
 msgstr "không thể lấy trạng thái về tập tin %s mới hơn đã được tạo"
 
-#: builtin/apply.c:3527
+#: builtin/apply.c:3787
 #, c-format
 msgid "unable to create backing store for newly created file %s"
 msgstr "không thể tạo 'backing store' cho tập tin được tạo mới hơn %s"
 
-#: builtin/apply.c:3530
+#: builtin/apply.c:3790
+#: builtin/apply.c:3898
 #, c-format
 msgid "unable to add cache entry for %s"
 msgstr "không thể thêm mục nhớ tạm cho %s"
 
-#: builtin/apply.c:3563
+#: builtin/apply.c:3823
 #, c-format
 msgid "closing file '%s'"
 msgstr "đang đóng tập tin '%s'"
 
-#: builtin/apply.c:3612
+#: builtin/apply.c:3872
 #, c-format
 msgid "unable to write file '%s' mode %o"
 msgstr "không thể ghi vào tập tin '%s' chế độ (mode) %o"
 
-#: builtin/apply.c:3668
+#: builtin/apply.c:3959
 #, c-format
 msgid "Applied patch %s cleanly."
 msgstr "Đã áp dụng miếng và %s một cách sạch sẽ."
 
-#: builtin/apply.c:3676
+#: builtin/apply.c:3967
 msgid "internal error"
 msgstr "lỗi nội bộ"
 
 #. Say this even without --verbose
-#: builtin/apply.c:3679
+#: builtin/apply.c:3970
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
 msgstr[0] "Đang áp dụng miếng vá %%s với %d lần từ chối..."
 msgstr[1] "Đang áp dụng miếng vá %%s với %d lần từ chối..."
 
-#: builtin/apply.c:3689
+#: builtin/apply.c:3980
 #, c-format
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "đang cắt cụt tên tập tin .rej thành %.*s.rej"
 
-#: builtin/apply.c:3710
+#: builtin/apply.c:4001
 #, c-format
 msgid "Hunk #%d applied cleanly."
 msgstr "Khối nhớ #%d được áp dụng gọn gàng."
 
-#: builtin/apply.c:3713
+#: builtin/apply.c:4004
 #, c-format
 msgid "Rejected hunk #%d."
 msgstr "hunk #%d bị từ chối."
 
-#: builtin/apply.c:3844
+#: builtin/apply.c:4154
 msgid "unrecognized input"
 msgstr "không thừa nhận đầu vào"
 
-#: builtin/apply.c:3855
+#: builtin/apply.c:4165
 msgid "unable to read index file"
 msgstr "không thể đọc tập tin lưu bảng mục lục"
 
-#: builtin/apply.c:3970
-#: builtin/apply.c:3973
+#: builtin/apply.c:4284
+#: builtin/apply.c:4287
 msgid "path"
 msgstr "đường-dẫn"
 
-#: builtin/apply.c:3971
+#: builtin/apply.c:4285
 msgid "don't apply changes matching the given path"
 msgstr "không áp dụng các thay đổi khớp với đường dẫn đã cho"
 
-#: builtin/apply.c:3974
+#: builtin/apply.c:4288
 msgid "apply changes matching the given path"
 msgstr "áp dụng các thay đổi khớp với đường dẫn đã cho"
 
-#: builtin/apply.c:3976
+#: builtin/apply.c:4290
 msgid "num"
 msgstr "số"
 
-#: builtin/apply.c:3977
+#: builtin/apply.c:4291
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr "gỡ bỏ <số> phần dẫn đầu (slashe) từ đường dẫn diff cổ điển"
 
-#: builtin/apply.c:3980
+#: builtin/apply.c:4294
 msgid "ignore additions made by the patch"
 msgstr "lờ đi phần phụ thêm tạo ra bởi miếng vá"
 
-#: builtin/apply.c:3982
+#: builtin/apply.c:4296
 msgid "instead of applying the patch, output diffstat for the input"
 msgstr "thay vì áp dụng một miếng vá, kết xuất kết quả từ lệnh diffstat cho đầu ra"
 
-#: builtin/apply.c:3986
+#: builtin/apply.c:4300
 msgid "shows number of added and deleted lines in decimal notation"
 msgstr "hiển thị số lượng các dòng được thêm vào và xóa đi theo ký hiệu thập phân"
 
-#: builtin/apply.c:3988
+#: builtin/apply.c:4302
 msgid "instead of applying the patch, output a summary for the input"
 msgstr "thay vì áp dụng một miếng vá, kết xuất kết quả cho đầu vào"
 
-#: builtin/apply.c:3990
+#: builtin/apply.c:4304
 msgid "instead of applying the patch, see if the patch is applicable"
 msgstr "thay vì áp dụng miếng vá, hãy xem xem miếng vá có thích hợp không"
 
-#: builtin/apply.c:3992
+#: builtin/apply.c:4306
 msgid "make sure the patch is applicable to the current index"
 msgstr "hãy chắc chắn là miếng vá thích hợp với bảng mục lục hiện hành"
 
-#: builtin/apply.c:3994
+#: builtin/apply.c:4308
 msgid "apply a patch without touching the working tree"
 msgstr "áp dụng một miếng vá mà không động chạm đến cây làm việc"
 
-#: builtin/apply.c:3996
+#: builtin/apply.c:4310
 msgid "also apply the patch (use with --stat/--summary/--check)"
 msgstr "đồng thời áp dụng miếng vá (sử dụng với tùy chọn --stat/--summary/--check)"
 
-#: builtin/apply.c:3998
+#: builtin/apply.c:4312
+msgid "attempt three-way merge if a patch does not apply"
+msgstr "thử hòa trộn kiểu three-way nếu việc vá không thể thực hiện được"
+
+#: builtin/apply.c:4314
 msgid "build a temporary index based on embedded index information"
 msgstr "xây dựng bảng mục lục tạm thời trên cơ sở thông tin bảng mục lục được nhúng"
 
-#: builtin/apply.c:4000
+#: builtin/apply.c:4316
 msgid "paths are separated with NUL character"
 msgstr "các đường dẫn bị ngăn cách bởi ký tự NULL"
 
-#: builtin/apply.c:4003
+#: builtin/apply.c:4319
 msgid "ensure at least <n> lines of context match"
 msgstr "đảm bảo rằng có ít nhất <n> dòng nội dung khớp"
 
-#: builtin/apply.c:4004
+#: builtin/apply.c:4320
 msgid "action"
 msgstr "hành động"
 
-#: builtin/apply.c:4005
+#: builtin/apply.c:4321
 msgid "detect new or modified lines that have whitespace errors"
 msgstr "tìm thấy một dòng mới hoặc bị sửa đổi mà nó có lỗi do khoảng trắng"
 
-#: builtin/apply.c:4008
-#: builtin/apply.c:4011
+#: builtin/apply.c:4324
+#: builtin/apply.c:4327
 msgid "ignore changes in whitespace when finding context"
 msgstr "lờ đi sự thay đổi do khoảng trắng khi quét nội dung"
 
-#: builtin/apply.c:4014
+#: builtin/apply.c:4330
 msgid "apply the patch in reverse"
 msgstr "áp dụng miếng vá theo chiều ngược"
 
-#: builtin/apply.c:4016
+#: builtin/apply.c:4332
 msgid "don't expect at least one line of context"
 msgstr "đừng hy vọng có ít nhất một dòng nội dung"
 
-#: builtin/apply.c:4018
+#: builtin/apply.c:4334
 msgid "leave the rejected hunks in corresponding *.rej files"
 msgstr "để lại khối dữ liệu bị từ chối trong các tập tin *.rej tương ứng"
 
-#: builtin/apply.c:4020
+#: builtin/apply.c:4336
 msgid "allow overlapping hunks"
 msgstr "cho phép chồng khối nhớ"
 
-#: builtin/apply.c:4021
+#: builtin/apply.c:4337
 msgid "be verbose"
 msgstr "chi tiết"
 
-#: builtin/apply.c:4023
+#: builtin/apply.c:4339
 msgid "tolerate incorrectly detected missing new-line at the end of file"
 msgstr "dung sai không chính xác đã tìm thấy thiếu dòng mới tại cuối tập tin"
 
-#: builtin/apply.c:4026
+#: builtin/apply.c:4342
 msgid "do not trust the line counts in the hunk headers"
 msgstr "không tin số lượng dòng trong phần đầu khối dữ liệu"
 
-#: builtin/apply.c:4028
+#: builtin/apply.c:4344
 msgid "root"
 msgstr "root"
 
-#: builtin/apply.c:4029
+#: builtin/apply.c:4345
 msgid "prepend <root> to all filenames"
 msgstr "treo thêm <root> vào tất cả các tên tập tin"
 
-#: builtin/apply.c:4050
+#: builtin/apply.c:4367
+msgid "--3way outside a repository"
+msgstr "--3way ở ngoài một kho chứa"
+
+#: builtin/apply.c:4375
 msgid "--index outside a repository"
 msgstr "--index ở ngoài một kho chứa"
 
-#: builtin/apply.c:4053
+#: builtin/apply.c:4378
 msgid "--cached outside a repository"
 msgstr "--cached ở ngoài một kho chứa"
 
-#: builtin/apply.c:4069
+#: builtin/apply.c:4394
 #, c-format
 msgid "can't open patch '%s'"
 msgstr "không thể mở miếng vá '%s'"
 
-#: builtin/apply.c:4083
+#: builtin/apply.c:4408
 #, c-format
 msgid "squelched %d whitespace error"
 msgid_plural "squelched %d whitespace errors"
 msgstr[0] "đã chấm dứt %d lỗi khoảng trắng"
 msgstr[1] "đã chấm dứt %d lỗi khoảng trắng"
 
-#: builtin/apply.c:4089
-#: builtin/apply.c:4099
+#: builtin/apply.c:4414
+#: builtin/apply.c:4424
 #, c-format
 msgid "%d line adds whitespace errors."
 msgid_plural "%d lines add whitespace errors."
@@ -1810,7 +2079,7 @@ msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Gặp lỗi khi giải quyết HEAD như là một tham chiếu (ref) hợp lệ."
 
 #: builtin/branch.c:788
-#: builtin/clone.c:558
+#: builtin/clone.c:561
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD không tìm thấy ở dưới refs/heads!"
 
@@ -1835,107 +2104,107 @@ msgstr "Cần một kho chứa để mà tạo một bundle."
 msgid "Need a repository to unbundle."
 msgstr "Cần một kho chứa để mà bung một bundle."
 
-#: builtin/checkout.c:113
-#: builtin/checkout.c:146
+#: builtin/checkout.c:114
+#: builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
 msgstr "đường dẫn '%s' không có các phiên bản của chúng ta"
 
-#: builtin/checkout.c:115
-#: builtin/checkout.c:148
+#: builtin/checkout.c:116
+#: builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
 msgstr "đường dẫn '%s' không có các phiên bản của chúng"
 
-#: builtin/checkout.c:131
+#: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
 msgstr "đường dẫn '%s' không có tất cả các phiên bản cần thiết"
 
-#: builtin/checkout.c:175
+#: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
 msgstr "đường dẫn '%s' không có các phiên bản cần thiết"
 
-#: builtin/checkout.c:192
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr "đường dẫn '%s': không thể hòa trộn"
 
-#: builtin/checkout.c:209
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr "Không thể thêm kết quả hòa trộn cho '%s'"
 
-#: builtin/checkout.c:234
-#: builtin/checkout.c:392
+#: builtin/checkout.c:235
+#: builtin/checkout.c:393
 msgid "corrupt index file"
 msgstr "tập tin ghi bảng mục lục bị hỏng"
 
-#: builtin/checkout.c:264
-#: builtin/checkout.c:271
+#: builtin/checkout.c:265
+#: builtin/checkout.c:272
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "đường dẫn '%s' không được hòa trộn"
 
-#: builtin/checkout.c:302
-#: builtin/checkout.c:498
-#: builtin/clone.c:583
+#: builtin/checkout.c:303
+#: builtin/checkout.c:499
+#: builtin/clone.c:586
 #: builtin/merge.c:812
 msgid "unable to write new index file"
 msgstr "không thể ghi tập tin lưu bảng mục lục mới"
 
-#: builtin/checkout.c:319
+#: builtin/checkout.c:320
 #: builtin/diff.c:302
 #: builtin/merge.c:408
 msgid "diff_setup_done failed"
 msgstr "diff_setup_done gặp lỗi"
 
-#: builtin/checkout.c:414
+#: builtin/checkout.c:415
 msgid "you need to resolve your current index first"
 msgstr "bạn cần phải giải quyết bảng mục lục hiện tại của bạn trước đã!"
 
-#: builtin/checkout.c:533
+#: builtin/checkout.c:534
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr "Không thể thực hiện reflog cho '%s'\n"
 
-#: builtin/checkout.c:566
+#: builtin/checkout.c:567
 msgid "HEAD is now at"
 msgstr "HEAD hiện giờ tại"
 
-#: builtin/checkout.c:573
+#: builtin/checkout.c:574
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Đặt lại nhánh '%s'\n"
 
-#: builtin/checkout.c:576
+#: builtin/checkout.c:577
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Đã sẵn sàng trên '%s'\n"
 
-#: builtin/checkout.c:580
+#: builtin/checkout.c:581
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Đã chuyển tới và reset nhánh '%s'\n"
 
-#: builtin/checkout.c:582
+#: builtin/checkout.c:583
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Đã chuyển đến nhánh mới '%s'\n"
 
-#: builtin/checkout.c:584
+#: builtin/checkout.c:585
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Đã chuyển đến nhánh '%s'\n"
 
-#: builtin/checkout.c:640
+#: builtin/checkout.c:641
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... và nhiều hơn %d.\n"
 
 #. The singular version
-#: builtin/checkout.c:646
+#: builtin/checkout.c:647
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -1958,7 +2227,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:664
+#: builtin/checkout.c:665
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -1973,71 +2242,72 @@ msgstr ""
 " git branch tên_nhánh_mới %s\n"
 "\n"
 
-#: builtin/checkout.c:694
+#: builtin/checkout.c:695
 msgid "internal error in revision walk"
 msgstr "lỗi nội bộ trong khi di chuyển qua các điểm xét lại"
 
-#: builtin/checkout.c:698
+#: builtin/checkout.c:699
 msgid "Previous HEAD position was"
 msgstr "Vị trí kế trước của HEAD là"
 
-#: builtin/checkout.c:724
+#: builtin/checkout.c:725
+#: builtin/checkout.c:920
 msgid "You are on a branch yet to be born"
 msgstr "Bạn tại nhánh mà nó chưa hề được sinh ra"
 
 #. case (1)
-#: builtin/checkout.c:855
+#: builtin/checkout.c:856
 #, c-format
 msgid "invalid reference: %s"
 msgstr "tham chiếu sai: %s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:894
+#: builtin/checkout.c:895
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "tham chiếu không phải là cây:%s"
 
-#: builtin/checkout.c:974
+#: builtin/checkout.c:977
 msgid "-B cannot be used with -b"
 msgstr "-B không thể được sử dụng với -b"
 
-#: builtin/checkout.c:983
+#: builtin/checkout.c:986
 msgid "--patch is incompatible with all other options"
 msgstr "--patch xung khắc với tất cả các tùy chọn khác"
 
-#: builtin/checkout.c:986
+#: builtin/checkout.c:989
 msgid "--detach cannot be used with -b/-B/--orphan"
 msgstr "--detach không thể được sử dụng với -b/-B/--orphan"
 
-#: builtin/checkout.c:988
+#: builtin/checkout.c:991
 msgid "--detach cannot be used with -t"
 msgstr "--detach không thể được sử dụng với tùy chọn -t"
 
-#: builtin/checkout.c:994
+#: builtin/checkout.c:997
 msgid "--track needs a branch name"
 msgstr "--track cần tên một nhánh"
 
-#: builtin/checkout.c:1001
+#: builtin/checkout.c:1004
 msgid "Missing branch name; try -b"
 msgstr "Thiếu tên nhánh; hãy thử -b"
 
-#: builtin/checkout.c:1007
+#: builtin/checkout.c:1010
 msgid "--orphan and -b|-B are mutually exclusive"
 msgstr "Tùy chọn --orphan và -b|-B loại từ lẫn nhau"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1012
 msgid "--orphan cannot be used with -t"
 msgstr "--orphan không thể được sử dụng với tùy chọn -t"
 
-#: builtin/checkout.c:1019
+#: builtin/checkout.c:1022
 msgid "git checkout: -f and -m are incompatible"
 msgstr "git checkout: -f và -m xung khắc nhau"
 
-#: builtin/checkout.c:1053
+#: builtin/checkout.c:1056
 msgid "invalid path specification"
 msgstr "đường dẫn đã cho không hợp lệ"
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid ""
 "git checkout: updating paths is incompatible with switching branches.\n"
@@ -2046,27 +2316,27 @@ msgstr ""
 "git checkout: việc cập nhật các đường dẫn là xung khắc với việc chuyển đổi các nhánh..\n"
 "Bạn đã có ý định checkout '%s' cái mà không thể được phân giải như là lần chuyển giao (commit)?"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1066
 msgid "git checkout: updating paths is incompatible with switching branches."
 msgstr "git checkout: việc cập nhật các đường dẫn là xung khắc với việc chuyển đổi các nhánh."
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1071
 msgid "git checkout: --detach does not take a path argument"
-msgstr "git checkout: --detach không nhận một đối số đường dẫn"
+msgstr "git checkout: --detach không nhận một đối số là đường dẫn"
 
-#: builtin/checkout.c:1071
+#: builtin/checkout.c:1074
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
 "git checkout: --ours/--theirs, --force và --merge là xung khắc với nhau khi\n"
-"checkout."
+"checkout bảng mục lục (index)."
 
-#: builtin/checkout.c:1090
+#: builtin/checkout.c:1093
 msgid "Cannot switch branch to a non-commit."
 msgstr "Không thể chuyển đến một non-commit."
 
-#: builtin/checkout.c:1093
+#: builtin/checkout.c:1096
 msgid "--ours/--theirs is incompatible with switching branches."
 msgstr "--ours/--theirs là xung khắc nhau khi chuyển đổi các nhánh."
 
@@ -2115,11 +2385,6 @@ msgstr "Không xóa %s\n"
 msgid "reference repository '%s' is not a local directory."
 msgstr "kho tham chiếu '%s' không phải là một thư mục nội bộ."
 
-#: builtin/clone.c:302
-#, c-format
-msgid "failed to open '%s'"
-msgstr "gặp lỗi khi mở '%s'"
-
 #: builtin/clone.c:306
 #, c-format
 msgid "failed to create directory '%s'"
@@ -2161,79 +2426,79 @@ msgstr "sao chép tệp tin tới '%s' gặp lỗi"
 msgid "done.\n"
 msgstr "hoàn tất.\n"
 
-#: builtin/clone.c:440
+#: builtin/clone.c:443
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "Không tìm thấy nhánh máy chủ %s để nhân bản (clone)."
 
-#: builtin/clone.c:549
+#: builtin/clone.c:552
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr "refers HEAD máy chủ  chỉ đến ref không tồn tại, không thể checkout.\n"
 
-#: builtin/clone.c:639
+#: builtin/clone.c:642
 msgid "Too many arguments."
 msgstr "Có quá nhiều đối số."
 
-#: builtin/clone.c:643
+#: builtin/clone.c:646
 msgid "You must specify a repository to clone."
 msgstr "Bạn phải chỉ định một kho để mà nhân bản (clone)."
 
-#: builtin/clone.c:654
+#: builtin/clone.c:657
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "tùy chọn --bare và --origin %s xung khắc nhau."
 
-#: builtin/clone.c:668
+#: builtin/clone.c:671
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "kho chứa '%s' chưa tồn tại"
 
-#: builtin/clone.c:673
+#: builtin/clone.c:676
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr "--depth bị lờ đi khi nhân bản nội bộ; hãy sử dụng file:// để thay thế."
 
-#: builtin/clone.c:683
+#: builtin/clone.c:686
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "đường dẫn đích '%s' đã có từ trước và không phải là một thư mục rỗng."
 
-#: builtin/clone.c:693
+#: builtin/clone.c:696
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "cây làm việc '%s' đã sẵn tồn tại rồi."
 
-#: builtin/clone.c:706
-#: builtin/clone.c:720
+#: builtin/clone.c:709
+#: builtin/clone.c:723
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "không thể tạo các thư mục dẫn đầu của '%s'"
 
-#: builtin/clone.c:709
+#: builtin/clone.c:712
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr "không thể tạo cây thư mục làm việc dir '%s'."
 
-#: builtin/clone.c:728
+#: builtin/clone.c:731
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Đang nhân bản thành kho chứa bare '%s'...\n"
 
-#: builtin/clone.c:730
+#: builtin/clone.c:733
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Đang nhân bản thành '%s'...\n"
 
-#: builtin/clone.c:786
+#: builtin/clone.c:789
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr "Không biết làm cách nào để nhân bản (clone) %s"
 
-#: builtin/clone.c:835
+#: builtin/clone.c:838
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr "Nhánh máy chủ %s không tìm thấy trong dòng ngược (upstream) %s"
 
-#: builtin/clone.c:842
+#: builtin/clone.c:845
 msgid "You appear to have cloned an empty repository."
 msgstr "Bạn hình như là đã nhân bản một kho trống rỗng."
 
@@ -2292,99 +2557,99 @@ msgstr ""
 "\n"
 "Nếu không, hãy thử sử dụng 'git reset'\n"
 
-#: builtin/commit.c:253
+#: builtin/commit.c:256
 msgid "failed to unpack HEAD tree object"
 msgstr "gặp lỗi khi tháo dỡ HEAD đối tượng cây"
 
-#: builtin/commit.c:295
+#: builtin/commit.c:298
 msgid "unable to create temporary index"
 msgstr "không thể tạo bảng mục lục tạm thời"
 
-#: builtin/commit.c:301
+#: builtin/commit.c:304
 msgid "interactive add failed"
 msgstr "việc thêm tương tác gặp lỗi"
 
-#: builtin/commit.c:334
-#: builtin/commit.c:355
-#: builtin/commit.c:405
+#: builtin/commit.c:337
+#: builtin/commit.c:358
+#: builtin/commit.c:408
 msgid "unable to write new_index file"
 msgstr "không thể ghi tập tin lưu bảng mục lục mới (new_index)"
 
-#: builtin/commit.c:386
+#: builtin/commit.c:389
 msgid "cannot do a partial commit during a merge."
 msgstr "không thể thực hiện việc chuyển giao (commit) cục bộ trong khi đang được hòa trộn."
 
-#: builtin/commit.c:388
+#: builtin/commit.c:391
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "không thể thực hiện việc chuyển giao (commit) bộ phận trong khi đang cherry-pick."
 
-#: builtin/commit.c:398
+#: builtin/commit.c:401
 msgid "cannot read the index"
 msgstr "không đọc được bảng mục lục"
 
-#: builtin/commit.c:418
+#: builtin/commit.c:421
 msgid "unable to write temporary index file"
 msgstr "không thể ghi tập tin lưu bảng mục lục tạm thời"
 
-#: builtin/commit.c:493
-#: builtin/commit.c:499
+#: builtin/commit.c:496
+#: builtin/commit.c:502
 #, c-format
 msgid "invalid commit: %s"
 msgstr "lần chuyển giao (commit) không hợp lệ: %s"
 
-#: builtin/commit.c:522
+#: builtin/commit.c:525
 msgid "malformed --author parameter"
 msgstr "đối số --author bị dị hình"
 
-#: builtin/commit.c:582
+#: builtin/commit.c:585
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "Chuỗi thụt lề đầu dòng dị hình: '%s'"
 
-#: builtin/commit.c:620
-#: builtin/commit.c:653
-#: builtin/commit.c:967
+#: builtin/commit.c:623
+#: builtin/commit.c:656
+#: builtin/commit.c:970
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "không thể tìm kiếm commit (lần chuyển giao) %s"
 
-#: builtin/commit.c:632
+#: builtin/commit.c:635
 #: builtin/shortlog.c:296
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(đang đọc thông điệp nhật ký từ đầu vào tiêu chuẩn)\n"
 
-#: builtin/commit.c:634
+#: builtin/commit.c:637
 msgid "could not read log from standard input"
 msgstr "không thể đọc nhật ký từ đầu vào tiêu chuẩn"
 
-#: builtin/commit.c:638
+#: builtin/commit.c:641
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "không đọc được tệp nhật ký '%s'"
 
-#: builtin/commit.c:644
+#: builtin/commit.c:647
 msgid "commit has empty message"
 msgstr "lần chuyển giao (commit) có ghi chú trống rỗng"
 
-#: builtin/commit.c:660
+#: builtin/commit.c:663
 msgid "could not read MERGE_MSG"
 msgstr "không thể đọc MERGE_MSG"
 
-#: builtin/commit.c:664
+#: builtin/commit.c:667
 msgid "could not read SQUASH_MSG"
 msgstr "không thể đọc SQUASH_MSG"
 
-#: builtin/commit.c:668
+#: builtin/commit.c:671
 #, c-format
 msgid "could not read '%s'"
 msgstr "Không thể đọc '%s'."
 
-#: builtin/commit.c:720
+#: builtin/commit.c:723
 msgid "could not write commit template"
 msgstr "không thể ghi mẫu commit"
 
-#: builtin/commit.c:731
+#: builtin/commit.c:734
 #, c-format
 msgid ""
 "\n"
@@ -2399,7 +2664,7 @@ msgstr ""
 "\t%s\n"
 "và thử lại.\n"
 
-#: builtin/commit.c:736
+#: builtin/commit.c:739
 #, c-format
 msgid ""
 "\n"
@@ -2414,7 +2679,7 @@ msgstr ""
 "\t%s\n"
 "và thử lại.\n"
 
-#: builtin/commit.c:748
+#: builtin/commit.c:751
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be ignored, and an empty message aborts the commit.\n"
@@ -2422,7 +2687,7 @@ msgstr ""
 "Hãy nhập vào các thông tin để giải thích các thay đổi của bạn. Những dòng được\n"
 "bắt đầu bằng '#' sẽ được bỏ qua, phần chú thích này nếu rỗng sẽ làm hủy bỏ lần chuyển giao (commit).\n"
 
-#: builtin/commit.c:753
+#: builtin/commit.c:756
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be kept; you may remove them yourself if you want to.\n"
@@ -2432,164 +2697,164 @@ msgstr ""
 "bắt đầu bằng '#' sẽ được bỏ qua; bạn có thể xóa chúng đi nếu muốn.\n"
 "Phần chú thích này nếu rỗng sẽ làm hủy bỏ lần chuyển giao (commit).\n"
 
-#: builtin/commit.c:766
+#: builtin/commit.c:769
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%sTác giả:    %s"
 
-#: builtin/commit.c:773
+#: builtin/commit.c:776
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%sNgười chuyển giao (commit): %s"
 
-#: builtin/commit.c:793
+#: builtin/commit.c:796
 msgid "Cannot read index"
 msgstr "không đọc được bảng mục lục"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:833
 msgid "Error building trees"
 msgstr "Gặp lỗi khi xây dựng cây"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:848
 #: builtin/tag.c:361
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Xin hãy áp dụng thông điệp sử dụng hoặc là tùy chọn -m hoặc là -F.\n"
 
-#: builtin/commit.c:942
+#: builtin/commit.c:945
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "Không tìm thấy tác giả đã sẵn có với '%s'"
 
-#: builtin/commit.c:957
-#: builtin/commit.c:1157
+#: builtin/commit.c:960
+#: builtin/commit.c:1160
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Chế độ cho các tập tin không bị theo vết không hợp lệ '%s'"
 
-#: builtin/commit.c:997
+#: builtin/commit.c:1000
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "Sử dụng cả hai tùy chọn --reset-author và --author không hợp lý"
 
-#: builtin/commit.c:1008
+#: builtin/commit.c:1011
 msgid "You have nothing to amend."
 msgstr "Không có gì để amend (tu bổ) cả."
 
-#: builtin/commit.c:1011
+#: builtin/commit.c:1014
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "Bạn đang ở giữa của quá trình hòa trộn -- không thể thực hiện amend (tu bổ)."
 
-#: builtin/commit.c:1013
+#: builtin/commit.c:1016
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "Bạn đang ở giữa của quá trình cherry-pick -- không thể thực hiện amend (tu bổ)."
 
-#: builtin/commit.c:1016
+#: builtin/commit.c:1019
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "Các tùy chọn --squash và --fixup không thể sử dụng cùng với nhau"
 
-#: builtin/commit.c:1026
+#: builtin/commit.c:1029
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Chỉ một tùy chọn trong số -c/-C/-F/--fixup được sử dụng"
 
-#: builtin/commit.c:1028
+#: builtin/commit.c:1031
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
 msgstr "Tùy chọn -m không thể được tổ hợp cùng với -c/-C/-F/--fixup."
 
-#: builtin/commit.c:1036
+#: builtin/commit.c:1039
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author chỉ có thể được sử dụng với tùy chọn -C, -c hay --amend."
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1056
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr "Chỉ một trong các tùy chọn --include/--only/--all/--interactive/--patch được sử dụng."
 
-#: builtin/commit.c:1055
+#: builtin/commit.c:1058
 msgid "No paths with --include/--only does not make sense."
 msgstr "Không đường dẫn với các tùy chọn --include/--only không hợp lý."
 
-#: builtin/commit.c:1057
+#: builtin/commit.c:1060
 msgid "Clever... amending the last one with dirty index."
 msgstr "Giỏi... đang tu bổ cái cuối với bảng mục lục phi nghĩa."
 
-#: builtin/commit.c:1059
+#: builtin/commit.c:1062
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
 msgstr "Những đường dẫn rõ ràng được chỉ ra không có tùy chọn -i cũng không -o; đang giả định --only những-đường-dẫn..."
 
-#: builtin/commit.c:1069
+#: builtin/commit.c:1072
 #: builtin/tag.c:577
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Chế độ dọn dẹp không hợp lệ %s"
 
-#: builtin/commit.c:1074
+#: builtin/commit.c:1077
 msgid "Paths with -a does not make sense."
 msgstr "Các đường dẫn với tùy chọn -a không hợp lý."
 
-#: builtin/commit.c:1257
+#: builtin/commit.c:1260
 msgid "couldn't look up newly created commit"
 msgstr "không thể tìm thấy lần chuyển giao (commit) mới hơn đã được tạo"
 
-#: builtin/commit.c:1259
+#: builtin/commit.c:1262
 msgid "could not parse newly created commit"
 msgstr "không thể phân tích cú pháp của đối tượng chuyển giao mới hơn đã được tạo"
 
-#: builtin/commit.c:1300
+#: builtin/commit.c:1303
 msgid "detached HEAD"
 msgstr "đã rời khỏi HEAD"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1305
 msgid " (root-commit)"
 msgstr " (root-commit)"
 
-#: builtin/commit.c:1446
+#: builtin/commit.c:1449
 msgid "could not parse HEAD commit"
 msgstr "không thể phân tích commit (lần chuyển giao) HEAD"
 
-#: builtin/commit.c:1484
+#: builtin/commit.c:1487
 #: builtin/merge.c:509
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "không thể mở %s' để đọc"
 
-#: builtin/commit.c:1491
+#: builtin/commit.c:1494
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Tập tin MERGE_HEAD sai hỏng (%s)"
 
-#: builtin/commit.c:1498
+#: builtin/commit.c:1501
 msgid "could not read MERGE_MODE"
 msgstr "không thể đọc MERGE_MODE"
 
-#: builtin/commit.c:1517
+#: builtin/commit.c:1520
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "không thể đọc thông điệp (message) commit (lần chuyển giao): %s"
 
-#: builtin/commit.c:1531
+#: builtin/commit.c:1534
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Đang bỏ qua việc chuyển giao (commit); bạn đã không biên soạn thông điệp (message).\n"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1539
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Đang bỏ qua lần chuyển giao (commit) bởi vì thông điệp của nó trống rỗng.\n"
 
-#: builtin/commit.c:1551
+#: builtin/commit.c:1554
 #: builtin/merge.c:936
 #: builtin/merge.c:961
 msgid "failed to write commit object"
 msgstr "gặp lỗi khi ghi đối tượng chuyển giao (commit)"
 
-#: builtin/commit.c:1572
+#: builtin/commit.c:1575
 msgid "cannot lock HEAD ref"
 msgstr "không thể khóa HEAD ref (tham chiếu)"
 
-#: builtin/commit.c:1576
+#: builtin/commit.c:1579
 msgid "cannot update HEAD ref"
 msgstr "không thể cập nhật HEAD ref (tham chiếu)"
 
-#: builtin/commit.c:1587
+#: builtin/commit.c:1590
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
@@ -2966,33 +3231,33 @@ msgstr "--[no-]exclude-standard không thể sử dụng cho nội dung lưu d
 msgid "both --cached and trees are given."
 msgstr "cả hai --cached và các cây phải được chỉ ra."
 
-#: builtin/help.c:63
+#: builtin/help.c:65
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "không nhận ra định dạng trợ giúp '%s'"
 
-#: builtin/help.c:91
+#: builtin/help.c:93
 msgid "Failed to start emacsclient."
 msgstr "Lỗi khởi chạy emacsclient."
 
-#: builtin/help.c:104
+#: builtin/help.c:106
 msgid "Failed to parse emacsclient version."
 msgstr "Gặp lỗi khi phân tích phiên bản emacsclient."
 
-#: builtin/help.c:112
+#: builtin/help.c:114
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "phiên bản của emacsclient '%d' quá cũ (< 22)."
 
-#: builtin/help.c:130
-#: builtin/help.c:158
-#: builtin/help.c:167
-#: builtin/help.c:175
+#: builtin/help.c:132
+#: builtin/help.c:160
+#: builtin/help.c:169
+#: builtin/help.c:177
 #, c-format
 msgid "failed to exec '%s': %s"
 msgstr "gặp lỗi khi thực thi '%s': %s"
 
-#: builtin/help.c:215
+#: builtin/help.c:217
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -3001,7 +3266,7 @@ msgstr ""
 "'%s': đường dẫn không hỗ trợ bộ trình chiếu man.\n"
 "Hãy cân nhắc đến việc sử dụng 'man.<tool>.cmd' để thay thế."
 
-#: builtin/help.c:227
+#: builtin/help.c:229
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -3010,35 +3275,30 @@ msgstr ""
 "'%s': cmd (lệnh) hỗ trợ bộ trình chiếu man.\n"
 "Hãy cân nhắc đến việc sử dụng 'man.<tool>.path' để thay thế."
 
-#: builtin/help.c:291
+#: builtin/help.c:299
 msgid "The most commonly used git commands are:"
 msgstr "Những lệnh git hay được sử dụng nhất là:"
 
-#: builtin/help.c:359
+#: builtin/help.c:367
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "'%s': không rõ chương trình xem man."
 
-#: builtin/help.c:376
+#: builtin/help.c:384
 msgid "no man viewer handled the request"
 msgstr "không có trình xem trợ giúp dạng manpage tiếp hợp với yêu cầu"
 
-#: builtin/help.c:384
+#: builtin/help.c:392
 msgid "no info viewer handled the request"
 msgstr "không có trình xem trợ giúp dạng info tiếp hợp với yêu cầu"
 
-#: builtin/help.c:395
-#, c-format
-msgid "'%s': not a documentation directory."
-msgstr "'%s': không phải là một thư mục tài liệu."
-
-#: builtin/help.c:436
-#: builtin/help.c:443
+#: builtin/help.c:447
+#: builtin/help.c:454
 #, c-format
 msgid "usage: %s%s"
 msgstr "cách sử dụng: %s%s"
 
-#: builtin/help.c:459
+#: builtin/help.c:470
 #, c-format
 msgid "`git %s' is aliased to `%s'"
 msgstr "`git %s' được đặt bí danh thành `%s'"
@@ -3112,184 +3372,184 @@ msgstr "khoảng bù cơ sở cho delta nằm ngoài phạm vi"
 msgid "unknown object type %d"
 msgstr "không hiểu kiểu đối tượng %d"
 
-#: builtin/index-pack.c:531
+#: builtin/index-pack.c:530
 msgid "cannot pread pack file"
 msgstr "không thể chạy hàm pread cho tập tin pack"
 
-#: builtin/index-pack.c:533
+#: builtin/index-pack.c:532
 #, c-format
 msgid "premature end of pack file, %lu byte missing"
 msgid_plural "premature end of pack file, %lu bytes missing"
 msgstr[0] "tập tin pack bị kết thúc sớm, %lu byte bị thiếu"
 msgstr[1] "tập tin pack bị kết thúc sớm, %lu byte bị thiếu"
 
-#: builtin/index-pack.c:555
+#: builtin/index-pack.c:558
 msgid "serious inflate inconsistency"
 msgstr "sự mâu thuẫn xả nén nghiêm trọng"
 
-#: builtin/index-pack.c:646
-#: builtin/index-pack.c:652
-#: builtin/index-pack.c:675
-#: builtin/index-pack.c:709
-#: builtin/index-pack.c:718
+#: builtin/index-pack.c:649
+#: builtin/index-pack.c:655
+#: builtin/index-pack.c:678
+#: builtin/index-pack.c:712
+#: builtin/index-pack.c:721
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SỰ VA CHẠM SHA1 ĐàXẢY RA VỚI %s!"
 
-#: builtin/index-pack.c:649
+#: builtin/index-pack.c:652
 #: builtin/pack-objects.c:170
 #: builtin/pack-objects.c:262
 #, c-format
 msgid "unable to read %s"
 msgstr "không thể đọc %s"
 
-#: builtin/index-pack.c:715
+#: builtin/index-pack.c:718
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "không thể đọc đối tượng đã tồn tại %s"
 
-#: builtin/index-pack.c:729
+#: builtin/index-pack.c:732
 #, c-format
 msgid "invalid blob object %s"
 msgstr "đối tượng blob không hợp lệ %s"
 
-#: builtin/index-pack.c:744
+#: builtin/index-pack.c:747
 #, c-format
 msgid "invalid %s"
 msgstr "%s không hợp lệ"
 
-#: builtin/index-pack.c:746
+#: builtin/index-pack.c:749
 msgid "Error in object"
 msgstr "Lỗi trong đối tượng"
 
-#: builtin/index-pack.c:748
+#: builtin/index-pack.c:751
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "Không phải tất cả các đối tượng con của %s là có thể với tới được"
 
-#: builtin/index-pack.c:818
-#: builtin/index-pack.c:844
+#: builtin/index-pack.c:821
+#: builtin/index-pack.c:847
 msgid "failed to apply delta"
 msgstr "gặp lỗi khi áp dụng delta"
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Receiving objects"
 msgstr "Đang nhận về các đối tượng"
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Indexing objects"
 msgstr "Các đối tượng bảng mục lục"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1012
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "pack bị sai hỏng (SHA1 không khớp)"
 
-#: builtin/index-pack.c:1014
+#: builtin/index-pack.c:1017
 msgid "cannot fstat packfile"
 msgstr "không thể fstat packfile"
 
-#: builtin/index-pack.c:1017
+#: builtin/index-pack.c:1020
 msgid "pack has junk at the end"
 msgstr "pack có phần thừa ở cuối"
 
-#: builtin/index-pack.c:1028
+#: builtin/index-pack.c:1031
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "lộn xộn hơn cả điên rồ khi chạy hàm parse_pack_objects()"
 
-#: builtin/index-pack.c:1051
+#: builtin/index-pack.c:1054
 msgid "Resolving deltas"
 msgstr "Đang phân giải các delta"
 
-#: builtin/index-pack.c:1102
+#: builtin/index-pack.c:1105
 msgid "confusion beyond insanity"
 msgstr "lộn xộn hơn cả điên rồ"
 
-#: builtin/index-pack.c:1121
+#: builtin/index-pack.c:1124
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "pack có %d delta chưa được giải quyết"
 msgstr[1] "pack có %d delta chưa được giải quyết"
 
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1149
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "không thể xả đối tượng nối thêm (%d)"
 
-#: builtin/index-pack.c:1225
+#: builtin/index-pack.c:1228
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "đối tượng nội bộ %s bị hỏng"
 
-#: builtin/index-pack.c:1249
+#: builtin/index-pack.c:1252
 msgid "error while closing pack file"
 msgstr "gặp lỗi trong khi đóng tập tin pack"
 
-#: builtin/index-pack.c:1262
+#: builtin/index-pack.c:1265
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr "không thể ghi tập tin giữ lại '%s'"
 
-#: builtin/index-pack.c:1270
+#: builtin/index-pack.c:1273
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr "không thể đóng tập tin giữ lại đã được ghi '%s'"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1286
 msgid "cannot store pack file"
 msgstr "không thể lưu tập tin pack"
 
-#: builtin/index-pack.c:1294
+#: builtin/index-pack.c:1297
 msgid "cannot store index file"
 msgstr "không thể lưu trữ tập tin ghi mục lục"
 
-#: builtin/index-pack.c:1395
+#: builtin/index-pack.c:1398
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Không thể mở tập tin pack đã sẵn có '%s' "
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1400
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "Không thể mở tập tin 'pack idx' cho '%s'"
 
-#: builtin/index-pack.c:1444
+#: builtin/index-pack.c:1447
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "không delta: %d đối tượng"
 msgstr[1] "không delta: %d đối tượng"
 
-#: builtin/index-pack.c:1451
+#: builtin/index-pack.c:1454
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "chiều dài xích = %d: %lu đối tượng"
 msgstr[1] "chiều dài xích = %d: %lu đối tượng"
 
-#: builtin/index-pack.c:1478
+#: builtin/index-pack.c:1481
 msgid "Cannot come back to cwd"
 msgstr "Không thể quay lại cwd"
 
-#: builtin/index-pack.c:1522
 #: builtin/index-pack.c:1525
-#: builtin/index-pack.c:1537
-#: builtin/index-pack.c:1541
+#: builtin/index-pack.c:1528
+#: builtin/index-pack.c:1540
+#: builtin/index-pack.c:1544
 #, c-format
 msgid "bad %s"
 msgstr "%s sai"
 
-#: builtin/index-pack.c:1555
+#: builtin/index-pack.c:1558
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin không thể được dùng mà không có --stdin"
 
-#: builtin/index-pack.c:1559
-#: builtin/index-pack.c:1569
+#: builtin/index-pack.c:1562
+#: builtin/index-pack.c:1572
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "tên tập tin packfile '%s' không được kết thúc bằng đuôi '.pack'"
 
-#: builtin/index-pack.c:1578
+#: builtin/index-pack.c:1581
 msgid "--verify with no packfile name given"
 msgstr "dùng tùy chọn --verify mà không đưa ra tên packfile"
 
@@ -3363,23 +3623,23 @@ msgstr "không sao chép các mẫu của phiên bản sai định dạng %d t
 msgid "insane git directory %s"
 msgstr "thư mục git điên rồ %s"
 
-#: builtin/init-db.c:322
-#: builtin/init-db.c:325
+#: builtin/init-db.c:323
+#: builtin/init-db.c:326
 #, c-format
 msgid "%s already exists"
 msgstr "%s đã tồn tại rồi"
 
-#: builtin/init-db.c:354
+#: builtin/init-db.c:355
 #, c-format
 msgid "unable to handle file type %d"
 msgstr "không thể handle tệp tin kiểu %d"
 
-#: builtin/init-db.c:357
+#: builtin/init-db.c:358
 #, c-format
 msgid "unable to move %s to %s"
 msgstr "không di chuyển được %s vào %s"
 
-#: builtin/init-db.c:362
+#: builtin/init-db.c:363
 #, c-format
 msgid "Could not create git link %s"
 msgstr "Không thể tạo liên kết git '%s'"
@@ -3389,48 +3649,48 @@ msgstr "Không thể tạo liên kết git '%s'"
 #. * existing" or "Initialized empty", the second " shared" or
 #. * "", and the last '%s%s' is the verbatim directory name.
 #.
-#: builtin/init-db.c:419
+#: builtin/init-db.c:420
 #, c-format
 msgid "%s%s Git repository in %s%s\n"
 msgstr "%s%s kho Git trong %s%s\n"
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Reinitialized existing"
 msgstr "Khởi tạo lại đã sẵn có rồi"
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Initialized empty"
 msgstr "Khởi tạo trống rỗng"
 
-#: builtin/init-db.c:421
+#: builtin/init-db.c:422
 msgid " shared"
 msgstr " đã chia sẻ"
 
-#: builtin/init-db.c:440
+#: builtin/init-db.c:441
 msgid "cannot tell cwd"
 msgstr "không nói chuyện được với lệnh cwd"
 
-#: builtin/init-db.c:521
-#: builtin/init-db.c:528
+#: builtin/init-db.c:522
+#: builtin/init-db.c:529
 #, c-format
 msgid "cannot mkdir %s"
 msgstr "không thể mkdir (tạo thư mục): %s"
 
-#: builtin/init-db.c:532
+#: builtin/init-db.c:533
 #, c-format
 msgid "cannot chdir to %s"
 msgstr "không thể chdir (chuyển đổi thư mục) sang %s"
 
-#: builtin/init-db.c:554
+#: builtin/init-db.c:555
 #, c-format
 msgid "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-dir=<directory>)"
 msgstr "%s (hoặc --work-tree=<thư-mục>) không cho phép không chỉ định %s (hoặc --git-dir=<thư-mục>)"
 
-#: builtin/init-db.c:578
+#: builtin/init-db.c:579
 msgid "Cannot access current working directory"
 msgstr "Không thể truy cập thư mục làm việc hiện hành"
 
-#: builtin/init-db.c:585
+#: builtin/init-db.c:586
 #, c-format
 msgid "Cannot access work tree '%s'"
 msgstr "không thể truy cập cây (tree) làm việc '%s'"
@@ -3440,97 +3700,97 @@ msgstr "không thể truy cập cây (tree) làm việc '%s'"
 msgid "Final output: %d %s\n"
 msgstr "Kết xuất cuối cùng: %d %s\n"
 
-#: builtin/log.c:402
-#: builtin/log.c:490
+#: builtin/log.c:403
+#: builtin/log.c:494
 #, c-format
 msgid "Could not read object %s"
 msgstr "Không thể đọc đối tượng %s"
 
-#: builtin/log.c:514
+#: builtin/log.c:518
 #, c-format
 msgid "Unknown type: %d"
 msgstr "Không nhận ra kiểu: %d"
 
-#: builtin/log.c:603
+#: builtin/log.c:608
 msgid "format.headers without value"
 msgstr "format.headers không có giá trị cụ thể"
 
-#: builtin/log.c:677
+#: builtin/log.c:682
 msgid "name of output directory is too long"
 msgstr "tên của thư mục kết xuất quá dài"
 
-#: builtin/log.c:688
+#: builtin/log.c:693
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr "Không thể mở tập tin miếng vá: %s"
 
-#: builtin/log.c:702
+#: builtin/log.c:707
 msgid "Need exactly one range."
 msgstr "Cần chính xác một vùng."
 
-#: builtin/log.c:710
+#: builtin/log.c:715
 msgid "Not a range."
 msgstr "Không phải là một vùng."
 
-#: builtin/log.c:787
+#: builtin/log.c:792
 msgid "Cover letter needs email format"
 msgstr "'Cover letter' cần cho định dạng thư"
 
-#: builtin/log.c:860
+#: builtin/log.c:865
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr "in-reply-to điên rồ: %s"
 
-#: builtin/log.c:933
+#: builtin/log.c:938
 msgid "Two output directories?"
 msgstr "Hai thư mục kết xuất?"
 
-#: builtin/log.c:1154
+#: builtin/log.c:1160
 #, c-format
 msgid "bogus committer info %s"
 msgstr "thông tin người chuyển giao không có thực %s"
 
-#: builtin/log.c:1199
+#: builtin/log.c:1205
 msgid "-n and -k are mutually exclusive."
 msgstr "-n và  -k loại từ lẫn nhau."
 
-#: builtin/log.c:1201
+#: builtin/log.c:1207
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr "--subject-prefix và -k xung khắc nhau."
 
-#: builtin/log.c:1209
+#: builtin/log.c:1215
 msgid "--name-only does not make sense"
 msgstr "--name-only không hợp lý"
 
-#: builtin/log.c:1211
+#: builtin/log.c:1217
 msgid "--name-status does not make sense"
 msgstr "--name-status không hợp lý"
 
-#: builtin/log.c:1213
+#: builtin/log.c:1219
 msgid "--check does not make sense"
 msgstr "--check không hợp lý"
 
-#: builtin/log.c:1236
+#: builtin/log.c:1242
 msgid "standard output, or directory, which one?"
 msgstr "đầu ra chuẩn, hay thư mục, chọn cái nào?"
 
-#: builtin/log.c:1238
+#: builtin/log.c:1244
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "Không thể tạo thư mục '%s'"
 
-#: builtin/log.c:1391
+#: builtin/log.c:1397
 msgid "Failed to create output files"
 msgstr "Gặp lỗi khi tạo các tập tin kết xuất"
 
-#: builtin/log.c:1495
+#: builtin/log.c:1501
 #, c-format
 msgid "Could not find a tracked remote branch, please specify <upstream> manually.\n"
 msgstr "Không tìm thấy nhánh mạng bị theo vết, hãy chỉ định <dòng-ngược> một cách thủ công.\n"
 
-#: builtin/log.c:1511
-#: builtin/log.c:1513
-#: builtin/log.c:1525
+#: builtin/log.c:1517
+#: builtin/log.c:1519
+#: builtin/log.c:1531
 #, c-format
 msgid "Unknown commit %s"
 msgstr "Không hiểu lần chuyển giao (commit) %s"
@@ -3612,10 +3872,6 @@ msgstr "lệnh git write-tree gặp lỗi khi ghi một cây"
 msgid "failed to read the cache"
 msgstr "gặp lỗi khi đọc bộ nhớ tạm"
 
-#: builtin/merge.c:697
-msgid "Unable to write index."
-msgstr "Không thể ghi bảng mục lục"
-
 #: builtin/merge.c:710
 msgid "Not handling anything other than two heads merge."
 msgstr "Không cầm nắm gì ngoài hai head hòa trộn"
@@ -4666,30 +4922,30 @@ msgstr "Những thay đổi bị bỏ trạng thái (stage) sau khi reset:"
 msgid "Cannot do a %s reset in the middle of a merge."
 msgstr "Không thể thực hiện một %s reset ở giữa của quá trình hòa trộn."
 
-#: builtin/reset.c:297
+#: builtin/reset.c:303
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "không thể phân tích đối tượng '%s'."
 
-#: builtin/reset.c:302
+#: builtin/reset.c:308
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch xung khắc với --{hard,mixed,soft}"
 
-#: builtin/reset.c:311
+#: builtin/reset.c:317
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
 msgstr "--mixed với các đường dẫn không còn dùng nữa; hãy thay thế bằng lệnh 'git reset -- <đường_dẫn>'."
 
-#: builtin/reset.c:313
+#: builtin/reset.c:319
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "Không thể thực hiện lệnh %s reset với các đường dẫn."
 
-#: builtin/reset.c:325
+#: builtin/reset.c:331
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr "%s reset không được phép trên kho bare (trên máy chủ)"
 
-#: builtin/reset.c:341
+#: builtin/reset.c:347
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "Không thể đặt lại (reset) bảng mục lục thành điểm xét lại '%s'."
@@ -4941,7 +5197,7 @@ msgstr "Liệt kê, tạo hay là xóa các nhánh"
 
 #: common-cmds.h:11
 msgid "Checkout a branch or paths to the working tree"
-msgstr "Checkout má»\99t nhánh hay các Ä\91ưá»\9dng dẫn tá»\9di cây làm việc"
+msgstr "Checkout má»\99t nhánh hay các Ä\91ưá»\9dng dẫn tá»\9bi cây làm việc"
 
 #: common-cmds.h:12
 msgid "Clone a repository into a new directory"
@@ -5026,9 +5282,9 @@ msgstr ""
 #: git-am.sh:105
 #, sh-format
 msgid ""
-"When you have resolved this problem run \"$cmdline --resolved\".\n"
-"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
-"To restore the original branch and stop patching run \"$cmdline --abort\"."
+"When you have resolved this problem, run \"$cmdline --resolved\".\n"
+"If you prefer to skip this patch, run \"$cmdline --skip\" instead.\n"
+"To restore the original branch and stop patching, run \"$cmdline --abort\"."
 msgstr ""
 "Khi bạn cần giải quyết vấn đề này hãy chạy lệnh \"$cmdline --resolved\".\n"
 "Nếu bạn có ý định bỏ qua miếng vá, thay vào đó bạn chạy \"$cmdline --skip\".\n"
@@ -5042,6 +5298,10 @@ msgstr "Đang trở lại để hòa trộn kiểu 'three-way'."
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
 msgstr "Kho thiếu đối tượng blob cần thiết để trở về trên '3-way merge'."
 
+#: git-am.sh:139
+msgid "Using index info to reconstruct a base tree..."
+msgstr "Sử dụng thông tin trong bảng mục lục để cấu trúc lại một cây (tree) cơ sở..."
+
 #: git-am.sh:154
 msgid ""
 "Did you hand edit your patch?\n"
@@ -5054,42 +5314,50 @@ msgstr ""
 msgid "Falling back to patching base and 3-way merge..."
 msgstr "Đang trở lại để vá cơ sở và '3-way merge'..."
 
-#: git-am.sh:275
+#: git-am.sh:179
+msgid "Failed to merge in the changes."
+msgstr "Gặp lỗi khi trộn vào các thay đổi."
+
+#: git-am.sh:274
 msgid "Only one StGIT patch series can be applied at once"
 msgstr "Chỉ có một sê-ri miếng vá StGIT được áp dụng một lúc"
 
-#: git-am.sh:362
+#: git-am.sh:361
 #, sh-format
 msgid "Patch format $patch_format is not supported."
 msgstr "Định dạng miếng vá $patch_format không được hỗ trợ."
 
-#: git-am.sh:364
+#: git-am.sh:363
 msgid "Patch format detection failed."
 msgstr "Dò tìm định dạng miếng vá gặp lỗi."
 
-#: git-am.sh:418
-msgid "-d option is no longer supported.  Do not use."
-msgstr "Tùy chọn -d không còn được hỗ trợ nữa. Xin đừng sử dụng."
+#: git-am.sh:389
+msgid ""
+"The -b/--binary option has been a no-op for long time, and\n"
+"it will be removed. Please do not use it anymore."
+msgstr ""
+"Tùy chọn -b/--binary đã không dùng từ lâu rồi, và\n"
+"nó sẽ được bỏ đi. Xin đừng sử dụng nó thêm nữa."
 
-#: git-am.sh:481
+#: git-am.sh:477
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
 msgstr "thư mục rebase trước $dotest vẫn chưa sẵn sàng nhưng mbox được đưa ra."
 
-#: git-am.sh:486
+#: git-am.sh:482
 msgid "Please make up your mind. --skip or --abort?"
 msgstr "Xin hãy rõ ràng. --skip hay --abort?"
 
-#: git-am.sh:513
+#: git-am.sh:509
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr "Thao tác phân giải không đang được tiến hành, chúng ta không phục hồi lại."
 
-#: git-am.sh:579
+#: git-am.sh:575
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
 msgstr "Bảng mục lục sai: không thể áp dụng các miếng vá (sai: $files)"
 
-#: git-am.sh:671
+#: git-am.sh:679
 #, sh-format
 msgid ""
 "Patch is empty.  Was it split wrong?\n"
@@ -5100,31 +5368,31 @@ msgstr ""
 "Nếu bạn thích bỏ qua miếng vá này, hãy chạy lệnh sau để thay thế \"$cmdline --skip\".\n"
 "Để phục hồi lại nhánh nguyên thủy và dừng vá lại hãy chạy lệnh \"$cmdline --abort\"."
 
-#: git-am.sh:708
+#: git-am.sh:706
 msgid "Patch does not have a valid e-mail address."
 msgstr "Miếng vá không có địa chỉ e-mail hợp lệ."
 
-#: git-am.sh:755
+#: git-am.sh:753
 msgid "cannot be interactive without stdin connected to a terminal."
 msgstr "không thể được tương tác mà không có stdin kết nối với một thiết bị cuối"
 
-#: git-am.sh:759
+#: git-am.sh:757
 msgid "Commit Body is:"
 msgstr "Thân của lần chuyển giao (commit) là:"
 
 #. 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:766
+#: git-am.sh:764
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
 msgstr "Áp dụng? đồng ý [y]/không [n]/chỉnh sửa [e]/hiển thị miếng [v]á/đồng ý tất cả [a]"
 
-#: git-am.sh:802
+#: git-am.sh:800
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr "Đang áp dụng (miếng vá): $FIRSTLINE"
 
-#: git-am.sh:823
+#: git-am.sh:821
 msgid ""
 "No changes - did you forget to use 'git add'?\n"
 "If there is nothing left to stage, chances are that something else\n"
@@ -5134,7 +5402,7 @@ msgstr ""
 "Nếu ở đây không có gì còn lại stage, tình cờ là có một số thứ khác\n"
 "đã sẵn được đưa vào với cùng nội dung thay đổi; bạn có lẽ muốn bỏ qua miếng vá này."
 
-#: git-am.sh:831
+#: git-am.sh:829
 msgid ""
 "You still have unmerged paths in your index\n"
 "did you forget to use 'git add'?"
@@ -5142,16 +5410,16 @@ msgstr ""
 "Bạn vẫn có những đường dẫn chưa được hòa trộn trong bảng mục lục của mình\n"
 "bạn đã quên sử dụng lệnh 'git add' à?"
 
-#: git-am.sh:847
+#: git-am.sh:845
 msgid "No changes -- Patch already applied."
 msgstr "Không thay đổi gì cả -- Miếng vá đã được áp dụng rồi."
 
-#: git-am.sh:857
+#: git-am.sh:855
 #, sh-format
 msgid "Patch failed at $msgnum $FIRSTLINE"
 msgstr "Vá gặp lỗi tại $msgnum $FIRSTLINE"
 
-#: git-am.sh:873
+#: git-am.sh:876
 msgid "applying to an empty history"
 msgstr "áp dụng vào một lịch sử trống rỗng"
 
@@ -5351,6 +5619,127 @@ msgstr "Không thể hòa trộn nhiều nhánh và trong một head trống r
 msgid "Cannot rebase onto multiple branches"
 msgstr "Không thể thực hiện lệnh rebase (cơ cấu lại) trên nhiều nhánh"
 
+#: git-rebase.sh:52
+msgid ""
+"When you have resolved this problem, run \"git rebase --continue\".\n"
+"If you prefer to skip this patch, run \"git rebase --skip\" instead.\n"
+"To check out the original branch and stop rebasing, run \"git rebase --abort\"."
+msgstr ""
+"Khi bạn cần giải quyết vấn đề này hãy chạy lệnh \"git rebase --continue\".\n"
+"Nếu bạn có ý định bỏ qua miếng vá, thay vào đó bạn chạy \"git rebase --skip\".\n"
+"Để phục hồi lại thành nhánh nguyên thủy và dừng việc vá lại thì chạy \"git rebase --abort\"."
+
+#: git-rebase.sh:159
+msgid "The pre-rebase hook refused to rebase."
+msgstr "hook (chương trình móc vào git) pre-rebase từ chối rebase."
+
+#: git-rebase.sh:164
+msgid "It looks like git-am is in progress. Cannot rebase."
+msgstr "Hình như đang trong quá trình thực hiện lệnh git-am. Không thể chạy lệnh rebase."
+
+#: git-rebase.sh:295
+msgid "The --exec option must be used with the --interactive option"
+msgstr "Tùy chọn --exec phải được sử dụng cùng với tùy chọn --interactive"
+
+#: git-rebase.sh:300
+msgid "No rebase in progress?"
+msgstr "Không phải đang rebase?"
+
+#: git-rebase.sh:313
+msgid "Cannot read HEAD"
+msgstr "Không thể đọc HEAD"
+
+#: git-rebase.sh:316
+msgid ""
+"You must edit all merge conflicts and then\n"
+"mark them as resolved using git add"
+msgstr ""
+"Bạn phải sửa tất cả các lần hòa trộn xung đột và sau\n"
+"đó đánh dấu chúng là cần xử lý sử dụng lệnh git add"
+
+#: git-rebase.sh:334
+#, sh-format
+msgid "Could not move back to $head_name"
+msgstr "Không thể quay trở lại $head_name"
+
+#: git-rebase.sh:350
+#, sh-format
+msgid ""
+"It seems that there is already a $state_dir_base directory, and\n"
+"I wonder if you are in the middle of another rebase.  If that is the\n"
+"case, please try\n"
+"\t$cmd_live_rebase\n"
+"If that is not the case, please\n"
+"\t$cmd_clear_stale_rebase\n"
+"and run me again.  I am stopping in case you still have something\n"
+"valuable there."
+msgstr ""
+"Hình như là ở đây sẵn có một thư mục $state_dir_base directory, và\n"
+"Tôi tự hỏi có phải bạn đang ở giữa một lệnh rebase khác.  Nếu đúng là\n"
+"như vậy, xin hãy thử\n"
+"\t$cmd_live_rebase\n"
+"Nếu không phải thế, hãy thử\n"
+"\t$cmd_clear_stale_rebase\n"
+"và chạy TÔI lần nữa.  TÔI  dừng lại trong trường hợp bạn vẫn\n"
+"có một số thứ quý giá ở đây.\n"
+"\n"
+"TÔI: là lệnh bạn vừa gọi!"
+
+#: git-rebase.sh:395
+#, sh-format
+msgid "invalid upstream $upstream_name"
+msgstr "dòng ngược không hợp lệ $upstream_name"
+
+#: git-rebase.sh:419
+#, sh-format
+msgid "$onto_name: there are more than one merge bases"
+msgstr "$onto_name: ở đây có nhiều hơn một "
+
+#: git-rebase.sh:422
+#: git-rebase.sh:426
+#, sh-format
+msgid "$onto_name: there is no merge base"
+msgstr "$onto_name: ở đây không có gì để hòa trộn"
+
+#: git-rebase.sh:431
+#, sh-format
+msgid "Does not point to a valid commit: $onto_name"
+msgstr "Không chỉ đến một lần chuyển giao (commit) không hợp lệ: $onto_name"
+
+#: git-rebase.sh:454
+#, sh-format
+msgid "fatal: no such branch: $branch_name"
+msgstr "nghiêm trọng: không có nhánh như thế: $branch_name"
+
+#: git-rebase.sh:474
+msgid "Please commit or stash them."
+msgstr "Xin hãy commit hoặc stash chúng."
+
+#: git-rebase.sh:492
+#, sh-format
+msgid "Current branch $branch_name is up to date."
+msgstr "Nhánh hiện tại $branch_name đã được cập nhật rồi."
+
+#: git-rebase.sh:495
+#, sh-format
+msgid "Current branch $branch_name is up to date, rebase forced."
+msgstr "Nhánh hiện tại $branch_name đã được cập nhật rồi, lệnh rebase ép buộc."
+
+#: git-rebase.sh:506
+#, sh-format
+msgid "Changes from $mb to $onto:"
+msgstr "Thay đổi từ $mb thành $onto:"
+
+#. Detach HEAD and reset the tree
+#: git-rebase.sh:515
+msgid "First, rewinding head to replay your work on top of it..."
+msgstr "Trước tiên, di chuyển head để xem lại các công việc trên đỉnh của nó..."
+
+#: git-rebase.sh:523
+#, sh-format
+msgid "Fast-forwarded $branch_name to $onto_name."
+msgstr "Fast-forward $branch_name thành $onto_name."
+
 #: git-stash.sh:51
 msgid "git stash clear with parameters is unimplemented"
 msgstr "git stash clear với các tham số là chưa được thực hiện (không nhận đối số)"
@@ -5491,27 +5880,27 @@ msgstr "không thể tháo bỏ một thành phần ra khỏi url '$remoteurl'"
 msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
 msgstr "Không tìm thấy ánh xạ (mapping) mô-đun-con trong .gitmodules cho đường dẫn '$sm_path'"
 
-#: git-submodule.sh:186
+#: git-submodule.sh:189
 #, sh-format
 msgid "Clone of '$url' into submodule path '$sm_path' failed"
 msgstr "Nhân bản '$url' vào đường dẫn mô-đun-con '$sm_path' gặp lỗi"
 
-#: git-submodule.sh:196
+#: git-submodule.sh:201
 #, sh-format
 msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
 msgstr "Gitdir '$a' là bộ phận của đường dẫn mô-đun-con '$b' hoặc \"vice versa\""
 
-#: git-submodule.sh:285
+#: git-submodule.sh:290
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "repo URL: '$repo' phải là đường dẫn tuyệt đối hoặc là bắt đầu bằng ./|../"
 
-#: git-submodule.sh:302
+#: git-submodule.sh:307
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "'$sm_path' thực sự đã tồn tại ở bảng mục lục rồi"
 
-#: git-submodule.sh:306
+#: git-submodule.sh:311
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -5522,62 +5911,62 @@ msgstr ""
 "$sm_path\n"
 "Sử dụng -f nếu bạn thực sự muốn thêm nó vào."
 
-#: git-submodule.sh:317
+#: git-submodule.sh:322
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "Đang thêm repo có sẵn tại '$sm_path' vào bảng mục lục"
 
-#: git-submodule.sh:319
+#: git-submodule.sh:324
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "'$sm_path' đã tồn tại từ trước và không phải là một kho git hợp lệ"
 
-#: git-submodule.sh:333
+#: git-submodule.sh:338
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "Không thể checkout mô-đun con '$sm_path'"
 
-#: git-submodule.sh:338
+#: git-submodule.sh:343
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "Gặp lỗi khi thêm mô-đun con '$sm_path'"
 
-#: git-submodule.sh:343
+#: git-submodule.sh:348
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "Gặp lỗi khi đăng ký với hệ thống mô-đun con '$sm_path'"
 
-#: git-submodule.sh:385
+#: git-submodule.sh:390
 #, sh-format
 msgid "Entering '$prefix$sm_path'"
 msgstr "Đang nhập '$prefix$sm_path'"
 
-#: git-submodule.sh:399
+#: git-submodule.sh:404
 #, sh-format
 msgid "Stopping at '$sm_path'; script returned non-zero status."
 msgstr "Dừng lại tại '$sm_path'; script trả về trạng thái khác không."
 
-#: git-submodule.sh:442
+#: git-submodule.sh:447
 #, sh-format
 msgid "No url found for submodule path '$sm_path' in .gitmodules"
 msgstr "Không tìm thấy url cho đường dẫn mô-đun-con '$sm_path' trong .gitmodules"
 
-#: git-submodule.sh:451
+#: git-submodule.sh:456
 #, sh-format
 msgid "Failed to register url for submodule path '$sm_path'"
 msgstr "Gặp lỗi khi đăng ký url cho đường dẫn mô-đun-con '$sm_path'"
 
-#: git-submodule.sh:453
+#: git-submodule.sh:458
 #, sh-format
 msgid "Submodule '$name' ($url) registered for path '$sm_path'"
 msgstr "Mô-đun-con '$name' ($url) được đăng ký cho đường dẫn '$sm_path'"
 
-#: git-submodule.sh:461
+#: git-submodule.sh:466
 #, sh-format
 msgid "Failed to register update mode for submodule path '$sm_path'"
 msgstr "Gặp lỗi khi đăng ký chế độ cập nhật cho đường dẫn mô-đun-con '$sm_path'"
 
-#: git-submodule.sh:560
+#: git-submodule.sh:565
 #, sh-format
 msgid ""
 "Submodule path '$sm_path' not initialized\n"
@@ -5586,98 +5975,103 @@ msgstr ""
 "Đường dẫn mô-đun-con '$sm_path' chưa được khởi tạo\n"
 "Có lẽ bạn muốn sử dụng lệnh 'update --init'?"
 
-#: git-submodule.sh:573
+#: git-submodule.sh:578
 #, sh-format
 msgid "Unable to find current revision in submodule path '$sm_path'"
 msgstr "Không tìm thấy điểm xét lại hiện hành trong đường dẫn mô-đun-con '$sm_path'"
 
-#: git-submodule.sh:592
+#: git-submodule.sh:597
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "Không thể lấy về (fetch) trong đường dẫn mô-đun-con '$sm_path'"
 
-#: git-submodule.sh:606
+#: git-submodule.sh:611
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
 msgstr "Không thể rebase '$sha1' trong đường dẫn mô-đun-con '$sm_path'"
 
-#: git-submodule.sh:607
+#: git-submodule.sh:612
 #, sh-format
 msgid "Submodule path '$sm_path': rebased into '$sha1'"
 msgstr "Đường dẫn mô-đun-con '$sm_path': được rebase vào trong '$sha1'"
 
-#: git-submodule.sh:612
+#: git-submodule.sh:617
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
 msgstr "Không thể hòa trộn (merge) '$sha1' trong đường dẫn mô-đun-con '$sm_path'"
 
-#: git-submodule.sh:613
+#: git-submodule.sh:618
 #, sh-format
 msgid "Submodule path '$sm_path': merged in '$sha1'"
 msgstr "Đường dẫn mô-đun-con '$sm_path': được hòa trộn vào '$sha1'"
 
-#: git-submodule.sh:618
+#: git-submodule.sh:623
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
 msgstr "Không thể checkout '$sha1' trong đường dẫn mô-đun-con '$sm_path'"
 
-#: git-submodule.sh:619
+#: git-submodule.sh:624
 #, sh-format
 msgid "Submodule path '$sm_path': checked out '$sha1'"
 msgstr "Đường dẫn mô-đun-con '$sm_path': được checkout '$sha1'"
 
-#: git-submodule.sh:641
-#: git-submodule.sh:964
+#: git-submodule.sh:646
+#: git-submodule.sh:969
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr "Gặp lỗi khi đệ quy vào trong đường dẫn mô-đun-con '$sm_path'"
 
-#: git-submodule.sh:749
-msgid "--cached cannot be used with --files"
-msgstr "--cached không thể được sử dụng cùng với --files"
+#: git-submodule.sh:754
+msgid "The --cached option cannot be used with the --files option"
+msgstr "Tùy chọn --cached không thể dùng cùng với tùy chọn --files"
 
 #. unexpected type
-#: git-submodule.sh:789
+#: git-submodule.sh:794
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "chế độ không như mong chờ $mod_dst"
 
-#: git-submodule.sh:807
+#: git-submodule.sh:812
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_src"
 msgstr "  Cảnh báo: $name không chứa lần chuyển giao (commit) $sha1_src"
 
-#: git-submodule.sh:810
+#: git-submodule.sh:815
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_dst"
 msgstr "  Cảnh báo: $name không chứa lần chuyển giao (commit) $sha1_dst"
 
-#: git-submodule.sh:813
+#: git-submodule.sh:818
 #, sh-format
 msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr "  Cảnh báo: $name không chứa những lần chuyển giao (commit) $sha1_src và $sha1_dst"
 
-#: git-submodule.sh:838
+#: git-submodule.sh:843
 msgid "blob"
 msgstr "blob"
 
-#: git-submodule.sh:839
-msgid "submodule"
-msgstr "mô-đun con"
-
-#: git-submodule.sh:876
+#: git-submodule.sh:881
 msgid "# Submodules changed but not updated:"
 msgstr "# Những mô-đun-con đã bị thay đổi nhưng chưa được cập nhật:"
 
-#: git-submodule.sh:878
+#: git-submodule.sh:883
 msgid "# Submodule changes to be committed:"
 msgstr "# Những thay đổi mô-đun-con được chuyển giao (commit):"
 
-#: git-submodule.sh:1022
+#: git-submodule.sh:1027
 #, sh-format
 msgid "Synchronizing submodule url for '$name'"
 msgstr "Đang đồng bộ hóa url mô-đun-con cho '$name'"
 
+#~ msgid "-d option is no longer supported.  Do not use."
+#~ msgstr "Tùy chọn -d không còn được hỗ trợ nữa. Xin đừng sử dụng."
+
+#~ msgid "%s: has been deleted/renamed"
+#~ msgstr "%s: đã được xóa/thay-tên"
+
+#~ msgid "'%s': not a documentation directory."
+#~ msgstr "'%s': không phải là một thư mục tài liệu."
+
 #~ msgid "--"
 #~ msgstr "--"
 
index b3e1a54c8efeba2571278400d57bbb01ec45f595..bc04236e476dfd5b9683ada57e4c6515c837e2c7 100644 (file)
@@ -12,8 +12,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2012-07-03 10:23+0800\n"
-"PO-Revision-Date: 2012-07-04 22:38+0800\n"
+"POT-Creation-Date: 2012-08-06 23:47+0800\n"
+"PO-Revision-Date: 2012-08-07 01:07+0800\n"
 "Last-Translator: Jiang Xin <worldhello.net@gmail.com>\n"
 "Language-Team: GitHub <https://github.com/gotgit/git/>\n"
 "Language: zh_CN\n"
@@ -52,7 +52,7 @@ msgstr "'%s' 不像是一个 v2 版本的包文件"
 msgid "unrecognized header: %s%s (%d)"
 msgstr "未能识别的包头:%s%s (%d)"
 
-#: bundle.c:89 builtin/commit.c:696
+#: bundle.c:89 builtin/commit.c:699
 #, c-format
 msgid "could not open '%s'"
 msgstr "不能打开 '%s'"
@@ -62,7 +62,7 @@ msgid "Repository lacks these prerequisite commits:"
 msgstr "版本库缺少这些必备的提交:"
 
 #: bundle.c:164 sequencer.c:550 sequencer.c:982 builtin/log.c:290
-#: builtin/log.c:721 builtin/log.c:1310 builtin/log.c:1529 builtin/merge.c:347
+#: builtin/log.c:726 builtin/log.c:1316 builtin/log.c:1535 builtin/merge.c:347
 #: builtin/shortlog.c:181
 msgid "revision walk setup failed"
 msgstr "版本遍历设置失败"
@@ -89,7 +89,7 @@ msgstr[1] "这个包需要 %d 个这些引用"
 msgid "rev-list died"
 msgstr "rev-list 终止"
 
-#: bundle.c:300 builtin/log.c:1206 builtin/shortlog.c:284
+#: bundle.c:300 builtin/log.c:1212 builtin/shortlog.c:284
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "未能识别的参数:%s"
@@ -237,8 +237,8 @@ msgstr ""
 "%s"
 
 #: diff.c:1400
-msgid " 0 files changed\n"
-msgstr " 0 个文件被修改\n"
+msgid " 0 files changed"
+msgstr " 0 个文件被修改"
 
 #: diff.c:1404
 #, c-format
@@ -261,7 +261,7 @@ msgid_plural ", %d deletions(-)"
 msgstr[0] ",删除 %d 行(-)"
 msgstr[1] ",删除 %d 行(-)"
 
-#: diff.c:3478
+#: diff.c:3461
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -297,16 +297,16 @@ msgstr "'%s':%s"
 msgid "'%s': short read %s"
 msgstr "'%s':读取不完整 %s"
 
-#: help.c:208
+#: help.c:212
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "在 '%s' 下可用的 git 命令"
 
-#: help.c:215
+#: help.c:219
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "在 $PATH 路径中的其他地方可用的 git 命令"
 
-#: help.c:271
+#: help.c:275
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -315,11 +315,11 @@ msgstr ""
 "'%s' 像是一个 git 命令,但却无法运行。\n"
 "可能是 git-%s 受损?"
 
-#: help.c:328
+#: help.c:332
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "唉呀,您的系统中未发现 Git 命令。"
 
-#: help.c:350
+#: help.c:354
 #, c-format
 msgid ""
 "WARNING: You called a Git command named '%s', which does not exist.\n"
@@ -328,17 +328,17 @@ msgstr ""
 "警告:您运行一个不存在的 Git 命令 '%s'。继续执行假定您要要运行的\n"
 "是 '%s'"
 
-#: help.c:355
+#: help.c:359
 #, c-format
 msgid "in %0.1f seconds automatically..."
 msgstr "在 %0.1f 秒钟后自动运行..."
 
-#: help.c:362
+#: help.c:366
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git:'%s' 不是一个 git 命令。参见 'git --help'。"
 
-#: help.c:366
+#: help.c:370
 msgid ""
 "\n"
 "Did you mean this?"
@@ -352,36 +352,298 @@ msgstr[1] ""
 "\n"
 "您指的是这些其中一个么?"
 
-#: parse-options.c:493
+#: merge-recursive.c:190
+#, c-format
+msgid "(bad commit)\n"
+msgstr "(坏提交)\n"
+
+#: merge-recursive.c:206
+#, c-format
+msgid "addinfo_cache failed for path '%s'"
+msgstr "为路径 '%s' addinfo_cache 失败"
+
+#: merge-recursive.c:268
+msgid "error building trees"
+msgstr "无法创建树"
+
+#: merge-recursive.c:497
+msgid "diff setup failed"
+msgstr "diff 设置失败"
+
+#: merge-recursive.c:627
+msgid "merge-recursive: disk full?"
+msgstr "merge-recursive:磁盘已满?"
+
+#: merge-recursive.c:690
+#, c-format
+msgid "failed to create path '%s'%s"
+msgstr "无法创建路径 '%s'%s"
+
+#: merge-recursive.c:701
+#, c-format
+msgid "Removing %s to make room for subdirectory\n"
+msgstr "删除 %s 以便为子目录留出空间\n"
+
+#. something else exists
+#. .. but not some other error (who really cares what?)
+#: merge-recursive.c:715 merge-recursive.c:736
+msgid ": perhaps a D/F conflict?"
+msgstr ":可能是一个目录/文件冲突?"
+
+#: merge-recursive.c:726
+#, c-format
+msgid "refusing to lose untracked file at '%s'"
+msgstr "拒绝丢弃 '%s' 中的未跟踪文件"
+
+#: merge-recursive.c:766
+#, c-format
+msgid "cannot read object %s '%s'"
+msgstr "不能读取对象 %s '%s'"
+
+#: merge-recursive.c:768
+#, c-format
+msgid "blob expected for %s '%s'"
+msgstr "%s '%s' 应为二进制对象(blob)"
+
+#: merge-recursive.c:791 builtin/clone.c:302
+#, c-format
+msgid "failed to open '%s'"
+msgstr "无法打开 '%s'"
+
+#: merge-recursive.c:799
+#, c-format
+msgid "failed to symlink '%s'"
+msgstr "无法创建符号链接 '%s'"
+
+#: merge-recursive.c:802
+#, c-format
+msgid "do not know what to do with %06o %s '%s'"
+msgstr "不知道如何处理 %06o %s '%s'"
+
+#: merge-recursive.c:939
+msgid "Failed to execute internal merge"
+msgstr "无法执行内部合并"
+
+#: merge-recursive.c:943
+#, c-format
+msgid "Unable to add %s to database"
+msgstr "不能添加 %s 至对象库"
+
+#: merge-recursive.c:959
+msgid "unsupported object type in the tree"
+msgstr "在树中有不支持的对象类型"
+
+#: merge-recursive.c:1038 merge-recursive.c:1052
+#, c-format
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree."
+msgstr ""
+"冲突(%1$s/删除):%2$s 在 %3$s 中被删除,在 %5$s 中被 %4$s。%7$s 在 %6$s 中"
+"的版本被保留。"
+
+#: merge-recursive.c:1044 merge-recursive.c:1057
+#, c-format
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree at %s."
+msgstr ""
+"冲突(%1$s/删除):%2$s 在 %3$s 中被删除,在 %5$s 中被 %4$s。%7$s 在 %6$s 中"
+"的版本保留于 %8$s 中。"
+
+#: merge-recursive.c:1098
+msgid "rename"
+msgstr "重命名"
+
+#: merge-recursive.c:1098
+msgid "renamed"
+msgstr "重命名"
+
+#: merge-recursive.c:1154
+#, c-format
+msgid "%s is a directory in %s adding as %s instead"
+msgstr "%s 是 %s 中的一个目录而以 %s 为名被添加"
+
+#: merge-recursive.c:1176
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
+"\"->\"%s\" in \"%s\"%s"
+msgstr ""
+"冲突(重命名/重命名):在分支 \"%3$s\" 中重命名 \"%1$s\"->\"%2$s\",在分支 "
+"\"%6$s\" 中重命名 \"%4$s\"->\"%5$s\"%7$s"
+
+#: merge-recursive.c:1181
+msgid " (left unresolved)"
+msgstr "(留下未解决)"
+
+#: merge-recursive.c:1235
+#, c-format
+msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
+msgstr ""
+"冲突(重命名/重命名):在 %3$s 中重命名 %1$s->%2$s,在 %6$s 中重命名 %4$s->"
+"%5$s"
+
+#: merge-recursive.c:1265
+#, c-format
+msgid "Renaming %s to %s and %s to %s instead"
+msgstr "而是重命名 %s 至 %s 以及 %s 至 %s"
+
+#: merge-recursive.c:1464
+#, c-format
+msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
+msgstr "冲突(重命名/添加):在 %3$s 中重命名 %1$s->%2$s。在 %5$s 中添加 %4$s"
+
+#: merge-recursive.c:1474
+#, c-format
+msgid "Adding merged %s"
+msgstr "添加合并后的 %s"
+
+#: merge-recursive.c:1479 merge-recursive.c:1677
+#, c-format
+msgid "Adding as %s instead"
+msgstr "而是以 %s 为名添加"
+
+#: merge-recursive.c:1530
+#, c-format
+msgid "cannot read object %s"
+msgstr "不能读取对象 %s"
+
+#: merge-recursive.c:1533
+#, c-format
+msgid "object %s is not a blob"
+msgstr "对象 %s 不是一个二进制对象(blob)"
+
+#: merge-recursive.c:1581
+msgid "modify"
+msgstr "修改"
+
+#: merge-recursive.c:1581
+msgid "modified"
+msgstr "修改"
+
+#: merge-recursive.c:1591
+msgid "content"
+msgstr "内容"
+
+#: merge-recursive.c:1598
+msgid "add/add"
+msgstr "添加/添加"
+
+#: merge-recursive.c:1632
+#, c-format
+msgid "Skipped %s (merged same as existing)"
+msgstr "略过 %s(已经做过相同合并)"
+
+#: merge-recursive.c:1646
+#, c-format
+msgid "Auto-merging %s"
+msgstr "自动合并 %s"
+
+#: merge-recursive.c:1650 git-submodule.sh:844
+msgid "submodule"
+msgstr "子模组"
+
+#: merge-recursive.c:1651
+#, c-format
+msgid "CONFLICT (%s): Merge conflict in %s"
+msgstr "冲突(%s):合并冲突于 %s"
+
+#: merge-recursive.c:1741
+#, c-format
+msgid "Removing %s"
+msgstr "删除 %s"
+
+#: merge-recursive.c:1766
+msgid "file/directory"
+msgstr "文件/目录"
+
+#: merge-recursive.c:1772
+msgid "directory/file"
+msgstr "目录/文件"
+
+#: merge-recursive.c:1777
+#, c-format
+msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
+msgstr "冲突(%1$s):在 %3$s 中有一个名为 %2$s 的目录。以 %5$s 为名添加 %4$s"
+
+#: merge-recursive.c:1787
+#, c-format
+msgid "Adding %s"
+msgstr "添加 %s"
+
+#: merge-recursive.c:1804
+msgid "Fatal merge failure, shouldn't happen."
+msgstr "严重的合并错误,不应发生。"
+
+#: merge-recursive.c:1823
+msgid "Already up-to-date!"
+msgstr "已经是最新的!"
+
+#: merge-recursive.c:1832
+#, c-format
+msgid "merging of trees %s and %s failed"
+msgstr "无法合并树 %s 和 %s"
+
+#: merge-recursive.c:1862
+#, c-format
+msgid "Unprocessed path??? %s"
+msgstr "未处理的路径??? %s"
+
+#: merge-recursive.c:1907
+msgid "Merging:"
+msgstr "合并:"
+
+#: merge-recursive.c:1920
+#, c-format
+msgid "found %u common ancestor:"
+msgid_plural "found %u common ancestors:"
+msgstr[0] "发现 %u 个共同祖先:"
+msgstr[1] "发现 %u 个共同祖先:"
+
+#: merge-recursive.c:1957
+msgid "merge returned no commit"
+msgstr "合并未返回提交"
+
+#: merge-recursive.c:2014
+#, c-format
+msgid "Could not parse object '%s'"
+msgstr "不能解析对象 '%s'"
+
+#: merge-recursive.c:2026 builtin/merge.c:697
+msgid "Unable to write index."
+msgstr "不能写入索引。"
+
+#: parse-options.c:494
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:511
+#: parse-options.c:512
 #, c-format
 msgid "usage: %s"
 msgstr "用法:%s"
 
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation
-#: parse-options.c:515
+#: parse-options.c:516
 #, c-format
 msgid "   or: %s"
 msgstr "  或:%s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: parse-options.c:518
+#: parse-options.c:519
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: remote.c:1629
+#: remote.c:1632
 #, 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] "您的分支领先 '%s' 共 %d 个提交。\n"
 msgstr[1] "您的分支领先 '%s' 共 %d 个提交。\n"
 
-#: remote.c:1635
+#: remote.c:1638
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -389,7 +651,7 @@ msgid_plural ""
 msgstr[0] "您的分支落后 '%s' 共 %d 个提交,并且可以快进。\n"
 msgstr[1] "您的分支落后 '%s' 共 %d 个提交,并且可以快进。\n"
 
-#: remote.c:1643
+#: remote.c:1646
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -612,7 +874,7 @@ msgstr "不能解析 HEAD"
 msgid "cannot abort from a branch yet to be born"
 msgstr "不能从尚未建立的分支终止"
 
-#: sequencer.c:805 builtin/apply.c:3697
+#: sequencer.c:805 builtin/apply.c:3988
 #, c-format
 msgid "cannot open %s: %s"
 msgstr "不能打开 %s:%s"
@@ -644,21 +906,21 @@ msgstr "不能作为初始提交还原"
 msgid "Can't cherry-pick into empty head"
 msgstr "不能拣选到空分支"
 
-#: sha1_name.c:864
+#: sha1_name.c:1044
 msgid "HEAD does not point to a branch"
 msgstr "HEAD 没有指向一个分支"
 
-#: sha1_name.c:867
+#: sha1_name.c:1047
 #, c-format
 msgid "No such branch: '%s'"
 msgstr "没有此分支:'%s'"
 
-#: sha1_name.c:869
+#: sha1_name.c:1049
 #, c-format
 msgid "No upstream configured for branch '%s'"
 msgstr "尚未给分支 '%s' 设置上游"
 
-#: sha1_name.c:872
+#: sha1_name.c:1052
 #, c-format
 msgid "Upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "上游分支 '%s' 没有存储为一个远程跟踪分支"
@@ -672,379 +934,378 @@ msgstr "无法在 passwd 文件中查询到当前用户:%s"
 msgid "no such user"
 msgstr "无此用户"
 
-#: wt-status.c:141
+#: wt-status.c:140
 msgid "Unmerged paths:"
 msgstr "未合并的路径:"
 
 #  译者:注意保持前导空格
-#: wt-status.c:168 wt-status.c:195
+#: wt-status.c:167 wt-status.c:194
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (使用 \"git reset %s <file>...\" 撤出暂存区)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:170 wt-status.c:197
+#: wt-status.c:169 wt-status.c:196
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (使用 \"git rm --cached <file>...\" 撤出暂存区)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:174
+#: wt-status.c:173
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (使用 \"git add <file>...\" 标记解决方案)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:176 wt-status.c:180
+#: wt-status.c:175 wt-status.c:179
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr "  (酌情使用 \"git add/rm <file>...\" 标记解决方案)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:178
+#: wt-status.c:177
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (使用 \"git rm <file>...\" 标记解决方案)"
 
-#: wt-status.c:189
+#: wt-status.c:188
 msgid "Changes to be committed:"
 msgstr "要提交的变更:"
 
-#: wt-status.c:207
+#: wt-status.c:206
 msgid "Changes not staged for commit:"
 msgstr "尚未暂存以备提交的变更:"
 
 #  译者:注意保持前导空格
-#: wt-status.c:211
+#: wt-status.c:210
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr "  (使用 \"git add <file>...\" 更新要提交的内容)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:213
+#: wt-status.c:212
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr "  (使用 \"git add/rm <file>...\" 更新要提交的内容)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:214
+#: wt-status.c:213
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr "  (使用 \"git checkout -- <file>...\" 丢弃工作区的改动)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:216
+#: wt-status.c:215
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr "  (提交或丢弃子模组中未跟踪或修改的内容)"
 
-#: wt-status.c:225
+#: wt-status.c:224
 #, c-format
 msgid "%s files:"
 msgstr "%s文件:"
 
 #  译者:注意保持前导空格
-#: wt-status.c:228
+#: wt-status.c:227
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr "  (使用 \"git %s <file>...\" 以包含要提交的内容)"
 
-#: wt-status.c:245
+#: wt-status.c:244
 msgid "bug"
 msgstr "bug"
 
-#: wt-status.c:250
+#: wt-status.c:249
 msgid "both deleted:"
 msgstr "双方删除:"
 
-#: wt-status.c:251
+#: wt-status.c:250
 msgid "added by us:"
 msgstr "由我们添加:"
 
-#: wt-status.c:252
+#: wt-status.c:251
 msgid "deleted by them:"
 msgstr "由他们删除:"
 
-#: wt-status.c:253
+#: wt-status.c:252
 msgid "added by them:"
 msgstr "由他们添加:"
 
-#: wt-status.c:254
+#: wt-status.c:253
 msgid "deleted by us:"
 msgstr "由我们删除:"
 
-#: wt-status.c:255
+#: wt-status.c:254
 msgid "both added:"
 msgstr "双方添加:"
 
-#: wt-status.c:256
+#: wt-status.c:255
 msgid "both modified:"
 msgstr "双方修改:"
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:286
+#: wt-status.c:285
 msgid "new commits, "
 msgstr "新提交, "
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:288
+#: wt-status.c:287
 msgid "modified content, "
 msgstr "修改的内容, "
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:290
+#: wt-status.c:289
 msgid "untracked content, "
 msgstr "未跟踪的内容, "
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:304
+#: wt-status.c:303
 #, c-format
 msgid "new file:   %s"
 msgstr "新文件:    %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:307
+#: wt-status.c:306
 #, c-format
 msgid "copied:     %s -> %s"
 msgstr "拷贝:      %s -> %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:310
+#: wt-status.c:309
 #, c-format
 msgid "deleted:    %s"
 msgstr "删除:      %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:313
+#: wt-status.c:312
 #, c-format
 msgid "modified:   %s"
 msgstr "修改:      %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:316
+#: wt-status.c:315
 #, c-format
 msgid "renamed:    %s -> %s"
 msgstr "重命名:    %s -> %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:319
+#: wt-status.c:318
 #, c-format
 msgid "typechange: %s"
 msgstr "类型变更:  %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:322
+#: wt-status.c:321
 #, c-format
 msgid "unknown:    %s"
 msgstr "未知:      %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: wt-status.c:325
+#: wt-status.c:324
 #, c-format
 msgid "unmerged:   %s"
 msgstr "未合并:    %s"
 
-#: wt-status.c:328
+#: wt-status.c:327
 #, c-format
 msgid "bug: unhandled diff status %c"
 msgstr "bug:未处理的差异状态 %c"
 
-#: wt-status.c:786
+#: wt-status.c:785
 msgid "You have unmerged paths."
 msgstr "您有路径尚未合并。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:789 wt-status.c:913
+#: wt-status.c:788 wt-status.c:912
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (解决冲突并运行 \"git commit\")"
 
-#: wt-status.c:792
+#: wt-status.c:791
 msgid "All conflicts fixed but you are still merging."
 msgstr "所有冲突已解决但您仍处于合并中。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:795
+#: wt-status.c:794
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (使用 \"git commit\" 结束合并)"
 
-#: wt-status.c:805
+#: wt-status.c:804
 msgid "You are in the middle of an am session."
 msgstr "您正处于一个 am 过程中。"
 
-#: wt-status.c:808
+#: wt-status.c:807
 msgid "The current patch is empty."
 msgstr "当前的补丁为空。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:812
+#: wt-status.c:811
 msgid "  (fix conflicts and then run \"git am --resolved\")"
 msgstr "  (解决冲突,然后运行 \"git am --resolved\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:814
+#: wt-status.c:813
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (使用 \"git am --skip\" 跳过此补丁)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:816
+#: wt-status.c:815
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (使用 \"git am --abort\" 恢复原有分支)"
 
-#: wt-status.c:874 wt-status.c:884
+#: wt-status.c:873 wt-status.c:883
 msgid "You are currently rebasing."
 msgstr "您正在变基。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:877
+#: wt-status.c:876
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (解决冲突,然后运行 \"git rebase --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:879
+#: wt-status.c:878
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (使用 \"git rebase --skip\" 跳过此补丁)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:881
+#: wt-status.c:880
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (使用 \"git rebase --abort\" 以检出原有分支)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:887
+#: wt-status.c:886
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (所有冲突已解决:运行 \"git rebase --continue\")"
 
-#: wt-status.c:889
+#: wt-status.c:888
 msgid "You are currently splitting a commit during a rebase."
 msgstr "您正在变基过程中拆分一个提交。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:892
+#: wt-status.c:891
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr "  (一旦您工作目录提交干净后,运行 \"git rebase --continue\")"
 
-#: wt-status.c:894
+#: wt-status.c:893
 msgid "You are currently editing a commit during a rebase."
 msgstr "您正在变基过程中编辑一个提交。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:897
+#: wt-status.c:896
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (使用 \"git commit --amend\" 修补当前提交)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:899
+#: wt-status.c:898
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
-msgstr ""
-"  (执行 \"git rebase --continue\" 一旦您满意您的修改)"
+msgstr "  (执行 \"git rebase --continue\" 一旦您满意您的修改)"
 
-#: wt-status.c:909
+#: wt-status.c:908
 msgid "You are currently cherry-picking."
 msgstr "您正在做拣选操作。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:916
+#: wt-status.c:915
 msgid "  (all conflicts fixed: run \"git commit\")"
 msgstr "  (解决所有冲突后,执行 \"git commit\")"
 
-#: wt-status.c:925
+#: wt-status.c:924
 msgid "You are currently bisecting."
 msgstr "您正在做二分查找。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:928
+#: wt-status.c:927
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (使用 \"git bisect reset\" 以回到原有分支)"
 
-#: wt-status.c:979
+#: wt-status.c:978
 msgid "On branch "
 msgstr "位于分支 "
 
-#: wt-status.c:986
+#: wt-status.c:985
 msgid "Not currently on any branch."
 msgstr "当前不在任何分支上。"
 
-#: wt-status.c:998
+#: wt-status.c:997
 msgid "Initial commit"
 msgstr "初始提交"
 
-#: wt-status.c:1012
+#: wt-status.c:1011
 msgid "Untracked"
 msgstr "未跟踪的"
 
-#: wt-status.c:1014
+#: wt-status.c:1013
 msgid "Ignored"
 msgstr "忽略的"
 
-#: wt-status.c:1016
+#: wt-status.c:1015
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "未跟踪的文件没有列出%s"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1018
+#: wt-status.c:1017
 msgid " (use -u option to show untracked files)"
 msgstr "(使用 -u 参数显示未跟踪的文件)"
 
-#: wt-status.c:1024
+#: wt-status.c:1023
 msgid "No changes"
 msgstr "没有修改"
 
-#: wt-status.c:1028
+#: wt-status.c:1027
 #, c-format
 msgid "no changes added to commit%s\n"
 msgstr "修改尚未加入提交%s\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1030
+#: wt-status.c:1029
 msgid " (use \"git add\" and/or \"git commit -a\")"
 msgstr "(使用 \"git add\" 和/或 \"git commit -a\")"
 
-#: wt-status.c:1032
+#: wt-status.c:1031
 #, c-format
 msgid "nothing added to commit but untracked files present%s\n"
 msgstr "空提交但存在未跟踪文件%s\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1034
+#: wt-status.c:1033
 msgid " (use \"git add\" to track)"
 msgstr "(使用 \"git add\" 建立跟踪)"
 
-#: wt-status.c:1036 wt-status.c:1039 wt-status.c:1042
+#: wt-status.c:1035 wt-status.c:1038 wt-status.c:1041
 #, c-format
 msgid "nothing to commit%s\n"
 msgstr "无须提交%s\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1037
+#: wt-status.c:1036
 msgid " (create/copy files and use \"git add\" to track)"
 msgstr "(新建/拷贝的文件使用 \"git add\" 建立跟踪)"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1040
+#: wt-status.c:1039
 msgid " (use -u to show untracked files)"
 msgstr "(使用 -u 显示未跟踪文件)"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1043
+#: wt-status.c:1042
 msgid " (working directory clean)"
 msgstr "(干净的工作区)"
 
-#: wt-status.c:1151
+#: wt-status.c:1150
 msgid "HEAD (no branch)"
 msgstr "HEAD(非分支)"
 
 #  译者:注意保持句尾空格
-#: wt-status.c:1157
+#: wt-status.c:1156
 msgid "Initial commit on "
 msgstr "初始提交于 "
 
 #  译者:注意保持句尾空格
-#: wt-status.c:1172
+#: wt-status.c:1171
 msgid "behind "
 msgstr "落后 "
 
 #  译者:注意保持句尾空格
-#: wt-status.c:1175 wt-status.c:1178
+#: wt-status.c:1174 wt-status.c:1177
 msgid "ahead "
 msgstr "领先 "
 
 #  译者:注意保持句尾空格
-#: wt-status.c:1180
+#: wt-status.c:1179
 msgid ", behind "
 msgstr ",落后 "
 
@@ -1053,7 +1314,7 @@ msgstr ",落后 "
 msgid "unexpected diff status %c"
 msgstr "意外的差异状态 %c"
 
-#: builtin/add.c:67 builtin/commit.c:226
+#: builtin/add.c:67 builtin/commit.c:229
 msgid "updating files failed"
 msgstr "更新文件失败"
 
@@ -1131,7 +1392,7 @@ msgstr "-A 和 -u 选项互斥"
 
 #: builtin/add.c:393
 msgid "Option --ignore-missing can only be used together with --dry-run"
-msgstr "é\80\89项 --ignore-missing å\8fªè\83½å\92\8c --dry-run å\85±用"
+msgstr "é\80\89项 --ignore-missing å\8fªè\83½å\92\8c --dry-run å\90\8cæ\97¶ä½¿用"
 
 #: builtin/add.c:413
 #, c-format
@@ -1143,75 +1404,75 @@ msgstr "没有指定文件,也没有文件被添加。\n"
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "也许您想要执行 'git add .'?\n"
 
-#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:286 builtin/mv.c:82
+#: builtin/add.c:420 builtin/clean.c:95 builtin/commit.c:289 builtin/mv.c:82
 #: builtin/rm.c:162
 msgid "index file corrupt"
 msgstr "索引文件损坏"
 
-#: builtin/add.c:480 builtin/apply.c:4108 builtin/mv.c:229 builtin/rm.c:260
+#: builtin/add.c:480 builtin/apply.c:4433 builtin/mv.c:229 builtin/rm.c:260
 msgid "Unable to write new index file"
 msgstr "无法写入新索引文件"
 
-#: builtin/apply.c:53
+#: builtin/apply.c:57
 msgid "git apply [options] [<patch>...]"
 msgstr "git apply [选项] [<补丁>...]"
 
-#: builtin/apply.c:106
+#: builtin/apply.c:110
 #, c-format
 msgid "unrecognized whitespace option '%s'"
 msgstr "未能识别的空白字符选项 '%s'"
 
-#: builtin/apply.c:121
+#: builtin/apply.c:125
 #, c-format
 msgid "unrecognized whitespace ignore option '%s'"
 msgstr "未能识别的空白字符忽略选项 '%s'"
 
-#: builtin/apply.c:815
+#: builtin/apply.c:824
 #, c-format
 msgid "Cannot prepare timestamp regexp %s"
 msgstr "无法准备时间戳正则表达式 %s"
 
-#: builtin/apply.c:824
+#: builtin/apply.c:833
 #, c-format
 msgid "regexec returned %d for input: %s"
 msgstr "regexec 返回 %d,输入为:%s"
 
-#: builtin/apply.c:905
+#: builtin/apply.c:914
 #, c-format
 msgid "unable to find filename in patch at line %d"
 msgstr "不能在补丁的第 %d 行找到文件名"
 
-#: builtin/apply.c:937
+#: builtin/apply.c:946
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
 msgstr "git apply:错误的 git-diff - 期望 /dev/null,但在第 %2$d 行得到 %1$s"
 
-#: builtin/apply.c:941
+#: builtin/apply.c:950
 #, c-format
 msgid "git apply: bad git-diff - inconsistent new filename on line %d"
 msgstr "git apply:错误的 git-diff - 第 %d 行上新文件名不一致"
 
-#: builtin/apply.c:942
+#: builtin/apply.c:951
 #, c-format
 msgid "git apply: bad git-diff - inconsistent old filename on line %d"
 msgstr "git apply:错误的 git-diff - 第 %d 行上旧文件名不一致"
 
-#: builtin/apply.c:949
+#: builtin/apply.c:958
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null on line %d"
 msgstr "git apply:错误的 git-diff - 期望 /dev/null 于第 %d 行"
 
-#: builtin/apply.c:1394
+#: builtin/apply.c:1403
 #, c-format
 msgid "recount: unexpected line: %.*s"
 msgstr "recount:意外的行:%.*s"
 
-#: builtin/apply.c:1451
+#: builtin/apply.c:1460
 #, c-format
 msgid "patch fragment without header at line %d: %.*s"
 msgstr "第 %d 行的补丁片段没有头信息:%.*s"
 
-#: builtin/apply.c:1468
+#: builtin/apply.c:1477
 #, c-format
 msgid ""
 "git diff header lacks filename information when removing %d leading pathname "
@@ -1222,82 +1483,82 @@ msgid_plural ""
 msgstr[0] "当移除 %d 个前导路径后 git diff 头缺乏文件名信息(第 %d 行)"
 msgstr[1] "当移除 %d 个前导路径后 git diff 头缺乏文件名信息(第 %d 行)"
 
-#: builtin/apply.c:1628
+#: builtin/apply.c:1637
 msgid "new file depends on old contents"
 msgstr "新文件依赖旧内容"
 
-#: builtin/apply.c:1630
+#: builtin/apply.c:1639
 msgid "deleted file still has contents"
 msgstr "删除的文件仍有内容"
 
-#: builtin/apply.c:1656
+#: builtin/apply.c:1665
 #, c-format
 msgid "corrupt patch at line %d"
 msgstr "补丁损坏位于第 %d 行"
 
-#: builtin/apply.c:1692
+#: builtin/apply.c:1701
 #, c-format
 msgid "new file %s depends on old contents"
 msgstr "新文件 %s 依赖旧内容"
 
-#: builtin/apply.c:1694
+#: builtin/apply.c:1703
 #, c-format
 msgid "deleted file %s still has contents"
 msgstr "删除的文件 %s 仍有内容"
 
-#: builtin/apply.c:1697
+#: builtin/apply.c:1706
 #, c-format
 msgid "** warning: file %s becomes empty but is not deleted"
 msgstr "** 警告:文件 %s 成为空文件但并未删除"
 
-#: builtin/apply.c:1843
+#: builtin/apply.c:1852
 #, c-format
 msgid "corrupt binary patch at line %d: %.*s"
 msgstr "二进制补丁在第 %d 行损坏:%.*s"
 
 #. there has to be one hunk (forward hunk)
-#: builtin/apply.c:1872
+#: builtin/apply.c:1881
 #, c-format
 msgid "unrecognized binary patch at line %d"
 msgstr "未能识别的二进制补丁位于第 %d 行"
 
-#: builtin/apply.c:1958
+#: builtin/apply.c:1967
 #, c-format
 msgid "patch with only garbage at line %d"
 msgstr "补丁文件的第 %d 行只有垃圾数据"
 
-#: builtin/apply.c:2048
+#: builtin/apply.c:2057
 #, c-format
 msgid "unable to read symlink %s"
 msgstr "无法读取符号链接 %s"
 
-#: builtin/apply.c:2052
+#: builtin/apply.c:2061
 #, c-format
 msgid "unable to open or read %s"
 msgstr "不能打开或读取 %s"
 
-#: builtin/apply.c:2123
+#: builtin/apply.c:2132
 msgid "oops"
 msgstr "哎哟"
 
-#: builtin/apply.c:2645
+#: builtin/apply.c:2654
 #, c-format
 msgid "invalid start of line: '%c'"
 msgstr "无效的行首字符:'%c'"
 
-#: builtin/apply.c:2763
+#: builtin/apply.c:2772
 #, c-format
 msgid "Hunk #%d succeeded at %d (offset %d line)."
 msgid_plural "Hunk #%d succeeded at %d (offset %d lines)."
 msgstr[0] "块 #%d 成功应用于 %d (偏移 %d 行)"
 msgstr[1] "块 #%d 成功应用于 %d (偏移 %d 行)"
 
-#: builtin/apply.c:2775
+#: builtin/apply.c:2784
 #, c-format
 msgid "Context reduced to (%ld/%ld) to apply fragment at %d"
 msgstr "上下文减少到(%ld/%ld)以在第 %d 行应用补丁片段"
 
-#: builtin/apply.c:2781
+#: builtin/apply.c:2790
 #, c-format
 msgid ""
 "while searching for:\n"
@@ -1306,313 +1567,321 @@ msgstr ""
 "当查询:\n"
 "%.*s"
 
-#: builtin/apply.c:2800
+#: builtin/apply.c:2809
 #, c-format
 msgid "missing binary patch data for '%s'"
 msgstr "缺失 '%s' 的二进制补丁数据"
 
-#: builtin/apply.c:2903
+#: builtin/apply.c:2912
 #, c-format
 msgid "binary patch does not apply to '%s'"
 msgstr "二进制补丁未应用到 '%s'"
 
-#: builtin/apply.c:2909
+#: builtin/apply.c:2918
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
 msgstr "到 '%s' 的二进制补丁产生了不正确的结果(预期 %s,得到 %s)"
 
-#: builtin/apply.c:2930
+#: builtin/apply.c:2939
 #, c-format
 msgid "patch failed: %s:%ld"
 msgstr "打补丁失败:%s:%ld"
 
-#: builtin/apply.c:3045
+#: builtin/apply.c:3061
 #, c-format
-msgid "patch %s has been renamed/deleted"
-msgstr "补丁 %s 已经被重命名/删除"
+msgid "cannot checkout %s"
+msgstr "不能检出 %s"
 
-#: builtin/apply.c:3052 builtin/apply.c:3069
+#: builtin/apply.c:3106 builtin/apply.c:3115 builtin/apply.c:3159
 #, c-format
 msgid "read of %s failed"
 msgstr "读取 %s 失败"
 
-#: builtin/apply.c:3084
-msgid "removal patch leaves file contents"
-msgstr "移除补丁仍留下了文件内容"
-
-#: builtin/apply.c:3105
+#: builtin/apply.c:3139 builtin/apply.c:3361
 #, c-format
-msgid "%s: already exists in working directory"
-msgstr "%s:已经存在于工作区中"
+msgid "path %s has been renamed/deleted"
+msgstr "路径 %s 已经被重命名/删除"
 
-#: builtin/apply.c:3143
+#: builtin/apply.c:3220 builtin/apply.c:3375
 #, c-format
-msgid "%s: has been deleted/renamed"
-msgstr "%s:已经被删除/重命名"
+msgid "%s: does not exist in index"
+msgstr "%s:不存在于索引中"
 
-#: builtin/apply.c:3148 builtin/apply.c:3179
+#: builtin/apply.c:3224 builtin/apply.c:3367 builtin/apply.c:3389
 #, c-format
 msgid "%s: %s"
 msgstr "%s:%s"
 
-#: builtin/apply.c:3159
-#, c-format
-msgid "%s: does not exist in index"
-msgstr "%s:不存在于索引中"
-
-#: builtin/apply.c:3173
+#: builtin/apply.c:3229 builtin/apply.c:3383
 #, c-format
 msgid "%s: does not match index"
 msgstr "%s:和索引不匹配"
 
-#: builtin/apply.c:3190
+#: builtin/apply.c:3331
+msgid "removal patch leaves file contents"
+msgstr "移除补丁仍留下了文件内容"
+
+#: builtin/apply.c:3400
 #, c-format
 msgid "%s: wrong type"
 msgstr "%s:错误类型"
 
-#: builtin/apply.c:3192
+#: builtin/apply.c:3402
 #, c-format
 msgid "%s has type %o, expected %o"
 msgstr "%s 的类型是 %o,预期是 %o"
 
-#: builtin/apply.c:3247
+#: builtin/apply.c:3503
 #, c-format
 msgid "%s: already exists in index"
 msgstr "%s:已经存在于索引中"
 
-#: builtin/apply.c:3267
+#: builtin/apply.c:3506
+#, c-format
+msgid "%s: already exists in working directory"
+msgstr "%s:已经存在于工作区中"
+
+#: builtin/apply.c:3526
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o)"
 msgstr "%2$s 的新模式(%1$o)和旧模式(%3$o)不匹配"
 
-#: builtin/apply.c:3272
+#: builtin/apply.c:3531
 #, c-format
 msgid "new mode (%o) of %s does not match old mode (%o) of %s"
 msgstr "%2$s 的新模式(%1$o)和 %4$s 的旧模式(%3$o)不匹配"
 
-#: builtin/apply.c:3280
+#: builtin/apply.c:3539
 #, c-format
 msgid "%s: patch does not apply"
 msgstr "%s:补丁未应用"
 
-#: builtin/apply.c:3293
+#: builtin/apply.c:3552
 #, c-format
 msgid "Checking patch %s..."
 msgstr "检查补丁 %s..."
 
-#: builtin/apply.c:3348 builtin/checkout.c:212 builtin/reset.c:158
+#: builtin/apply.c:3607 builtin/checkout.c:213 builtin/reset.c:158
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
 msgstr "对路径 '%s' 的 make_cache_entry 操作失败"
 
-#: builtin/apply.c:3491
+#: builtin/apply.c:3750
 #, c-format
 msgid "unable to remove %s from index"
 msgstr "不能从索引中移除 %s"
 
-#: builtin/apply.c:3518
+#: builtin/apply.c:3778
 #, c-format
 msgid "corrupt patch for subproject %s"
 msgstr "子项目 %s 损坏的补丁"
 
-#: builtin/apply.c:3522
+#: builtin/apply.c:3782
 #, c-format
 msgid "unable to stat newly created file '%s'"
 msgstr "不能枚举新建文件 '%s' 的状态"
 
-#: builtin/apply.c:3527
+#: builtin/apply.c:3787
 #, c-format
 msgid "unable to create backing store for newly created file %s"
 msgstr "不能为新建文件 %s 创建后端存储"
 
-#: builtin/apply.c:3530
+#: builtin/apply.c:3790 builtin/apply.c:3898
 #, c-format
 msgid "unable to add cache entry for %s"
 msgstr "无法为 %s 添加缓存条目"
 
-#: builtin/apply.c:3563
+#: builtin/apply.c:3823
 #, c-format
 msgid "closing file '%s'"
 msgstr "关闭文件 '%s'"
 
-#: builtin/apply.c:3612
+#: builtin/apply.c:3872
 #, c-format
 msgid "unable to write file '%s' mode %o"
 msgstr "不能写文件 '%s' 权限 %o"
 
-#: builtin/apply.c:3668
+#: builtin/apply.c:3959
 #, c-format
 msgid "Applied patch %s cleanly."
 msgstr "成功应用补丁 %s。"
 
-#: builtin/apply.c:3676
+#: builtin/apply.c:3967
 msgid "internal error"
 msgstr "内部错误"
 
 #. Say this even without --verbose
-#: builtin/apply.c:3679
+#: builtin/apply.c:3970
 #, c-format
 msgid "Applying patch %%s with %d reject..."
 msgid_plural "Applying patch %%s with %d rejects..."
 msgstr[0] "应用补丁 %%s 时 %d 个被拒绝..."
 msgstr[1] "应用补丁 %%s 时 %d 个被拒绝..."
 
-#: builtin/apply.c:3689
+#: builtin/apply.c:3980
 #, c-format
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "截短 .rej 文件名为 %.*s.rej"
 
-#: builtin/apply.c:3710
+#: builtin/apply.c:4001
 #, c-format
 msgid "Hunk #%d applied cleanly."
 msgstr "第 #%d 个片段成功应用。"
 
-#: builtin/apply.c:3713
+#: builtin/apply.c:4004
 #, c-format
 msgid "Rejected hunk #%d."
 msgstr "拒绝第 #%d 个片段。"
 
-#: builtin/apply.c:3844
+#: builtin/apply.c:4154
 msgid "unrecognized input"
 msgstr "未能识别的输入"
 
-#: builtin/apply.c:3855
+#: builtin/apply.c:4165
 msgid "unable to read index file"
 msgstr "无法读取索引文件"
 
-#: builtin/apply.c:3970 builtin/apply.c:3973
+#: builtin/apply.c:4284 builtin/apply.c:4287
 msgid "path"
 msgstr "路径"
 
-#: builtin/apply.c:3971
+#: builtin/apply.c:4285
 msgid "don't apply changes matching the given path"
 msgstr "不要应用与给出路径向匹配的变更"
 
-#: builtin/apply.c:3974
+#: builtin/apply.c:4288
 msgid "apply changes matching the given path"
 msgstr "应用与给出路径向匹配的变更"
 
-#: builtin/apply.c:3976
+#: builtin/apply.c:4290
 msgid "num"
 msgstr "数字"
 
-#: builtin/apply.c:3977
+#: builtin/apply.c:4291
 msgid "remove <num> leading slashes from traditional diff paths"
 msgstr "从传统的 diff 路径中移除 <数字> 个前导路径"
 
-#: builtin/apply.c:3980
+#: builtin/apply.c:4294
 msgid "ignore additions made by the patch"
 msgstr "忽略补丁中的添加的文件"
 
-#: builtin/apply.c:3982
+#: builtin/apply.c:4296
 msgid "instead of applying the patch, output diffstat for the input"
 msgstr "不应用补丁,而是显示输入的差异统计(diffstat)"
 
-#: builtin/apply.c:3986
+#: builtin/apply.c:4300
 msgid "shows number of added and deleted lines in decimal notation"
 msgstr "以数字方式显示添加或删除行的数量"
 
-#: builtin/apply.c:3988
+#: builtin/apply.c:4302
 msgid "instead of applying the patch, output a summary for the input"
 msgstr "不应用补丁,而是显示输入的概要"
 
-#: builtin/apply.c:3990
+#: builtin/apply.c:4304
 msgid "instead of applying the patch, see if the patch is applicable"
 msgstr "不应用补丁,而是查看补丁是否可应用"
 
-#: builtin/apply.c:3992
+#: builtin/apply.c:4306
 msgid "make sure the patch is applicable to the current index"
 msgstr "确认补丁可以应用到当前索引"
 
-#: builtin/apply.c:3994
+#: builtin/apply.c:4308
 msgid "apply a patch without touching the working tree"
 msgstr "应用补丁而不修改工作区"
 
-#: builtin/apply.c:3996
+#: builtin/apply.c:4310
 msgid "also apply the patch (use with --stat/--summary/--check)"
-msgstr "同时应用此补丁(和 --stat/--summary/--check 共用)"
+msgstr "还应用此补丁(使用 --stat/--summary/--check 参数)"
+
+#: builtin/apply.c:4312
+msgid "attempt three-way merge if a patch does not apply"
+msgstr "如果一个补丁不能应用则尝试三路合并"
 
-#: builtin/apply.c:3998
+#: builtin/apply.c:4314
 msgid "build a temporary index based on embedded index information"
 msgstr "创建一个临时索引基于嵌入的索引信息"
 
-#: builtin/apply.c:4000
+#: builtin/apply.c:4316
 msgid "paths are separated with NUL character"
 msgstr "路径以 NUL 字符分隔"
 
-#: builtin/apply.c:4003
+#: builtin/apply.c:4319
 msgid "ensure at least <n> lines of context match"
 msgstr "确保至少匹配 <n> 行上下文"
 
-#: builtin/apply.c:4004
+#: builtin/apply.c:4320
 msgid "action"
 msgstr "动作"
 
-#: builtin/apply.c:4005
+#: builtin/apply.c:4321
 msgid "detect new or modified lines that have whitespace errors"
 msgstr "检查新增和修改的行中间的空白字符滥用"
 
-#: builtin/apply.c:4008 builtin/apply.c:4011
+#: builtin/apply.c:4324 builtin/apply.c:4327
 msgid "ignore changes in whitespace when finding context"
 msgstr "查找上下文时忽略空白字符的变更"
 
-#: builtin/apply.c:4014
+#: builtin/apply.c:4330
 msgid "apply the patch in reverse"
 msgstr "反向应用补丁"
 
-#: builtin/apply.c:4016
+#: builtin/apply.c:4332
 msgid "don't expect at least one line of context"
 msgstr "无需至少一行上下文"
 
-#: builtin/apply.c:4018
+#: builtin/apply.c:4334
 msgid "leave the rejected hunks in corresponding *.rej files"
 msgstr "将拒绝的补丁片段保存在对应的 *.rej 文件中"
 
-#: builtin/apply.c:4020
+#: builtin/apply.c:4336
 msgid "allow overlapping hunks"
 msgstr "允许重叠的补丁片段"
 
-#: builtin/apply.c:4021
+#: builtin/apply.c:4337
 msgid "be verbose"
 msgstr "冗长输出"
 
-#: builtin/apply.c:4023
+#: builtin/apply.c:4339
 msgid "tolerate incorrectly detected missing new-line at the end of file"
 msgstr "宽容不正确的文件末尾换行符"
 
-#: builtin/apply.c:4026
+#: builtin/apply.c:4342
 msgid "do not trust the line counts in the hunk headers"
 msgstr "不信任补丁片段的头信息中的行号"
 
-#: builtin/apply.c:4028
+#: builtin/apply.c:4344
 msgid "root"
 msgstr "根目录"
 
-#: builtin/apply.c:4029
+#: builtin/apply.c:4345
 msgid "prepend <root> to all filenames"
 msgstr "为所有文件名前添加 <根目录>"
 
-#: builtin/apply.c:4050
+#: builtin/apply.c:4367
+msgid "--3way outside a repository"
+msgstr "--3way 在一个版本库之外"
+
+#: builtin/apply.c:4375
 msgid "--index outside a repository"
 msgstr "--index 在一个版本库之外"
 
-#: builtin/apply.c:4053
+#: builtin/apply.c:4378
 msgid "--cached outside a repository"
 msgstr "--cached 在一个版本库之外"
 
-#: builtin/apply.c:4069
+#: builtin/apply.c:4394
 #, c-format
 msgid "can't open patch '%s'"
 msgstr "不能打开补丁 '%s'"
 
-#: builtin/apply.c:4083
+#: builtin/apply.c:4408
 #, c-format
 msgid "squelched %d whitespace error"
 msgid_plural "squelched %d whitespace errors"
 msgstr[0] "抑制下仍有 %d 个空白字符误用"
 msgstr[1] "抑制下仍有 %d 个空白字符误用"
 
-#: builtin/apply.c:4089 builtin/apply.c:4099
+#: builtin/apply.c:4414 builtin/apply.c:4424
 #, c-format
 msgid "%d line adds whitespace errors."
 msgid_plural "%d lines add whitespace errors."
@@ -1676,7 +1945,7 @@ msgstr ""
 
 #: builtin/branch.c:180
 msgid "cannot use -a with -d"
-msgstr "ä¸\8dè\83½å°\86 -a å\92\8c -d å\85±用"
+msgstr "ä¸\8dè\83½å°\86 -a å\92\8c -d å\90\8cæ\97¶ä½¿用"
 
 #: builtin/branch.c:186
 msgid "Couldn't look up commit object for HEAD"
@@ -1819,7 +2088,7 @@ msgstr "不能写分支描述模版:%s"
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "无法将 HEAD 解析为有效引用。"
 
-#: builtin/branch.c:788 builtin/clone.c:558
+#: builtin/branch.c:788 builtin/clone.c:561
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD 没有位于 /refs/heads 之下!"
 
@@ -1844,100 +2113,100 @@ msgstr "需要一个版本库来创建包。"
 msgid "Need a repository to unbundle."
 msgstr "需要一个版本库来解包。"
 
-#: builtin/checkout.c:113 builtin/checkout.c:146
+#: builtin/checkout.c:114 builtin/checkout.c:147
 #, c-format
 msgid "path '%s' does not have our version"
 msgstr "路径 '%s' 没有我们的版本"
 
-#: builtin/checkout.c:115 builtin/checkout.c:148
+#: builtin/checkout.c:116 builtin/checkout.c:149
 #, c-format
 msgid "path '%s' does not have their version"
 msgstr "路径 '%s' 没有他们的版本"
 
-#: builtin/checkout.c:131
+#: builtin/checkout.c:132
 #, c-format
 msgid "path '%s' does not have all necessary versions"
 msgstr "路径 '%s' 没有全部必须的版本"
 
-#: builtin/checkout.c:175
+#: builtin/checkout.c:176
 #, c-format
 msgid "path '%s' does not have necessary versions"
 msgstr "路径 '%s' 没有必须的版本"
 
-#: builtin/checkout.c:192
+#: builtin/checkout.c:193
 #, c-format
 msgid "path '%s': cannot merge"
 msgstr "path '%s':无法合并"
 
-#: builtin/checkout.c:209
+#: builtin/checkout.c:210
 #, c-format
 msgid "Unable to add merge result for '%s'"
 msgstr "无法为 '%s' 添加合并结果"
 
-#: builtin/checkout.c:234 builtin/checkout.c:392
+#: builtin/checkout.c:235 builtin/checkout.c:393
 msgid "corrupt index file"
 msgstr "损坏的索引文件"
 
-#: builtin/checkout.c:264 builtin/checkout.c:271
+#: builtin/checkout.c:265 builtin/checkout.c:272
 #, c-format
 msgid "path '%s' is unmerged"
 msgstr "路径 '%s' 未合并"
 
-#: builtin/checkout.c:302 builtin/checkout.c:498 builtin/clone.c:583
+#: builtin/checkout.c:303 builtin/checkout.c:499 builtin/clone.c:586
 #: builtin/merge.c:812
 msgid "unable to write new index file"
 msgstr "无法写新的索引文件"
 
-#: builtin/checkout.c:319 builtin/diff.c:302 builtin/merge.c:408
+#: builtin/checkout.c:320 builtin/diff.c:302 builtin/merge.c:408
 msgid "diff_setup_done failed"
 msgstr "diff_setup_done 失败"
 
-#: builtin/checkout.c:414
+#: builtin/checkout.c:415
 msgid "you need to resolve your current index first"
 msgstr "您需要先解决当前索引的冲突"
 
-#: builtin/checkout.c:533
+#: builtin/checkout.c:534
 #, c-format
 msgid "Can not do reflog for '%s'\n"
 msgstr "不能对 '%s' 执行 reflog 操作\n"
 
-#: builtin/checkout.c:566
+#: builtin/checkout.c:567
 msgid "HEAD is now at"
 msgstr "HEAD 目前位于"
 
-#: builtin/checkout.c:573
+#: builtin/checkout.c:574
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "重置分支 '%s'\n"
 
-#: builtin/checkout.c:576
+#: builtin/checkout.c:577
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "已经位于 '%s'\n"
 
-#: builtin/checkout.c:580
+#: builtin/checkout.c:581
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "切换并重置分支 '%s'\n"
 
-#: builtin/checkout.c:582
+#: builtin/checkout.c:583
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "切换到一个新分支 '%s'\n"
 
-#: builtin/checkout.c:584
+#: builtin/checkout.c:585
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "切换到分支 '%s'\n"
 
 #  译者:注意保持前导空格
-#: builtin/checkout.c:640
+#: builtin/checkout.c:641
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... 及其它 %d 个。\n"
 
 #. The singular version
-#: builtin/checkout.c:646
+#: builtin/checkout.c:647
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -1958,7 +2227,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:664
+#: builtin/checkout.c:665
 #, c-format
 msgid ""
 "If you want to keep them by creating a new branch, this may be a good time\n"
@@ -1973,71 +2242,71 @@ msgstr ""
 " git branch new_branch_name %s\n"
 "\n"
 
-#: builtin/checkout.c:694
+#: builtin/checkout.c:695
 msgid "internal error in revision walk"
 msgstr "在版本遍历时遇到内部错误"
 
-#: builtin/checkout.c:698
+#: builtin/checkout.c:699
 msgid "Previous HEAD position was"
 msgstr "之前的 HEAD 位置是"
 
-#: builtin/checkout.c:724
+#: builtin/checkout.c:725 builtin/checkout.c:920
 msgid "You are on a branch yet to be born"
 msgstr "您位于一个尚未初始化的分支"
 
 #. case (1)
-#: builtin/checkout.c:855
+#: builtin/checkout.c:856
 #, c-format
 msgid "invalid reference: %s"
 msgstr "无效引用:%s"
 
 #. case (1): want a tree
-#: builtin/checkout.c:894
+#: builtin/checkout.c:895
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "引用不是一个树:%s"
 
-#: builtin/checkout.c:974
+#: builtin/checkout.c:977
 msgid "-B cannot be used with -b"
-msgstr "-B ä¸\8dè\83½å\92\8c -b å\85±用"
+msgstr "-B ä¸\8dè\83½å\92\8c -b å\90\8cæ\97¶ä½¿用"
 
-#: builtin/checkout.c:983
+#: builtin/checkout.c:986
 msgid "--patch is incompatible with all other options"
 msgstr "--patch 选项和其他选项不兼容"
 
-#: builtin/checkout.c:986
+#: builtin/checkout.c:989
 msgid "--detach cannot be used with -b/-B/--orphan"
-msgstr "--detach ä¸\8dè\83½å\92\8c -b/-B/--orphan å\85±用"
+msgstr "--detach ä¸\8dè\83½å\92\8c -b/-B/--orphan å\90\8cæ\97¶ä½¿用"
 
-#: builtin/checkout.c:988
+#: builtin/checkout.c:991
 msgid "--detach cannot be used with -t"
-msgstr "--detach ä¸\8dè\83½å\92\8c -t å\85±用"
+msgstr "--detach ä¸\8dè\83½å\92\8c -t å\90\8cæ\97¶ä½¿用"
 
-#: builtin/checkout.c:994
+#: builtin/checkout.c:997
 msgid "--track needs a branch name"
 msgstr "--track 需要一个分支名"
 
-#: builtin/checkout.c:1001
+#: builtin/checkout.c:1004
 msgid "Missing branch name; try -b"
 msgstr "缺少分支名;尝试 -b"
 
-#: builtin/checkout.c:1007
+#: builtin/checkout.c:1010
 msgid "--orphan and -b|-B are mutually exclusive"
 msgstr "--orphan 和 -b|-B 互斥"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1012
 msgid "--orphan cannot be used with -t"
-msgstr "--orphan ä¸\8dè\83½å\92\8c -t å\85±用"
+msgstr "--orphan ä¸\8dè\83½å\92\8c -t å\90\8cæ\97¶ä½¿用"
 
-#: builtin/checkout.c:1019
+#: builtin/checkout.c:1022
 msgid "git checkout: -f and -m are incompatible"
 msgstr "git checkout:-f 和 -m 不兼容"
 
-#: builtin/checkout.c:1053
+#: builtin/checkout.c:1056
 msgid "invalid path specification"
 msgstr "无效的路径规格"
 
-#: builtin/checkout.c:1061
+#: builtin/checkout.c:1064
 #, c-format
 msgid ""
 "git checkout: updating paths is incompatible with switching branches.\n"
@@ -2046,32 +2315,32 @@ msgstr ""
 "git checkout:更新路径和切换分支不兼容。\n"
 "您是想要检出 '%s' 但未能将其解析为提交么?"
 
-#: builtin/checkout.c:1063
+#: builtin/checkout.c:1066
 msgid "git checkout: updating paths is incompatible with switching branches."
 msgstr "git checkout:更新路径和切换分支不兼容。"
 
-#: builtin/checkout.c:1068
+#: builtin/checkout.c:1071
 msgid "git checkout: --detach does not take a path argument"
 msgstr "git checkout:--detach 不跟路径参数"
 
-#: builtin/checkout.c:1071
+#: builtin/checkout.c:1074
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
 msgstr ""
 "git checkout:在从索引检出时,--ours/--theirs、--force 和 --merge 不兼容。"
 
-#: builtin/checkout.c:1090
+#: builtin/checkout.c:1093
 msgid "Cannot switch branch to a non-commit."
 msgstr "无法切换分支到一个非提交。"
 
-#: builtin/checkout.c:1093
+#: builtin/checkout.c:1096
 msgid "--ours/--theirs is incompatible with switching branches."
 msgstr "--ours/--theirs 和切换分支不兼容。"
 
 #: builtin/clean.c:78
 msgid "-x and -X cannot be used together"
-msgstr "-x å\92\8c -X ä¸\8dè\83½å\85±用"
+msgstr "-x å\92\8c -X ä¸\8dè\83½å\90\8cæ\97¶ä½¿用"
 
 #: builtin/clean.c:82
 msgid ""
@@ -2116,11 +2385,6 @@ msgstr "未删除 %s\n"
 msgid "reference repository '%s' is not a local directory."
 msgstr "引用版本库 '%s' 不是一个本地目录。"
 
-#: builtin/clone.c:302
-#, c-format
-msgid "failed to open '%s'"
-msgstr "无法打开 '%s'"
-
 #: builtin/clone.c:306
 #, c-format
 msgid "failed to create directory '%s'"
@@ -2161,78 +2425,78 @@ msgstr "无法拷贝文件至 '%s'"
 msgid "done.\n"
 msgstr "完成。\n"
 
-#: builtin/clone.c:440
+#: builtin/clone.c:443
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "不能发现要克隆的远程分支 %s。"
 
-#: builtin/clone.c:549
+#: builtin/clone.c:552
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr "远程 HEAD 指向一个不存在的引用,无法检出。\n"
 
-#: builtin/clone.c:639
+#: builtin/clone.c:642
 msgid "Too many arguments."
 msgstr "太多参数。"
 
-#: builtin/clone.c:643
+#: builtin/clone.c:646
 msgid "You must specify a repository to clone."
 msgstr "您必须指定一个版本库来克隆。"
 
-#: builtin/clone.c:654
+#: builtin/clone.c:657
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "--bare 和 --origin %s 选项不兼容。"
 
-#: builtin/clone.c:668
+#: builtin/clone.c:671
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "版本库 '%s' 不存在"
 
-#: builtin/clone.c:673
+#: builtin/clone.c:676
 msgid "--depth is ignored in local clones; use file:// instead."
 msgstr "--depth 在本地克隆被忽略,改为 file:// 协议试试。"
 
-#: builtin/clone.c:683
+#: builtin/clone.c:686
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "目标路径 '%s' 已经存在,并且不是一个空目录。"
 
-#: builtin/clone.c:693
+#: builtin/clone.c:696
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "工作区 '%s' 已经存在。"
 
-#: builtin/clone.c:706 builtin/clone.c:720
+#: builtin/clone.c:709 builtin/clone.c:723
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "不能为 '%s' 创建先导目录"
 
-#: builtin/clone.c:709
+#: builtin/clone.c:712
 #, c-format
 msgid "could not create work tree dir '%s'."
 msgstr "不能为 '%s' 创建工作区目录。"
 
-#: builtin/clone.c:728
+#: builtin/clone.c:731
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "克隆到裸版本库 '%s'...\n"
 
-#: builtin/clone.c:730
+#: builtin/clone.c:733
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "正克隆到 '%s'...\n"
 
-#: builtin/clone.c:786
+#: builtin/clone.c:789
 #, c-format
 msgid "Don't know how to clone %s"
 msgstr "不知道如何克隆 %s"
 
-#: builtin/clone.c:835
+#: builtin/clone.c:838
 #, c-format
 msgid "Remote branch %s not found in upstream %s"
 msgstr "远程分支 %s 在上游 %s 未发现"
 
-#: builtin/clone.c:842
+#: builtin/clone.c:845
 msgid "You appear to have cloned an empty repository."
 msgstr "您似乎克隆了一个空版本库。"
 
@@ -2288,93 +2552,93 @@ msgstr ""
 "\n"
 "否则,请使用命令 'git reset'\n"
 
-#: builtin/commit.c:253
+#: builtin/commit.c:256
 msgid "failed to unpack HEAD tree object"
 msgstr "无法解包 HEAD 树对象"
 
-#: builtin/commit.c:295
+#: builtin/commit.c:298
 msgid "unable to create temporary index"
 msgstr "不能创建临时索引"
 
-#: builtin/commit.c:301
+#: builtin/commit.c:304
 msgid "interactive add failed"
 msgstr "交互式添加失败"
 
-#: builtin/commit.c:334 builtin/commit.c:355 builtin/commit.c:405
+#: builtin/commit.c:337 builtin/commit.c:358 builtin/commit.c:408
 msgid "unable to write new_index file"
 msgstr "无法写 new_index 文件"
 
-#: builtin/commit.c:386
+#: builtin/commit.c:389
 msgid "cannot do a partial commit during a merge."
 msgstr "在合并过程中不能做部分提交。"
 
-#: builtin/commit.c:388
+#: builtin/commit.c:391
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "在拣选过程中不能做部分提交。"
 
-#: builtin/commit.c:398
+#: builtin/commit.c:401
 msgid "cannot read the index"
 msgstr "无法读取索引"
 
-#: builtin/commit.c:418
+#: builtin/commit.c:421
 msgid "unable to write temporary index file"
 msgstr "无法写临时索引文件"
 
-#: builtin/commit.c:493 builtin/commit.c:499
+#: builtin/commit.c:496 builtin/commit.c:502
 #, c-format
 msgid "invalid commit: %s"
 msgstr "无效的提交:%s"
 
-#: builtin/commit.c:522
+#: builtin/commit.c:525
 msgid "malformed --author parameter"
 msgstr "非法的 --author 参数"
 
-#: builtin/commit.c:582
+#: builtin/commit.c:585
 #, c-format
 msgid "Malformed ident string: '%s'"
 msgstr "非法的身份字符串:'%s'"
 
-#: builtin/commit.c:620 builtin/commit.c:653 builtin/commit.c:967
+#: builtin/commit.c:623 builtin/commit.c:656 builtin/commit.c:970
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "不能查询提交 %s"
 
-#: builtin/commit.c:632 builtin/shortlog.c:296
+#: builtin/commit.c:635 builtin/shortlog.c:296
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(正从标准输入中读取日志信息)\n"
 
-#: builtin/commit.c:634
+#: builtin/commit.c:637
 msgid "could not read log from standard input"
 msgstr "不能从标准输入中读取日志信息"
 
-#: builtin/commit.c:638
+#: builtin/commit.c:641
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "不能读取日志文件 '%s'"
 
-#: builtin/commit.c:644
+#: builtin/commit.c:647
 msgid "commit has empty message"
 msgstr "提交说明为空"
 
-#: builtin/commit.c:660
+#: builtin/commit.c:663
 msgid "could not read MERGE_MSG"
 msgstr "不能读取 MERGE_MSG"
 
-#: builtin/commit.c:664
+#: builtin/commit.c:667
 msgid "could not read SQUASH_MSG"
 msgstr "不能读取 SQUASH_MSG"
 
-#: builtin/commit.c:668
+#: builtin/commit.c:671
 #, c-format
 msgid "could not read '%s'"
 msgstr "不能读取 '%s'"
 
-#: builtin/commit.c:720
+#: builtin/commit.c:723
 msgid "could not write commit template"
 msgstr "不能写提交模版"
 
-#: builtin/commit.c:731
+#: builtin/commit.c:734
 #, c-format
 msgid ""
 "\n"
@@ -2384,11 +2648,11 @@ msgid ""
 "and try again.\n"
 msgstr ""
 "\n"
-"看起来您正在做一个合并提交。如果不对,请删除文件\n"
+"似乎您正在做一个合并提交。如果不对,请删除文件\n"
 "\t%s\n"
 "然后重试。\n"
 
-#: builtin/commit.c:736
+#: builtin/commit.c:739
 #, c-format
 msgid ""
 "\n"
@@ -2398,11 +2662,11 @@ msgid ""
 "and try again.\n"
 msgstr ""
 "\n"
-"看起来您正在做一个拣选提交。如果不对,请删除文件\n"
+"似乎您正在做一个拣选提交。如果不对,请删除文件\n"
 "\t%s\n"
 "然后重试。\n"
 
-#: builtin/commit.c:748
+#: builtin/commit.c:751
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be ignored, and an empty message aborts the commit.\n"
@@ -2410,7 +2674,7 @@ msgstr ""
 "请为您的变更输入提交说明。以 '#' 开始的行将被忽略,而一个空的提交\n"
 "说明将会终止提交。\n"
 
-#: builtin/commit.c:753
+#: builtin/commit.c:756
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '#' will be kept; you may remove them yourself if you want to.\n"
@@ -2420,160 +2684,160 @@ msgstr ""
 "如果您想这样做的话。而一个空的提交说明将会终止提交。\n"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:766
+#: builtin/commit.c:769
 #, c-format
 msgid "%sAuthor:    %s"
 msgstr "%s作者:     %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:773
+#: builtin/commit.c:776
 #, c-format
 msgid "%sCommitter: %s"
 msgstr "%s提交者:   %s"
 
-#: builtin/commit.c:793
+#: builtin/commit.c:796
 msgid "Cannot read index"
 msgstr "无法读取索引"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:833
 msgid "Error building trees"
 msgstr "无法创建树对象"
 
-#: builtin/commit.c:845 builtin/tag.c:361
+#: builtin/commit.c:848 builtin/tag.c:361
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "请使用 -m 或者 -F 选项提供提交说明。\n"
 
-#: builtin/commit.c:942
+#: builtin/commit.c:945
 #, c-format
 msgid "No existing author found with '%s'"
 msgstr "没有找到匹配 '%s' 的作者"
 
-#: builtin/commit.c:957 builtin/commit.c:1157
+#: builtin/commit.c:960 builtin/commit.c:1160
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "无效的未追踪文件参数 '%s'"
 
-#: builtin/commit.c:997
+#: builtin/commit.c:1000
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "同时使用 --reset-author 和 --author 没有意义"
 
-#: builtin/commit.c:1008
+#: builtin/commit.c:1011
 msgid "You have nothing to amend."
 msgstr "您没有可修补的提交。"
 
-#: builtin/commit.c:1011
+#: builtin/commit.c:1014
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "您正处于一个合并过程中 -- 无法修补提交。"
 
-#: builtin/commit.c:1013
+#: builtin/commit.c:1016
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "您正处于一个拣选过程中 -- 无法修补提交。"
 
-#: builtin/commit.c:1016
+#: builtin/commit.c:1019
 msgid "Options --squash and --fixup cannot be used together"
-msgstr "é\80\89项 --squash å\92\8c --fixup ä¸\8dè\83½å\85±用"
+msgstr "é\80\89项 --squash å\92\8c --fixup ä¸\8dè\83½å\90\8cæ\97¶ä½¿用"
 
-#: builtin/commit.c:1026
+#: builtin/commit.c:1029
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "只能用一个 -c/-C/-F/--fixup 选项。"
 
-#: builtin/commit.c:1028
+#: builtin/commit.c:1031
 msgid "Option -m cannot be combined with -c/-C/-F/--fixup."
-msgstr "é\80\89项 -m ä¸\8dè\83½å\92\8c -c/-C/-F/--fixup å\85±用。"
+msgstr "é\80\89项 -m ä¸\8dè\83½å\92\8c -c/-C/-F/--fixup å\90\8cæ\97¶ä½¿用。"
 
-#: builtin/commit.c:1036
+#: builtin/commit.c:1039
 msgid "--reset-author can be used only with -C, -c or --amend."
-msgstr "--reset-author å\8fªè\83½å\92\8c -Cã\80\81-c æ\88\96 --amend å\85±用。"
+msgstr "--reset-author å\8fªè\83½å\92\8c -Cã\80\81-c æ\88\96 --amend å\90\8cæ\97¶ä½¿用。"
 
-#: builtin/commit.c:1053
+#: builtin/commit.c:1056
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr "只能用一个 --include/--only/--all/--interactive/--patch 选项。"
 
-#: builtin/commit.c:1055
+#: builtin/commit.c:1058
 msgid "No paths with --include/--only does not make sense."
 msgstr "参数 --include/--only 不跟路径没有意义。"
 
-#: builtin/commit.c:1057
+#: builtin/commit.c:1060
 msgid "Clever... amending the last one with dirty index."
 msgstr "聪明... 在索引不干净下修补最后的提交。"
 
-#: builtin/commit.c:1059
+#: builtin/commit.c:1062
 msgid "Explicit paths specified without -i nor -o; assuming --only paths..."
 msgstr "指定了明确的路径而没有使用 -i 或 -o 选项;认为是 --only paths..."
 
-#: builtin/commit.c:1069 builtin/tag.c:577
+#: builtin/commit.c:1072 builtin/tag.c:577
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "无效的清理模式 %s"
 
-#: builtin/commit.c:1074
+#: builtin/commit.c:1077
 msgid "Paths with -a does not make sense."
-msgstr "è·¯å¾\84å\92\8c -a é\80\89项å\85±用没有意义。"
+msgstr "è·¯å¾\84å\92\8c -a é\80\89项å\90\8cæ\97¶ä½¿用没有意义。"
 
-#: builtin/commit.c:1257
+#: builtin/commit.c:1260
 msgid "couldn't look up newly created commit"
 msgstr "无法找到新创建的提交"
 
-#: builtin/commit.c:1259
+#: builtin/commit.c:1262
 msgid "could not parse newly created commit"
 msgstr "不能解析新创建的提交"
 
-#: builtin/commit.c:1300
+#: builtin/commit.c:1303
 msgid "detached HEAD"
 msgstr "分离头指针"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: builtin/commit.c:1302
+#: builtin/commit.c:1305
 msgid " (root-commit)"
 msgstr "(根提交)"
 
-#: builtin/commit.c:1446
+#: builtin/commit.c:1449
 msgid "could not parse HEAD commit"
 msgstr "不能解析 HEAD 提交"
 
-#: builtin/commit.c:1484 builtin/merge.c:509
+#: builtin/commit.c:1487 builtin/merge.c:509
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "不能为读入打开 '%s'"
 
-#: builtin/commit.c:1491
+#: builtin/commit.c:1494
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "损坏的 MERGE_HEAD 文件(%s)"
 
-#: builtin/commit.c:1498
+#: builtin/commit.c:1501
 msgid "could not read MERGE_MODE"
 msgstr "不能读取 MERGE_MODE"
 
-#: builtin/commit.c:1517
+#: builtin/commit.c:1520
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "不能读取提交说明:%s"
 
-#: builtin/commit.c:1531
+#: builtin/commit.c:1534
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "终止提交;您未更改来自模版的提交说明。\n"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1539
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "终止提交因为提交说明为空。\n"
 
-#: builtin/commit.c:1551 builtin/merge.c:936 builtin/merge.c:961
+#: builtin/commit.c:1554 builtin/merge.c:936 builtin/merge.c:961
 msgid "failed to write commit object"
 msgstr "无法写提交对象"
 
-#: builtin/commit.c:1572
+#: builtin/commit.c:1575
 msgid "cannot lock HEAD ref"
 msgstr "无法锁定 HEAD 引用"
 
-#: builtin/commit.c:1576
+#: builtin/commit.c:1579
 msgid "cannot update HEAD ref"
 msgstr "无法更新 HEAD 引用"
 
-#: builtin/commit.c:1587
+#: builtin/commit.c:1590
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full or quota is\n"
@@ -2664,7 +2928,7 @@ msgstr "没有发现名称,无法描述任何东西。"
 
 #: builtin/describe.c:482
 msgid "--dirty is incompatible with committishes"
-msgstr "--dirty ä¸\8dè\83½ä¸\8eæ\8f\90交å\85±用"
+msgstr "--dirty ä¸\8dè\83½ä¸\8eæ\8f\90交å\90\8cæ\97¶ä½¿用"
 
 #: builtin/diff.c:77
 #, c-format
@@ -2693,7 +2957,7 @@ msgstr "提供了超过 %d 个树对象:'%s'"
 #: builtin/diff.c:356
 #, c-format
 msgid "more than two blobs given: '%s'"
-msgstr "提供了超过两个 blob 对象:'%s'"
+msgstr "提供了超过两个二进制对象(blob):'%s'"
 
 #: builtin/diff.c:364
 #, c-format
@@ -2930,11 +3194,11 @@ msgstr "--open-files-in-pager 仅用于工作区"
 
 #: builtin/grep.c:963
 msgid "--cached or --untracked cannot be used with --no-index."
-msgstr "--cached æ\88\96 --untracked ä¸\8dè\83½ä¸\8e --no-index å\85±用。"
+msgstr "--cached æ\88\96 --untracked ä¸\8dè\83½ä¸\8e --no-index å\90\8cæ\97¶ä½¿用。"
 
 #: builtin/grep.c:968
 msgid "--no-index or --untracked cannot be used with revs."
-msgstr "--no-index æ\88\96 --untracked ä¸\8dè\83½å\92\8cç\89\88æ\9c¬å\85±用。"
+msgstr "--no-index æ\88\96 --untracked ä¸\8dè\83½å\92\8cç\89\88æ\9c¬å\90\8cæ\97¶ä½¿用。"
 
 #: builtin/grep.c:971
 msgid "--[no-]exclude-standard cannot be used for tracked contents."
@@ -2944,30 +3208,30 @@ msgstr "--[no-]exclude-standard 不能用于已跟踪内容。"
 msgid "both --cached and trees are given."
 msgstr "同时给出了 --cached 和树对象。"
 
-#: builtin/help.c:63
+#: builtin/help.c:65
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "未能识别的帮助格式 '%s'"
 
-#: builtin/help.c:91
+#: builtin/help.c:93
 msgid "Failed to start emacsclient."
 msgstr "无法启动 emacsclient。"
 
-#: builtin/help.c:104
+#: builtin/help.c:106
 msgid "Failed to parse emacsclient version."
 msgstr "无法解析 emacsclient 版本。"
 
-#: builtin/help.c:112
+#: builtin/help.c:114
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "emacsclient 版本 '%d' 太老 (< 22)。"
 
-#: builtin/help.c:130 builtin/help.c:158 builtin/help.c:167 builtin/help.c:175
+#: builtin/help.c:132 builtin/help.c:160 builtin/help.c:169 builtin/help.c:177
 #, c-format
 msgid "failed to exec '%s': %s"
 msgstr "无法执行 '%s':%s"
 
-#: builtin/help.c:215
+#: builtin/help.c:217
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -2976,7 +3240,7 @@ msgstr ""
 "'%s':不支持的 man 手册查看器的路径。\n"
 "请使用 'man.<tool>.cmd'。"
 
-#: builtin/help.c:227
+#: builtin/help.c:229
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -2985,34 +3249,29 @@ msgstr ""
 "'%s': 支持的 man 手册查看器命令。\n"
 "请使用 'man.<tool>.path'。"
 
-#: builtin/help.c:291
+#: builtin/help.c:299
 msgid "The most commonly used git commands are:"
 msgstr "最常用的 git 命令有:"
 
-#: builtin/help.c:359
+#: builtin/help.c:367
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "'%s':未知的 man 查看器。"
 
-#: builtin/help.c:376
+#: builtin/help.c:384
 msgid "no man viewer handled the request"
 msgstr "没有 man 查看器处理此请求"
 
-#: builtin/help.c:384
+#: builtin/help.c:392
 msgid "no info viewer handled the request"
 msgstr "没有 info 查看器处理此请求"
 
-#: builtin/help.c:395
-#, c-format
-msgid "'%s': not a documentation directory."
-msgstr "'%s':不是一个文档目录。"
-
-#: builtin/help.c:436 builtin/help.c:443
+#: builtin/help.c:447 builtin/help.c:454
 #, c-format
 msgid "usage: %s%s"
 msgstr "用法:%s%s"
 
-#: builtin/help.c:459
+#: builtin/help.c:470
 #, c-format
 msgid "`git %s' is aliased to `%s'"
 msgstr "`git %s' 是 `%s' 的别名"
@@ -3086,176 +3345,176 @@ msgstr "delta 基准偏移越界"
 msgid "unknown object type %d"
 msgstr "未知对象类型 %d"
 
-#: builtin/index-pack.c:531
+#: builtin/index-pack.c:530
 msgid "cannot pread pack file"
 msgstr "无法读取包文件"
 
-#: builtin/index-pack.c:533
+#: builtin/index-pack.c:532
 #, c-format
 msgid "premature end of pack file, %lu byte missing"
 msgid_plural "premature end of pack file, %lu bytes missing"
 msgstr[0] "包文件过早结束,缺少 %lu 字节"
 msgstr[1] "包文件过早结束,缺少 %lu 字节"
 
-#: builtin/index-pack.c:555
+#: builtin/index-pack.c:558
 msgid "serious inflate inconsistency"
 msgstr "解压缩严重的不一致"
 
-#: builtin/index-pack.c:646 builtin/index-pack.c:652 builtin/index-pack.c:675
-#: builtin/index-pack.c:709 builtin/index-pack.c:718
+#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678
+#: builtin/index-pack.c:712 builtin/index-pack.c:721
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "发现 %s 出现 SHA1 冲突!"
 
-#: builtin/index-pack.c:649 builtin/pack-objects.c:170
+#: builtin/index-pack.c:652 builtin/pack-objects.c:170
 #: builtin/pack-objects.c:262
 #, c-format
 msgid "unable to read %s"
 msgstr "不能读 %s"
 
-#: builtin/index-pack.c:715
+#: builtin/index-pack.c:718
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "不能读取现存对象 %s"
 
-#: builtin/index-pack.c:729
+#: builtin/index-pack.c:732
 #, c-format
 msgid "invalid blob object %s"
-msgstr "无效的 blob 对象 %s"
+msgstr "无效的二进制对象(blob)%s"
 
-#: builtin/index-pack.c:744
+#: builtin/index-pack.c:747
 #, c-format
 msgid "invalid %s"
 msgstr "无效的 %s"
 
-#: builtin/index-pack.c:746
+#: builtin/index-pack.c:749
 msgid "Error in object"
 msgstr "对象中出错"
 
-#: builtin/index-pack.c:748
+#: builtin/index-pack.c:751
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "%s 的所有子对象并非都可达"
 
-#: builtin/index-pack.c:818 builtin/index-pack.c:844
+#: builtin/index-pack.c:821 builtin/index-pack.c:847
 msgid "failed to apply delta"
 msgstr "无法应用 delta"
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Receiving objects"
 msgstr "接收对象中"
 
-#: builtin/index-pack.c:983
+#: builtin/index-pack.c:986
 msgid "Indexing objects"
 msgstr "索引对象中"
 
-#: builtin/index-pack.c:1009
+#: builtin/index-pack.c:1012
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "包冲突(SHA1 不匹配)"
 
-#: builtin/index-pack.c:1014
+#: builtin/index-pack.c:1017
 msgid "cannot fstat packfile"
 msgstr "不能枚举包文件状态"
 
-#: builtin/index-pack.c:1017
+#: builtin/index-pack.c:1020
 msgid "pack has junk at the end"
 msgstr "包的结尾有垃圾数据"
 
-#: builtin/index-pack.c:1028
+#: builtin/index-pack.c:1031
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "parse_pack_objects() 中遇到不可理喻的问题"
 
-#: builtin/index-pack.c:1051
+#: builtin/index-pack.c:1054
 msgid "Resolving deltas"
 msgstr "处理 delta 中"
 
-#: builtin/index-pack.c:1102
+#: builtin/index-pack.c:1105
 msgid "confusion beyond insanity"
 msgstr "不可理喻"
 
-#: builtin/index-pack.c:1121
+#: builtin/index-pack.c:1124
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "包有 %d 个未解决的 delta"
 msgstr[1] "包有 %d 个未解决的 delta"
 
-#: builtin/index-pack.c:1146
+#: builtin/index-pack.c:1149
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "不能缩小附加对象(%d)"
 
-#: builtin/index-pack.c:1225
+#: builtin/index-pack.c:1228
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "本地对象 %s 已损坏"
 
-#: builtin/index-pack.c:1249
+#: builtin/index-pack.c:1252
 msgid "error while closing pack file"
 msgstr "关闭包文件时出错"
 
-#: builtin/index-pack.c:1262
+#: builtin/index-pack.c:1265
 #, c-format
 msgid "cannot write keep file '%s'"
 msgstr "无法写保留文件 '%s'"
 
-#: builtin/index-pack.c:1270
+#: builtin/index-pack.c:1273
 #, c-format
 msgid "cannot close written keep file '%s'"
 msgstr "无法关闭保留文件 '%s'"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1286
 msgid "cannot store pack file"
 msgstr "无法存储包文件"
 
-#: builtin/index-pack.c:1294
+#: builtin/index-pack.c:1297
 msgid "cannot store index file"
 msgstr "无法存储索引文件"
 
-#: builtin/index-pack.c:1395
+#: builtin/index-pack.c:1398
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "无法打开现存包文件 '%s'"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1400
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "无法为 %s 打开包索引文件"
 
-#: builtin/index-pack.c:1444
+#: builtin/index-pack.c:1447
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "非 delta:%d 个对象"
 msgstr[1] "非 delta:%d 个对象"
 
-#: builtin/index-pack.c:1451
+#: builtin/index-pack.c:1454
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "链长 = %d: %lu 对象"
 msgstr[1] "链长 = %d: %lu 对象"
 
-#: builtin/index-pack.c:1478
+#: builtin/index-pack.c:1481
 msgid "Cannot come back to cwd"
 msgstr "无法返回当前工作目录"
 
-#: builtin/index-pack.c:1522 builtin/index-pack.c:1525
-#: builtin/index-pack.c:1537 builtin/index-pack.c:1541
+#: builtin/index-pack.c:1525 builtin/index-pack.c:1528
+#: builtin/index-pack.c:1540 builtin/index-pack.c:1544
 #, c-format
 msgid "bad %s"
 msgstr "错误选项 %s"
 
-#: builtin/index-pack.c:1555
+#: builtin/index-pack.c:1558
 msgid "--fix-thin cannot be used without --stdin"
-msgstr "--fix-thin ä¸\8dè\83½å\92\8c --stdin å\85±用"
+msgstr "--fix-thin ä¸\8dè\83½å\92\8c --stdin å\90\8cæ\97¶ä½¿用"
 
-#: builtin/index-pack.c:1559 builtin/index-pack.c:1569
+#: builtin/index-pack.c:1562 builtin/index-pack.c:1572
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "包名 '%s' 没有以 '.pack' 结尾"
 
-#: builtin/index-pack.c:1578
+#: builtin/index-pack.c:1581
 msgid "--verify with no packfile name given"
 msgstr "--verify 没有提供包名参数"
 
@@ -3329,22 +3588,22 @@ msgstr "没有从 '%2$s' 复制带有错误版本 %1$d 的模版"
 msgid "insane git directory %s"
 msgstr "不正常的 git 目录 %s"
 
-#: builtin/init-db.c:322 builtin/init-db.c:325
+#: builtin/init-db.c:323 builtin/init-db.c:326
 #, c-format
 msgid "%s already exists"
 msgstr "%s 已经存在"
 
-#: builtin/init-db.c:354
+#: builtin/init-db.c:355
 #, c-format
 msgid "unable to handle file type %d"
 msgstr "不能处理 %d 类型的文件"
 
-#: builtin/init-db.c:357
+#: builtin/init-db.c:358
 #, c-format
 msgid "unable to move %s to %s"
 msgstr "不能移动 %s 至 %s"
 
-#: builtin/init-db.c:362
+#: builtin/init-db.c:363
 #, c-format
 msgid "Could not create git link %s"
 msgstr "不能创建 git link %s"
@@ -3354,39 +3613,39 @@ msgstr "不能创建 git link %s"
 #. * existing" or "Initialized empty", the second " shared" or
 #. * "", and the last '%s%s' is the verbatim directory name.
 #.
-#: builtin/init-db.c:419
+#: builtin/init-db.c:420
 #, c-format
 msgid "%s%s Git repository in %s%s\n"
 msgstr "%s%s Git 版本库于 %s%s\n"
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Reinitialized existing"
 msgstr "重新初始化现存的"
 
-#: builtin/init-db.c:420
+#: builtin/init-db.c:421
 msgid "Initialized empty"
 msgstr "初始化空的"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: builtin/init-db.c:421
+#: builtin/init-db.c:422
 msgid " shared"
 msgstr "共享"
 
-#: builtin/init-db.c:440
+#: builtin/init-db.c:441
 msgid "cannot tell cwd"
 msgstr "无法获知当前路径"
 
-#: builtin/init-db.c:521 builtin/init-db.c:528
+#: builtin/init-db.c:522 builtin/init-db.c:529
 #, c-format
 msgid "cannot mkdir %s"
 msgstr "不能创建目录 %s"
 
-#: builtin/init-db.c:532
+#: builtin/init-db.c:533
 #, c-format
 msgid "cannot chdir to %s"
 msgstr "不能切换目录到 %s"
 
-#: builtin/init-db.c:554
+#: builtin/init-db.c:555
 #, c-format
 msgid ""
 "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-"
@@ -3395,11 +3654,11 @@ msgstr ""
 "不允许 %s(或 --work-tree=<directory>)而没有指定 %s(或 --git-"
 "dir=<directory>)"
 
-#: builtin/init-db.c:578
+#: builtin/init-db.c:579
 msgid "Cannot access current working directory"
 msgstr "不能访问当前工作目录"
 
-#: builtin/init-db.c:585
+#: builtin/init-db.c:586
 #, c-format
 msgid "Cannot access work tree '%s'"
 msgstr "不能访问工作区 '%s'"
@@ -3409,95 +3668,95 @@ msgstr "不能访问工作区 '%s'"
 msgid "Final output: %d %s\n"
 msgstr "最终输出:%d %s\n"
 
-#: builtin/log.c:402 builtin/log.c:490
+#: builtin/log.c:403 builtin/log.c:494
 #, c-format
 msgid "Could not read object %s"
 msgstr "不能读取对象 %s"
 
-#: builtin/log.c:514
+#: builtin/log.c:518
 #, c-format
 msgid "Unknown type: %d"
 msgstr "未知类型:%d"
 
-#: builtin/log.c:603
+#: builtin/log.c:608
 msgid "format.headers without value"
 msgstr "format.headers 没有值"
 
-#: builtin/log.c:677
+#: builtin/log.c:682
 msgid "name of output directory is too long"
 msgstr "输出目录名太长"
 
-#: builtin/log.c:688
+#: builtin/log.c:693
 #, c-format
 msgid "Cannot open patch file %s"
 msgstr "无法打开补丁文件 %s"
 
-#: builtin/log.c:702
+#: builtin/log.c:707
 msgid "Need exactly one range."
 msgstr "只需要一个范围。"
 
-#: builtin/log.c:710
+#: builtin/log.c:715
 msgid "Not a range."
 msgstr "不是一个范围。"
 
-#: builtin/log.c:787
+#: builtin/log.c:792
 msgid "Cover letter needs email format"
 msgstr "信封需要邮件地址格式"
 
-#: builtin/log.c:860
+#: builtin/log.c:865
 #, c-format
 msgid "insane in-reply-to: %s"
 msgstr "不正常的 in-reply-to:%s"
 
-#: builtin/log.c:933
+#: builtin/log.c:938
 msgid "Two output directories?"
 msgstr "两个输出目录?"
 
-#: builtin/log.c:1154
+#: builtin/log.c:1160
 #, c-format
 msgid "bogus committer info %s"
 msgstr "虚假的提交者信息 %s"
 
-#: builtin/log.c:1199
+#: builtin/log.c:1205
 msgid "-n and -k are mutually exclusive."
 msgstr "-n 和 -k 互斥。"
 
-#: builtin/log.c:1201
+#: builtin/log.c:1207
 msgid "--subject-prefix and -k are mutually exclusive."
 msgstr "--subject-prefix 和 -k 互斥。"
 
-#: builtin/log.c:1209
+#: builtin/log.c:1215
 msgid "--name-only does not make sense"
 msgstr "--name-only 无意义"
 
-#: builtin/log.c:1211
+#: builtin/log.c:1217
 msgid "--name-status does not make sense"
 msgstr "--name-status 无意义"
 
-#: builtin/log.c:1213
+#: builtin/log.c:1219
 msgid "--check does not make sense"
 msgstr "--check 无意义"
 
-#: builtin/log.c:1236
+#: builtin/log.c:1242
 msgid "standard output, or directory, which one?"
 msgstr "标准输出或目录,哪一个?"
 
-#: builtin/log.c:1238
+#: builtin/log.c:1244
 #, c-format
 msgid "Could not create directory '%s'"
 msgstr "不能创建目录 '%s'"
 
-#: builtin/log.c:1391
+#: builtin/log.c:1397
 msgid "Failed to create output files"
 msgstr "无法创建输出文件"
 
-#: builtin/log.c:1495
+#: builtin/log.c:1501
 #, c-format
 msgid ""
 "Could not find a tracked remote branch, please specify <upstream> manually.\n"
 msgstr "不能找到跟踪的远程分支,请手工指定 <upstream>。\n"
 
-#: builtin/log.c:1511 builtin/log.c:1513 builtin/log.c:1525
+#: builtin/log.c:1517 builtin/log.c:1519 builtin/log.c:1531
 #, c-format
 msgid "Unknown commit %s"
 msgstr "未知提交 %s"
@@ -3579,10 +3838,6 @@ msgstr "git write-tree 无法写入一树对象"
 msgid "failed to read the cache"
 msgstr "无法读取缓存"
 
-#: builtin/merge.c:697
-msgid "Unable to write index."
-msgstr "不能写索引。"
-
 #: builtin/merge.c:710
 msgid "Not handling anything other than two heads merge."
 msgstr "不能处理两个头合并之外的任何操作。"
@@ -3691,11 +3946,11 @@ msgstr "您尚未结束您的拣选(存在 CHERRY_PICK_HEAD)。"
 
 #: builtin/merge.c:1249
 msgid "You cannot combine --squash with --no-ff."
-msgstr "æ\82¨ä¸\8dè\83½å°\86 --squash ä¸\8e --no-ff å\85±用。"
+msgstr "æ\82¨ä¸\8dè\83½å°\86 --squash ä¸\8e --no-ff å\90\8cæ\97¶ä½¿用。"
 
 #: builtin/merge.c:1254
 msgid "You cannot combine --no-ff with --ff-only."
-msgstr "æ\82¨ä¸\8dè\83½å°\86 --no-ff ä¸\8e --ff-only å\85±用。"
+msgstr "æ\82¨ä¸\8dè\83½å°\86 --no-ff ä¸\8e --ff-only å\90\8cæ\97¶ä½¿用。"
 
 #: builtin/merge.c:1261
 msgid "No commit specified and merge.defaultToUpstream not set."
@@ -4165,7 +4420,7 @@ msgstr "--all 和 --tags 不兼容"
 
 #: builtin/push.c:286
 msgid "--all can't be combined with refspecs"
-msgstr "--all ä¸\8dè\83½å\92\8cå¼\95ç\94¨è¡¨è¾¾å¼\8få\85±用"
+msgstr "--all ä¸\8dè\83½å\92\8cå¼\95ç\94¨è¡¨è¾¾å¼\8få\90\8cæ\97¶ä½¿用"
 
 #: builtin/push.c:291
 msgid "--mirror and --tags are incompatible"
@@ -4173,7 +4428,7 @@ msgstr "--mirror 和 --tags 不兼容"
 
 #: builtin/push.c:292
 msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror ä¸\8dè\83½å\92\8cå¼\95ç\94¨è¡¨è¾¾å¼\8få\85±用"
+msgstr "--mirror ä¸\8dè\83½å\92\8cå¼\95ç\94¨è¡¨è¾¾å¼\8få\90\8cæ\97¶ä½¿用"
 
 #: builtin/push.c:297
 msgid "--all and --mirror are incompatible"
@@ -4211,7 +4466,7 @@ msgstr "指定一个 master 分支并使用 --mirror 选项没有意义"
 
 #: builtin/remote.c:187
 msgid "specifying branches to track makes sense only with fetch mirrors"
-msgstr "æ\8c\87å®\9aè¦\81è·\9f踪ç\9a\84å\88\86æ\94¯å\8fªå\9c¨ä¸\8eè\8e·å\8f\96é\95\9cå\83\8få\85±用才有意义"
+msgstr "æ\8c\87å®\9aè¦\81è·\9f踪ç\9a\84å\88\86æ\94¯å\8fªå\9c¨ä¸\8eè\8e·å\8f\96é\95\9cå\83\8få\90\8cæ\97¶ä½¿用才有意义"
 
 #: builtin/remote.c:195 builtin/remote.c:646
 #, c-format
@@ -4594,32 +4849,32 @@ msgstr "重置后撤出暂存区的变更:"
 msgid "Cannot do a %s reset in the middle of a merge."
 msgstr "在合并过程中不能做%s重置操作。"
 
-#: builtin/reset.c:297
+#: builtin/reset.c:303
 #, c-format
 msgid "Could not parse object '%s'."
 msgstr "不能解析对象 '%s'。"
 
-#: builtin/reset.c:302
+#: builtin/reset.c:308
 msgid "--patch is incompatible with --{hard,mixed,soft}"
 msgstr "--patch 与 --{hard,mixed,soft} 不兼容"
 
-#: builtin/reset.c:311
+#: builtin/reset.c:317
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
-msgstr "--mixed 带路径已弃用,代之以 'git reset -- <paths>'。"
+msgstr "--mixed 带路径已弃用,而是用 'git reset -- <paths>'。"
 
 #  译者:汉字之间无空格,故删除%s前后空格
-#: builtin/reset.c:313
+#: builtin/reset.c:319
 #, c-format
 msgid "Cannot do %s reset with paths."
 msgstr "不能带路径进行%s重置。"
 
 #  译者:汉字之间无空格,故删除%s前后空格
-#: builtin/reset.c:325
+#: builtin/reset.c:331
 #, c-format
 msgid "%s reset is not allowed in a bare repository"
 msgstr "不能对裸版本库进行%s重置"
 
-#: builtin/reset.c:341
+#: builtin/reset.c:347
 #, c-format
 msgid "Could not reset index file to revision '%s'."
 msgstr "不能重置索引文件至版本 '%s'。"
@@ -4627,7 +4882,7 @@ msgstr "不能重置索引文件至版本 '%s'。"
 #: builtin/revert.c:70 builtin/revert.c:92
 #, c-format
 msgid "%s: %s cannot be used with %s"
-msgstr "%sï¼\9a%s ä¸\8dè\83½å\92\8c %s å\85±用"
+msgstr "%sï¼\9a%s ä¸\8dè\83½å\92\8c %s å\90\8cæ\97¶ä½¿用"
 
 #: builtin/revert.c:131
 msgid "program error"
@@ -4777,15 +5032,15 @@ msgstr "--column 和 -n 不兼容"
 
 #: builtin/tag.c:523
 msgid "-n option is only allowed with -l."
-msgstr "-n é\80\89项å\8fªå\85\81许å\92\8c -l å\85±用。"
+msgstr "-n é\80\89项å\8fªå\85\81许å\92\8c -l å\90\8cæ\97¶ä½¿用。"
 
 #: builtin/tag.c:525
 msgid "--contains option is only allowed with -l."
-msgstr "--contains é\80\89项å\8fªå\85\81许å\92\8c -l å\85±用。"
+msgstr "--contains é\80\89项å\8fªå\85\81许å\92\8c -l å\90\8cæ\97¶ä½¿用。"
 
 #: builtin/tag.c:527
 msgid "--points-at option is only allowed with -l."
-msgstr "--points-at é\80\89项å\8fªå\85\81许å\92\8c -l å\85±用。"
+msgstr "--points-at é\80\89项å\8fªå\85\81许å\92\8c -l å\90\8cæ\97¶ä½¿用。"
 
 #: builtin/tag.c:535
 msgid "only one -F or -m option is allowed."
@@ -4953,9 +5208,9 @@ msgstr "您好像在上一次 'am' 失败后移动了 HEAD。未回退至 ORIG_H
 #: git-am.sh:105
 #, sh-format
 msgid ""
-"When you have resolved this problem run \"$cmdline --resolved\".\n"
-"If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n"
-"To restore the original branch and stop patching run \"$cmdline --abort\"."
+"When you have resolved this problem, run \"$cmdline --resolved\".\n"
+"If you prefer to skip this patch, run \"$cmdline --skip\" instead.\n"
+"To restore the original branch and stop patching, run \"$cmdline --abort\"."
 msgstr ""
 "当您解决了此问题后,执行 \"$cmdline --resolved\"。\n"
 "如果您想跳过此补丁,则执行 \"$cmdline --skip\"。\n"
@@ -4967,7 +5222,11 @@ msgstr "无法求助于三路合并。"
 
 #: git-am.sh:137
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
-msgstr "版本库缺乏必要的 blob 数据以进行三路合并。"
+msgstr "版本库缺乏必要的二进制对象(blob)以进行三路合并。"
+
+#: git-am.sh:139
+msgid "Using index info to reconstruct a base tree..."
+msgstr "更新索引信息以重建基树..."
 
 #: git-am.sh:154
 msgid ""
@@ -4975,48 +5234,56 @@ msgid ""
 "It does not apply to blobs recorded in its index."
 msgstr ""
 "您是否曾手动编辑过您的补丁?\n"
-"无法应用补丁到索引中的数据上。"
+"无法应用补丁到索引中的二进制对象(blob)上。"
 
 #: git-am.sh:163
 msgid "Falling back to patching base and 3-way merge..."
 msgstr "转而在基础版本上打补丁及进行三路合并..."
 
-#: git-am.sh:275
+#: git-am.sh:179
+msgid "Failed to merge in the changes."
+msgstr "无法合并变更。"
+
+#: git-am.sh:274
 msgid "Only one StGIT patch series can be applied at once"
 msgstr "一次只能有一个 StGIT 补丁队列被应用"
 
-#: git-am.sh:362
+#: git-am.sh:361
 #, sh-format
 msgid "Patch format $patch_format is not supported."
 msgstr "不支持 $patch_format 补丁格式。"
 
-#: git-am.sh:364
+#: git-am.sh:363
 msgid "Patch format detection failed."
 msgstr "补丁格式检测失败。"
 
-#: git-am.sh:418
-msgid "-d option is no longer supported.  Do not use."
-msgstr "不再支持 -d 选项。不要使用。"
+#: git-am.sh:389
+msgid ""
+"The -b/--binary option has been a no-op for long time, and\n"
+"it will be removed. Please do not use it anymore."
+msgstr ""
+"参数 -b/--binary 已经很长时间不做任何实质操作了,并且将被删除。\n"
+"请不要再使用它了。"
 
-#: git-am.sh:481
+#: git-am.sh:477
 #, sh-format
 msgid "previous rebase directory $dotest still exists but mbox given."
 msgstr "之前的变基目录 $dotest 仍然存在但给出了mbox。"
 
-#: git-am.sh:486
+#: git-am.sh:482
 msgid "Please make up your mind. --skip or --abort?"
 msgstr "请下决心。--skip 或是 --abort ?"
 
-#: git-am.sh:513
+#: git-am.sh:509
 msgid "Resolve operation not in progress, we are not resuming."
 msgstr "解决操作未进行,我们不会继续。"
 
-#: git-am.sh:579
+#: git-am.sh:575
 #, sh-format
 msgid "Dirty index: cannot apply patches (dirty: $files)"
 msgstr "脏的索引:不能应用补丁(脏文件:$files)"
 
-#: git-am.sh:671
+#: git-am.sh:679
 #, sh-format
 msgid ""
 "Patch is empty.  Was it split wrong?\n"
@@ -5027,15 +5294,15 @@ msgstr ""
 "如果您想要跳过这个补丁,执行 \"$cmdline --skip\"。\n"
 "要恢复原分支并停止打补丁,执行 \"$cmdline --abort\"。"
 
-#: git-am.sh:708
+#: git-am.sh:706
 msgid "Patch does not have a valid e-mail address."
 msgstr "补丁中没有一个有效的邮件地址。"
 
-#: git-am.sh:755
+#: git-am.sh:753
 msgid "cannot be interactive without stdin connected to a terminal."
 msgstr "标准输入没有和终端关联,不能进行交互式操作。"
 
-#: git-am.sh:759
+#: git-am.sh:757
 msgid "Commit Body is:"
 msgstr "提交内容为:"
 
@@ -5043,16 +5310,16 @@ 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:766
+#: git-am.sh:764
 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:802
+#: git-am.sh:800
 #, sh-format
 msgid "Applying: $FIRSTLINE"
 msgstr "正应用:$FIRSTLINE"
 
-#: git-am.sh:823
+#: git-am.sh:821
 msgid ""
 "No changes - did you forget to use 'git add'?\n"
 "If there is nothing left to stage, chances are that something else\n"
@@ -5062,22 +5329,22 @@ msgstr ""
 "如果没有什么要添加到暂存区的,则很可能是其它提交已经引入了相同的变更。\n"
 "您也许想要跳过这个补丁。"
 
-#: git-am.sh:831
+#: git-am.sh:829
 msgid ""
 "You still have unmerged paths in your index\n"
 "did you forget to use 'git add'?"
 msgstr "您的索引中仍有未合并的路径。您是否忘了执行 'git add'?"
 
-#: git-am.sh:847
+#: git-am.sh:845
 msgid "No changes -- Patch already applied."
 msgstr "没有变更 -- 补丁已经应用过。"
 
-#: git-am.sh:857
+#: git-am.sh:855
 #, sh-format
 msgid "Patch failed at $msgnum $FIRSTLINE"
 msgstr "补丁失败于 $msgnum $FIRSTLINE"
 
-#: git-am.sh:873
+#: git-am.sh:876
 msgid "applying to an empty history"
 msgstr "正应用到一个空历史上"
 
@@ -5278,6 +5545,123 @@ msgstr "无法将多个分支合并到空分支"
 msgid "Cannot rebase onto multiple branches"
 msgstr "无法变基到多个分支"
 
+#: git-rebase.sh:52
+msgid ""
+"When you have resolved this problem, run \"git rebase --continue\".\n"
+"If you prefer to skip this patch, run \"git rebase --skip\" instead.\n"
+"To check out the original branch and stop rebasing, run \"git rebase --abort"
+"\"."
+msgstr ""
+"当您解决了此问题后,执行 \"git rebase --continue\"。\n"
+"如果您想跳过此补丁,则执行 \"git rebase --skip\"。\n"
+"要恢复原分支并停止变基,执行 \"git rebase --abort\"。"
+
+#: git-rebase.sh:159
+msgid "The pre-rebase hook refused to rebase."
+msgstr "钩子 pre-rebase 拒绝变基。"
+
+#: git-rebase.sh:164
+msgid "It looks like git-am is in progress. Cannot rebase."
+msgstr "似乎正处于在 git-am 的执行过程中。无法变基。"
+
+#: git-rebase.sh:295
+msgid "The --exec option must be used with the --interactive option"
+msgstr "选项 --exec 必须和选项 --interactive 同时使用"
+
+#: git-rebase.sh:300
+msgid "No rebase in progress?"
+msgstr "没有正在进行的变基?"
+
+#: git-rebase.sh:313
+msgid "Cannot read HEAD"
+msgstr "不能读取 HEAD"
+
+#: git-rebase.sh:316
+msgid ""
+"You must edit all merge conflicts and then\n"
+"mark them as resolved using git add"
+msgstr ""
+"您必须编辑所有的合并冲突,然后通过 git add\n"
+"命令将它们标记为已解决"
+
+#: git-rebase.sh:334
+#, sh-format
+msgid "Could not move back to $head_name"
+msgstr "无法移回 $head_name"
+
+#: git-rebase.sh:350
+#, sh-format
+msgid ""
+"It seems that there is already a $state_dir_base directory, and\n"
+"I wonder if you are in the middle of another rebase.  If that is the\n"
+"case, please try\n"
+"\t$cmd_live_rebase\n"
+"If that is not the case, please\n"
+"\t$cmd_clear_stale_rebase\n"
+"and run me again.  I am stopping in case you still have something\n"
+"valuable there."
+msgstr ""
+"好像已有一个 $state_dir_base 目录,我怀疑您正处于另外一个变基过程中。\n"
+"如果是这样,请尝试执行\n"
+"\t$cmd_live_rebase\n"
+"如果不是这样,请执行\n"
+"\t$cmd_clear_stale_rebase\n"
+"然后再重新执行变基。为避免您丢失重要数据,我已经停止当前操作。"
+
+#: git-rebase.sh:395
+#, sh-format
+msgid "invalid upstream $upstream_name"
+msgstr "无效的上游 $upstream_name"
+
+#: git-rebase.sh:419
+#, sh-format
+msgid "$onto_name: there are more than one merge bases"
+msgstr "$onto_name: 有一个以上的合并基准"
+
+#: git-rebase.sh:422 git-rebase.sh:426
+#, sh-format
+msgid "$onto_name: there is no merge base"
+msgstr "$onto_name: 没有合并基准"
+
+#: git-rebase.sh:431
+#, sh-format
+msgid "Does not point to a valid commit: $onto_name"
+msgstr "没有指向一个有效的提交:$onto_name"
+
+#: git-rebase.sh:454
+#, sh-format
+msgid "fatal: no such branch: $branch_name"
+msgstr "严重错误:无此分支:$branch_name"
+
+#: git-rebase.sh:474
+msgid "Please commit or stash them."
+msgstr "请提交或为它们保存进度。"
+
+#: git-rebase.sh:492
+#, sh-format
+msgid "Current branch $branch_name is up to date."
+msgstr "当前分支 $branch_name 是最新的。"
+
+#: git-rebase.sh:495
+#, sh-format
+msgid "Current branch $branch_name is up to date, rebase forced."
+msgstr "当前分支 $branch_name 是最新的,强制变基。"
+
+#: git-rebase.sh:506
+#, sh-format
+msgid "Changes from $mb to $onto:"
+msgstr "变更从 $mb 到 $onto:"
+
+#. Detach HEAD and reset the tree
+#: git-rebase.sh:515
+msgid "First, rewinding head to replay your work on top of it..."
+msgstr "首先,重置头指针以便在上面重放您的工作..."
+
+#: git-rebase.sh:523
+#, sh-format
+msgid "Fast-forwarded $branch_name to $onto_name."
+msgstr "快进 $branch_name 至 $onto_name。"
+
 #: git-stash.sh:51
 msgid "git stash clear with parameters is unimplemented"
 msgstr "git stash clear 不支持参数"
@@ -5417,27 +5801,27 @@ msgstr "无法从 url '$remoteurl' 剥离一个组件"
 msgid "No submodule mapping found in .gitmodules for path '$sm_path'"
 msgstr "未在 .gitmodules 中发现路径 '$sm_path' 的子模组映射"
 
-#: git-submodule.sh:186
+#: git-submodule.sh:189
 #, sh-format
 msgid "Clone of '$url' into submodule path '$sm_path' failed"
 msgstr "无法克隆 '$url' 到子模组路径 '$sm_path'"
 
-#: git-submodule.sh:196
+#: git-submodule.sh:201
 #, sh-format
 msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa"
 msgstr "Gitdir '$a' 在子模组路径 '$b' 之下或者相反"
 
-#: git-submodule.sh:285
+#: git-submodule.sh:290
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "版本库URL:'$repo' 必须是绝对路径或以 ./|../ 起始"
 
-#: git-submodule.sh:302
+#: git-submodule.sh:307
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "'$sm_path' 已经存在于索引中"
 
-#: git-submodule.sh:306
+#: git-submodule.sh:311
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -5448,62 +5832,62 @@ msgstr ""
 "$sm_path\n"
 "如果您确实想添加它,使用 -f 参数。"
 
-#: git-submodule.sh:317
+#: git-submodule.sh:322
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "添加位于 '$sm_path' 的现存版本库到索引"
 
-#: git-submodule.sh:319
+#: git-submodule.sh:324
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "'$sm_path' 已存在且不是一个有效的 git 版本库"
 
-#: git-submodule.sh:333
+#: git-submodule.sh:338
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "不能检出子模组 '$sm_path'"
 
-#: git-submodule.sh:338
+#: git-submodule.sh:343
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "无法添加子模组 '$sm_path'"
 
-#: git-submodule.sh:343
+#: git-submodule.sh:348
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "无法注册子模组 '$sm_path'"
 
-#: git-submodule.sh:385
+#: git-submodule.sh:390
 #, sh-format
 msgid "Entering '$prefix$sm_path'"
 msgstr "正在进入 '$prefix$sm_path'"
 
-#: git-submodule.sh:399
+#: git-submodule.sh:404
 #, sh-format
 msgid "Stopping at '$sm_path'; script returned non-zero status."
 msgstr "停止于 '$sm_path',脚本返回非零值。"
 
-#: git-submodule.sh:442
+#: git-submodule.sh:447
 #, sh-format
 msgid "No url found for submodule path '$sm_path' in .gitmodules"
 msgstr "在 .gitmodules 中未找到子模组路径 '$sm_path' 的 url"
 
-#: git-submodule.sh:451
+#: git-submodule.sh:456
 #, sh-format
 msgid "Failed to register url for submodule path '$sm_path'"
 msgstr "无法为子模组路径 '$sm_path' 注册 url"
 
-#: git-submodule.sh:453
+#: git-submodule.sh:458
 #, sh-format
 msgid "Submodule '$name' ($url) registered for path '$sm_path'"
 msgstr "子模组 '$name' ($url) 已为路径 '$sm_path' 注册"
 
-#: git-submodule.sh:461
+#: git-submodule.sh:466
 #, sh-format
 msgid "Failed to register update mode for submodule path '$sm_path'"
 msgstr "无法为子模组路径 '$sm_path' 注册更新模式"
 
-#: git-submodule.sh:560
+#: git-submodule.sh:565
 #, sh-format
 msgid ""
 "Submodule path '$sm_path' not initialized\n"
@@ -5512,96 +5896,92 @@ msgstr ""
 "子模组路径 '$sm_path' 没有初始化\n"
 "也许您想用 'update --init'?"
 
-#: git-submodule.sh:573
+#: git-submodule.sh:578
 #, sh-format
 msgid "Unable to find current revision in submodule path '$sm_path'"
 msgstr "无法在子模组路径 '$sm_path' 中找到当前版本"
 
-#: git-submodule.sh:592
+#: git-submodule.sh:597
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "无法在子模组路径 '$sm_path' 中获取"
 
-#: git-submodule.sh:606
+#: git-submodule.sh:611
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$sm_path'"
 msgstr "无法在子模组路径 '$sm_path' 中变基 '$sha1'"
 
-#: git-submodule.sh:607
+#: git-submodule.sh:612
 #, sh-format
 msgid "Submodule path '$sm_path': rebased into '$sha1'"
 msgstr "子模组路径 '$sm_path':变基至 '$sha1'"
 
-#: git-submodule.sh:612
+#: git-submodule.sh:617
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$sm_path'"
 msgstr "无法合并 '$sha1' 到子模组路径 '$sm_path' 中"
 
-#: git-submodule.sh:613
+#: git-submodule.sh:618
 #, sh-format
 msgid "Submodule path '$sm_path': merged in '$sha1'"
 msgstr "子模组路径 '$sm_path':已合并入 '$sha1'"
 
-#: git-submodule.sh:618
+#: git-submodule.sh:623
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$sm_path'"
 msgstr "无法在子模组路径 '$sm_path' 中检出 '$sha1'"
 
-#: git-submodule.sh:619
+#: git-submodule.sh:624
 #, sh-format
 msgid "Submodule path '$sm_path': checked out '$sha1'"
 msgstr "子模组路径 '$sm_path':检出 '$sha1'"
 
-#: git-submodule.sh:641 git-submodule.sh:964
+#: git-submodule.sh:646 git-submodule.sh:969
 #, sh-format
 msgid "Failed to recurse into submodule path '$sm_path'"
 msgstr "无法递归进子模组路径 '$sm_path'"
 
-#: git-submodule.sh:749
-msgid "--cached cannot be used with --files"
-msgstr "--cached 不能和 --files 共用"
+#: git-submodule.sh:754
+msgid "The --cached option cannot be used with the --files option"
+msgstr "选项 --cached 不能和选项 --files 同时使用"
 
 #. unexpected type
-#: git-submodule.sh:789
+#: git-submodule.sh:794
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "意外的模式 $mod_dst"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:807
+#: git-submodule.sh:812
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_src"
 msgstr "  警告:$name 未包含提交 $sha1_src"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:810
+#: git-submodule.sh:815
 #, sh-format
 msgid "  Warn: $name doesn't contain commit $sha1_dst"
 msgstr "  警告:$name 未包含提交 $sha1_dst"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:813
+#: git-submodule.sh:818
 #, sh-format
 msgid "  Warn: $name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr "  警告:$name 未包含提交 $sha1_src 和 $sha1_dst"
 
-#: git-submodule.sh:838
+#: git-submodule.sh:843
 msgid "blob"
-msgstr "blob"
-
-#: git-submodule.sh:839
-msgid "submodule"
-msgstr "子模组"
+msgstr "二进制对象"
 
-#: git-submodule.sh:876
+#: git-submodule.sh:881
 msgid "# Submodules changed but not updated:"
 msgstr "# 子模组已修改但尚未更新:"
 
-#: git-submodule.sh:878
+#: git-submodule.sh:883
 msgid "# Submodule changes to be committed:"
 msgstr "要提交的子模组变更:"
 
-#: git-submodule.sh:1022
+#: git-submodule.sh:1027
 #, sh-format
 msgid "Synchronizing submodule url for '$name'"
 msgstr "为 '$name' 同步子模组 url"
index 4ccaf7ac197c28400eddd496abcfc725528ca32b..af5cfbde63aed41d95ac7318d064d3012832d2c5 100644 (file)
@@ -298,7 +298,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
                        return -1;
                }
        }
-       if (!memcmp(ent->base, objdir, pfxlen)) {
+       if (!strcmp(ent->base, objdir)) {
                free(ent);
                return -1;
        }
diff --git a/t/Git-SVN/00compile.t b/t/Git-SVN/00compile.t
new file mode 100644 (file)
index 0000000..c92fee4
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 7;
+
+require_ok 'Git::SVN';
+require_ok 'Git::SVN::Utils';
+require_ok 'Git::SVN::Ra';
+require_ok 'Git::SVN::Log';
+require_ok 'Git::SVN::Migration';
+require_ok 'Git::IndexInfo';
+require_ok 'Git::SVN::GlobSpec';
diff --git a/t/Git-SVN/Utils/add_path_to_url.t b/t/Git-SVN/Utils/add_path_to_url.t
new file mode 100644 (file)
index 0000000..bfbd878
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils qw(
+       add_path_to_url
+);
+
+# A reference cannot be a hash key, so we use an array.
+my @tests = (
+       ["http://x.com", "bar"]                 => 'http://x.com/bar',
+       ["http://x.com", ""]                    => 'http://x.com',
+       ["http://x.com/foo/", undef]            => 'http://x.com/foo/',
+       ["http://x.com/foo/", "/bar/baz/"]      => 'http://x.com/foo/bar/baz/',
+       ["http://x.com", 'per%cent']            => 'http://x.com/per%25cent',
+);
+
+while(@tests) {
+       my($have, $want) = splice @tests, 0, 2;
+
+       my $args = join ", ", map { qq['$_'] } map { defined($_) ? $_ : 'undef' } @$have;
+       my $name = "add_path_to_url($args) eq $want";
+       is add_path_to_url(@$have), $want, $name;
+}
diff --git a/t/Git-SVN/Utils/can_compress.t b/t/Git-SVN/Utils/can_compress.t
new file mode 100644 (file)
index 0000000..d7b49b8
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils qw(can_compress);
+
+# !! is the "convert this to boolean" operator.
+is !!can_compress(), !!eval { require Compress::Zlib };
diff --git a/t/Git-SVN/Utils/canonicalize_url.t b/t/Git-SVN/Utils/canonicalize_url.t
new file mode 100644 (file)
index 0000000..05795ab
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/env perl
+
+# Test our own home rolled URL canonicalizer.  Test the private one
+# directly because we can't predict what the SVN API is doing to do.
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils;
+my $canonicalize_url = \&Git::SVN::Utils::_canonicalize_url_ourselves;
+
+my %tests = (
+       "http://x.com"                  => "http://x.com",
+       "http://x.com/"                 => "http://x.com",
+       "http://x.com/foo/bar"          => "http://x.com/foo/bar",
+       "http://x.com//foo//bar//"      => "http://x.com/foo/bar",
+       "http://x.com/  /%/"            => "http://x.com/%20%20/%25",
+);
+
+for my $arg (keys %tests) {
+       my $want = $tests{$arg};
+
+       is $canonicalize_url->($arg), $want, "canonicalize_url('$arg') => $want";
+}
diff --git a/t/Git-SVN/Utils/collapse_dotdot.t b/t/Git-SVN/Utils/collapse_dotdot.t
new file mode 100644 (file)
index 0000000..1da1cce
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils;
+my $collapse_dotdot = \&Git::SVN::Utils::_collapse_dotdot;
+
+my %tests = (
+       "foo/bar/baz"                   => "foo/bar/baz",
+       ".."                            => "..",
+       "foo/.."                        => "",
+       "/foo/bar/../../baz"            => "/baz",
+       "deeply/.././deeply/nested"     => "./deeply/nested",
+);
+
+for my $arg (keys %tests) {
+       my $want = $tests{$arg};
+
+       is $collapse_dotdot->($arg), $want, "_collapse_dotdot('$arg') => $want";
+}
diff --git a/t/Git-SVN/Utils/fatal.t b/t/Git-SVN/Utils/fatal.t
new file mode 100644 (file)
index 0000000..49e1438
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+BEGIN {
+       # Override exit at BEGIN time before Git::SVN::Utils is loaded
+       # so it will see our local exit later.
+       *CORE::GLOBAL::exit = sub(;$) {
+       return @_ ? CORE::exit($_[0]) : CORE::exit();
+       };
+}
+
+use Git::SVN::Utils qw(fatal);
+
+# fatal()
+{
+       # Capture the exit code and prevent exit.
+       my $exit_status;
+       no warnings 'redefine';
+       local *CORE::GLOBAL::exit = sub { $exit_status = $_[0] || 0 };
+
+       # Trap fatal's message to STDERR
+       my $stderr;
+       close STDERR;
+       ok open STDERR, ">", \$stderr;
+
+       fatal "Some", "Stuff", "Happened";
+
+       is $stderr, "Some Stuff Happened\n";
+       is $exit_status, 1;
+}
diff --git a/t/Git-SVN/Utils/join_paths.t b/t/Git-SVN/Utils/join_paths.t
new file mode 100644 (file)
index 0000000..d4488e7
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Test::More 'no_plan';
+
+use Git::SVN::Utils qw(
+       join_paths
+);
+
+# A reference cannot be a hash key, so we use an array.
+my @tests = (
+       []                                      => '',
+       ["/x.com", "bar"]                       => '/x.com/bar',
+       ["x.com", ""]                           => 'x.com',
+       ["/x.com/foo/", undef, "bar"]           => '/x.com/foo/bar',
+       ["x.com/foo/", "/bar/baz/"]             => 'x.com/foo/bar/baz/',
+       ["foo", "bar"]                          => 'foo/bar',
+       ["/foo/bar", "baz", "/biff"]            => '/foo/bar/baz/biff',
+       ["", undef, "."]                        => '.',
+       []                                      => '',
+
+);
+
+while(@tests) {
+       my($have, $want) = splice @tests, 0, 2;
+
+       my $args = join ", ", map { qq['$_'] } map { defined($_) ? $_ : 'undef' } @$have;
+       my $name = "join_paths($args) eq '$want'";
+       is join_paths(@$have), $want, $name;
+}
index 52b1c27c2c9d3c6111447df4fa241b724f0e6ee1..5d80a985fb709b2cd278f45555fcdeccf45ebb10 100755 (executable)
@@ -51,16 +51,16 @@ test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate v
 test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables with spaces' '
     cmdline="git am" &&
     export cmdline;
-    printf "When you have resolved this problem run git am --resolved." >expect &&
-    eval_gettext "When you have resolved this problem run \$cmdline --resolved." >actual
+    printf "When you have resolved this problem, run git am --resolved." >expect &&
+    eval_gettext "When you have resolved this problem, run \$cmdline --resolved." >actual
     test_i18ncmp expect actual
 '
 
 test_expect_success 'eval_gettext: our eval_gettext() fallback can interpolate variables with spaces and quotes' '
     cmdline="git am" &&
     export cmdline;
-    printf "When you have resolved this problem run \"git am --resolved\"." >expect &&
-    eval_gettext "When you have resolved this problem run \"\$cmdline --resolved\"." >actual
+    printf "When you have resolved this problem, run \"git am --resolved\"." >expect &&
+    eval_gettext "When you have resolved this problem, run \"\$cmdline --resolved\"." >actual
     test_i18ncmp expect actual
 '
 
index a3b77239f48ade053c3514c9ba65cd72286d0783..f8457f9d14c90349b0d3b09a3f695cbfafc3cbbf 100755 (executable)
@@ -47,6 +47,7 @@ test_expect_success \
 
 
 test_expect_success 'flags and then non flags' '
+       test_tick &&
        echo comment text |
        git commit-tree $(cat treeid) >commitid &&
        echo comment text |
index 7788ae02adca18ab1d1f8cf7b76243fbf56377ae..1de0ebda25c1034fc1b343a8f0e3da9c2c7f8c6e 100755 (executable)
@@ -68,24 +68,24 @@ test_expect_success 'rebase against master' '
 
 test_expect_success 'rebase against master twice' '
        git rebase master >out &&
-       grep "Current branch my-topic-branch is up to date" out
+       test_i18ngrep "Current branch my-topic-branch is up to date" out
 '
 
 test_expect_success 'rebase against master twice with --force' '
        git rebase --force-rebase master >out &&
-       grep "Current branch my-topic-branch is up to date, rebase forced" out
+       test_i18ngrep "Current branch my-topic-branch is up to date, rebase forced" out
 '
 
 test_expect_success 'rebase against master twice from another branch' '
        git checkout my-topic-branch^ &&
        git rebase master my-topic-branch >out &&
-       grep "Current branch my-topic-branch is up to date" out
+       test_i18ngrep "Current branch my-topic-branch is up to date" out
 '
 
 test_expect_success 'rebase fast-forward to master' '
        git checkout my-topic-branch^ &&
        git rebase my-topic-branch >out &&
-       grep "Fast-forwarded HEAD to my-topic-branch" out
+       test_i18ngrep "Fast-forwarded HEAD to my-topic-branch" out
 '
 
 test_expect_success 'the rebase operation should not have destroyed author information' '
index 3f75d328de8ee08e0d27b3eb589d9c247182d435..7304b663c31992de232736a3d9201bb878d2c6f4 100755 (executable)
@@ -858,7 +858,7 @@ test_expect_success 'rebase -ix with --autosquash' '
 test_expect_success 'rebase --exec without -i shows error message' '
        git reset --hard execute &&
        test_must_fail git rebase --exec "git show HEAD" HEAD~2 2>actual &&
-       echo "--exec option must be used with --interactive option" >expected &&
+       echo "The --exec option must be used with the --interactive option" >expected &&
        test_i18ncmp expected actual
 '
 
index 6898377910f9fce8ccc73fba7b8140dff53d7ec6..e6a9a0d436f3a28a7de6eaadd7f1f223ae740c64 100755 (executable)
@@ -62,9 +62,16 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '
         ! grep "^ fileX |  *1 +$" diffstat.txt
 '
 
+# Output to stderr:
+#
+#     "Does not point to a valid commit: invalid-ref"
+#
+# NEEDSWORK: This "grep" is fine in real non-C locales, but
+# GETTEXT_POISON poisons the refname along with the enclosing
+# error message.
 test_expect_success 'rebase --onto outputs the invalid ref' '
        test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
-       grep "invalid-ref" err
+       test_i18ngrep "invalid-ref" err
 '
 
 test_done
index 1104249182074c1a987905e1661356ff8da7580c..c680f789a7028f5300a4665ca068c9a7e87bb22a 100755 (executable)
@@ -242,10 +242,10 @@ test_expect_success 'merge of identical changes in a renamed file' '
        rm -f A M N &&
        git reset --hard &&
        git checkout change+rename &&
-       GIT_MERGE_VERBOSITY=3 git merge change | grep "^Skipped B" &&
+       GIT_MERGE_VERBOSITY=3 git merge change | test_i18ngrep "^Skipped B" &&
        git reset --hard HEAD^ &&
        git checkout change &&
-       GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B"
+       GIT_MERGE_VERBOSITY=3 git merge change+rename | test_i18ngrep "^Skipped B"
 '
 
 test_expect_success 'setup for rename + d/f conflicts' '
@@ -303,9 +303,9 @@ test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' '
        git checkout -q renamed-file-has-no-conflicts^0 &&
        test_must_fail git merge --strategy=recursive dir-in-way >output &&
 
-       grep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
-       grep "Auto-merging dir" output &&
-       grep "Adding as dir~HEAD instead" output &&
+       test_i18ngrep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
+       test_i18ngrep "Auto-merging dir" output &&
+       test_i18ngrep "Adding as dir~HEAD instead" output &&
 
        test 3 -eq "$(git ls-files -u | wc -l)" &&
        test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
@@ -325,9 +325,9 @@ test_expect_success 'Same as previous, but merged other way' '
        test_must_fail git merge --strategy=recursive renamed-file-has-no-conflicts >output 2>errors &&
 
        ! grep "error: refusing to lose untracked file at" errors &&
-       grep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
-       grep "Auto-merging dir" output &&
-       grep "Adding as dir~renamed-file-has-no-conflicts instead" output &&
+       test_i18ngrep "CONFLICT (modify/delete): dir/file-in-the-way" output &&
+       test_i18ngrep "Auto-merging dir" output &&
+       test_i18ngrep "Adding as dir~renamed-file-has-no-conflicts instead" output &&
 
        test 3 -eq "$(git ls-files -u | wc -l)" &&
        test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" &&
index 466fa3804bc8a840d994e9d2e9092f599cc87eab..411550d2b6e9085c5e7f93c25effec7b130f0401 100755 (executable)
@@ -380,7 +380,7 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' '
        git checkout B^0 &&
 
        test_must_fail git merge -s recursive C^0 >out &&
-       grep "CONFLICT (rename/rename)" out &&
+       test_i18ngrep "CONFLICT (rename/rename)" out &&
 
        test 2 -eq $(git ls-files -s | wc -l) &&
        test 2 -eq $(git ls-files -u | wc -l) &&
diff --git a/t/t7409-submodule-detached-worktree.sh b/t/t7409-submodule-detached-worktree.sh
new file mode 100755 (executable)
index 0000000..2fec13d
--- /dev/null
@@ -0,0 +1,78 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Daniel Graña
+#
+
+test_description='Test submodules on detached working tree
+
+This test verifies that "git submodule" initialization, update and addition works
+on detahced working trees
+'
+
+TEST_NO_CREATE_REPO=1
+. ./test-lib.sh
+
+test_expect_success 'submodule on detached working tree' '
+       git init --bare remote &&
+       test_create_repo bundle1 &&
+       (
+               cd bundle1 &&
+               test_commit "shoot" &&
+               git rev-parse --verify HEAD >../expect
+       ) &&
+       mkdir home &&
+       (
+               cd home &&
+               export GIT_WORK_TREE="$(pwd)" GIT_DIR="$(pwd)/.dotfiles" &&
+               git clone --bare ../remote .dotfiles &&
+               git submodule add ../bundle1 .vim/bundle/sogood &&
+               test_commit "sogood" &&
+               (
+                       unset GIT_WORK_TREE GIT_DIR &&
+                       cd .vim/bundle/sogood &&
+                       git rev-parse --verify HEAD >actual &&
+                       test_cmp ../../../../expect actual
+               ) &&
+               git push origin master
+       ) &&
+       mkdir home2 &&
+       (
+               cd home2 &&
+               git clone --bare ../remote .dotfiles &&
+               export GIT_WORK_TREE="$(pwd)" GIT_DIR="$(pwd)/.dotfiles" &&
+               git checkout master &&
+               git submodule update --init &&
+               (
+                       unset GIT_WORK_TREE GIT_DIR &&
+                       cd .vim/bundle/sogood &&
+                       git rev-parse --verify HEAD >actual &&
+                       test_cmp ../../../../expect actual
+               )
+       )
+'
+
+test_expect_success 'submodule on detached working pointed by core.worktree' '
+       mkdir home3 &&
+       (
+               cd home3 &&
+               export GIT_DIR="$(pwd)/.dotfiles" &&
+               git clone --bare ../remote "$GIT_DIR" &&
+               git config core.bare false &&
+               git config core.worktree .. &&
+               git checkout master &&
+               git submodule add ../bundle1 .vim/bundle/dupe &&
+               test_commit "dupe" &&
+               git push origin master
+       ) &&
+       (
+               cd home &&
+               export GIT_DIR="$(pwd)/.dotfiles" &&
+               git config core.bare false &&
+               git config core.worktree .. &&
+               git pull &&
+               git submodule update --init &&
+               test -f .vim/bundle/dupe/shoot.t
+       )
+'
+
+test_done
index 181456aa9a80893e93477302516a7f00594eba85..deb187eb7b4277a43f46e73c1d85012b728ce14a 100755 (executable)
@@ -235,44 +235,56 @@ test_expect_success 'cleanup commit messages (strip,-F,-e): output' '
        test_i18ncmp expect actual
 '
 
-echo "#
-# Author:    $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
-#" >> expect
-
-test_expect_success 'author different from committer' '
+test_expect_success 'message shows author when it is not equal to committer' '
        echo >>negative &&
-       test_might_fail git commit -e -m "sample" &&
-       head -n 7 .git/COMMIT_EDITMSG >actual &&
-       test_i18ncmp expect actual
+       git commit -e -m "sample" -a &&
+       test_i18ngrep \
+         "^# Author: *A U Thor <author@example.com>\$" \
+         .git/COMMIT_EDITMSG
 '
 
-mv expect expect.tmp
-sed '$d' < expect.tmp > expect
-rm -f expect.tmp
-echo "# Committer:
-#" >> expect
+test_expect_success 'setup auto-ident prerequisite' '
+       if (sane_unset GIT_COMMITTER_EMAIL &&
+           sane_unset GIT_COMMITTER_NAME &&
+           git var GIT_COMMITTER_IDENT); then
+               test_set_prereq AUTOIDENT
+       else
+               test_set_prereq NOAUTOIDENT
+       fi
+'
 
-test_expect_success 'committer is automatic' '
+test_expect_success AUTOIDENT 'message shows committer when it is automatic' '
 
        echo >>negative &&
        (
                sane_unset GIT_COMMITTER_EMAIL &&
                sane_unset GIT_COMMITTER_NAME &&
-               # must fail because there is no change
-               test_must_fail git commit -e -m "sample"
+               git commit -e -m "sample" -a
        ) &&
-       head -n 8 .git/COMMIT_EDITMSG | \
-       sed "s/^# Committer: .*/# Committer:/" >actual
-       test_i18ncmp expect actual
+       # the ident is calculated from the system, so we cannot
+       # check the actual value, only that it is there
+       test_i18ngrep "^# Committer: " .git/COMMIT_EDITMSG
 '
 
-pwd=`pwd`
-cat >> .git/FAKE_EDITOR << EOF
-#! /bin/sh
-echo editor started > "$pwd/.git/result"
+write_script .git/FAKE_EDITOR <<EOF
+echo editor started > "$(pwd)/.git/result"
 exit 0
 EOF
-chmod +x .git/FAKE_EDITOR
+
+test_expect_success NOAUTOIDENT 'do not fire editor when committer is bogus' '
+       >.git/result
+       >expect &&
+
+       echo >>negative &&
+       (
+               sane_unset GIT_COMMITTER_EMAIL &&
+               sane_unset GIT_COMMITTER_NAME &&
+               GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" &&
+               export GIT_EDITOR &&
+               test_must_fail git commit -e -m sample -a
+       ) &&
+       test_cmp expect .git/result
+'
 
 test_expect_success 'do not fire editor in the presence of conflicts' '
 
@@ -293,16 +305,14 @@ test_expect_success 'do not fire editor in the presence of conflicts' '
        test_must_fail git cherry-pick -n master &&
        echo "editor not started" >.git/result &&
        (
-               GIT_EDITOR="$(pwd)/.git/FAKE_EDITOR" &&
+               GIT_EDITOR="\"$(pwd)/.git/FAKE_EDITOR\"" &&
                export GIT_EDITOR &&
                test_must_fail git commit
        ) &&
        test "$(cat .git/result)" = "editor not started"
 '
 
-pwd=`pwd`
-cat >.git/FAKE_EDITOR <<EOF
-#! $SHELL_PATH
+write_script .git/FAKE_EDITOR <<EOF
 # kill -TERM command added below.
 EOF
 
@@ -339,13 +349,12 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo
 
 '
 
-cat >.git/FAKE_EDITOR <<EOF
-#!$SHELL_PATH
-mv "\$1" "\$1.orig"
+write_script .git/FAKE_EDITOR <<\EOF
+mv "$1" "$1.orig"
 (
        echo message
-       cat "\$1.orig"
-) >"\$1"
+       cat "$1.orig"
+) >"$1"
 EOF
 
 echo '## Custom template' >template
index 24e9b1974d17a02dd1c668e888a67f894e7a1209..523d04123d02cabb8703f91e9bec194c7d737f00 100755 (executable)
@@ -399,17 +399,6 @@ test_expect_success 'grep -q, silently report matches' '
        test_cmp empty actual
 '
 
-# Create 1024 file names that sort between "y" and "z" to make sure
-# the two files are handled by different calls to an external grep.
-# This depends on MAXARGS in builtin-grep.c being 1024 or less.
-c32="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v"
-test_expect_success 'grep -C1, hunk mark between files' '
-       for a in $c32; do for b in $c32; do : >y-$a$b; done; done &&
-       git add y-?? &&
-       git grep -C1 "^[yz]" >actual &&
-       test_cmp expected actual
-'
-
 test_expect_success 'grep -C1 hunk mark between files' '
        git grep -C1 "^[yz]" >actual &&
        test_cmp expected actual
index 289fc313fb737ac7895580fd8407cff758b085e7..ee73013eed0b1c6410319aa3d7e4e57ea242a594 100755 (executable)
@@ -27,15 +27,17 @@ test_expect_success 'setup old-looking metadata' '
 head=`git rev-parse --verify refs/heads/git-svn-HEAD^0`
 test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'"
 
+svnrepo_escaped=`echo $svnrepo | sed 's/ /%20/'`
+
 test_expect_success 'initialize old-style (v0) git svn layout' '
        mkdir -p "$GIT_DIR"/git-svn/info "$GIT_DIR"/svn/info &&
        echo "$svnrepo" > "$GIT_DIR"/git-svn/info/url &&
        echo "$svnrepo" > "$GIT_DIR"/svn/info/url &&
        git svn migrate &&
-       ! test -d "$GIT_DIR"/git svn &&
+       ! test -d "$GIT_DIR"/git-svn &&
        git rev-parse --verify refs/${remotes_git_svn}^0 &&
        git rev-parse --verify refs/remotes/svn^0 &&
-       test "$(git config --get svn-remote.svn.url)" = "$svnrepo" &&
+       test "$(git config --get svn-remote.svn.url)" = "$svnrepo_escaped" &&
        test `git config --get svn-remote.svn.fetch` = \
              ":refs/${remotes_git_svn}"
        '
index 63fc982c8cdbd9c19eb06bba58ad5e86da5dd03e..193d3cabddec0c4ed63edeade9b3fb93bef790bb 100755 (executable)
@@ -32,6 +32,11 @@ test_expect_success 'setup svnrepo' '
        start_httpd
        '
 
+# SVN 1.7 will truncate "not-a%40{0]" to just "not-a".
+# Look at what SVN wound up naming the branch and use that.
+# Be sure to escape the @ if it shows up.
+non_reflog=`svn_cmd ls "$svnrepo/pr ject/branches" | grep not-a | sed 's/\///' | sed 's/@/%40/'`
+
 test_expect_success 'test clone with funky branch names' '
        git svn clone -s "$svnrepo/pr ject" project &&
        (
@@ -42,7 +47,7 @@ test_expect_success 'test clone with funky branch names' '
                git rev-parse "refs/remotes/%2Eleading_dot" &&
                git rev-parse "refs/remotes/trailing_dot%2E" &&
                git rev-parse "refs/remotes/trailing_dotlock%2Elock" &&
-               git rev-parse "refs/remotes/not-a%40{0}reflog"
+               git rev-parse "refs/remotes/$non_reflog"
        )
        '
 
diff --git a/t/t9163-git-svn-reset-clears-caches.sh b/t/t9163-git-svn-reset-clears-caches.sh
new file mode 100755 (executable)
index 0000000..cd4c662
--- /dev/null
@@ -0,0 +1,78 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Peter Baumann
+#
+
+test_description='git svn reset clears memoized caches'
+. ./lib-git-svn.sh
+
+svn_ver="$(svn --version --quiet)"
+case $svn_ver in
+0.* | 1.[0-4].*)
+       skip_all="skipping git-svn test - SVN too old ($svn_ver)"
+       test_done
+       ;;
+esac
+
+# ... a  -  b - m   <- trunk
+#      \       /
+#       ... c       <- branch1
+#
+# SVN Commits not interesting for this test are abbreviated with "..."
+#
+test_expect_success 'initialize source svn repo' '
+       svn_cmd mkdir -m "create trunk" "$svnrepo"/trunk &&
+       svn_cmd mkdir -m "create branches" "$svnrepo/branches" &&
+       svn_cmd co "$svnrepo"/trunk "$SVN_TREE" &&
+       (
+               cd "$SVN_TREE" &&
+               touch foo &&
+               svn_cmd add foo &&
+               svn_cmd commit -m "a" &&
+               svn_cmd cp -m branch "$svnrepo"/trunk "$svnrepo"/branches/branch1 &&
+               svn_cmd switch "$svnrepo"/branches/branch1 &&
+               touch bar &&
+               svn_cmd add bar &&
+               svn_cmd commit -m b &&
+               svn_cmd switch "$svnrepo"/trunk &&
+               touch baz &&
+               svn_cmd add baz &&
+               svn_cmd commit -m c &&
+               svn_cmd up &&
+               svn_cmd merge "$svnrepo"/branches/branch1 &&
+               svn_cmd commit -m "m"
+       ) &&
+       rm -rf "$SVN_TREE"
+'
+
+test_expect_success 'fetch to merge-base (a)' '
+       git svn init -s "$svnrepo" &&
+       git svn fetch --revision BASE:3
+'
+
+# git svn rebase looses the merge commit
+#
+# ... a  -  b - m  <- trunk
+#      \
+#       ... c
+#
+test_expect_success 'rebase looses SVN merge (m)' '
+       git svn rebase &&
+       git svn fetch &&
+       test 1 = $(git cat-file -p master|grep parent|wc -l)
+'
+
+# git svn fetch creates correct history with merge commit
+#
+# ... a  -  b - m  <- trunk
+#      \       /
+#       ... c      <- branch1
+#
+test_expect_success 'reset and fetch gets the SVN merge (m) correctly' '
+       git svn reset -r 3 &&
+       git reset --hard trunk &&
+       git svn fetch &&
+       test 2 = $(git cat-file -p trunk|grep parent|wc -l)
+'
+
+test_done
diff --git a/t/t9164-git-svn-dcommit-concrrent.sh b/t/t9164-git-svn-dcommit-concrrent.sh
new file mode 100755 (executable)
index 0000000..aac2dda
--- /dev/null
@@ -0,0 +1,216 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Robert Luberda
+#
+
+test_description='concurrent git svn dcommit'
+. ./lib-git-svn.sh
+
+
+
+test_expect_success 'setup svn repository' '
+       svn_cmd checkout "$svnrepo" work.svn &&
+       (
+               cd work.svn &&
+               echo >file && echo > auto_updated_file
+               svn_cmd add file auto_updated_file &&
+               svn_cmd commit -m "initial commit"
+       ) &&
+       svn_cmd checkout "$svnrepo" work-auto-commits.svn
+'
+N=0
+next_N()
+{
+       N=$(( $N + 1 ))
+}
+
+# Setup SVN repository hooks to emulate SVN failures or concurrent commits
+# The function adds
+# either pre-commit  hook, which causes SVN commit given in second argument
+#                    to fail
+# or     post-commit hook, which creates a new commit (a new line added to
+#                    auto_updated_file) after given SVN commit
+# The first argument contains a type of the hook
+# The second argument contains a number (not SVN revision) of commit
+# the hook should be applied for (each time the hook is run, the given
+# number is decreased by one until it gets 0, in which case the hook
+# will execute its real action)
+setup_hook()
+{
+       hook_type="$1"  # "pre-commit" or "post-commit"
+       skip_revs="$2"
+       [ "$hook_type" = "pre-commit" ] ||
+               [ "$hook_type" = "post-commit" ] ||
+               { echo "ERROR: invalid argument ($hook_type)" \
+                       "passed to setup_hook" >&2 ; return 1; }
+       echo "cnt=$skip_revs" > "$hook_type-counter"
+       rm -f "$rawsvnrepo/hooks/"*-commit # drop previous hooks
+       hook="$rawsvnrepo/hooks/$hook_type"
+       cat > "$hook" <<- 'EOF1'
+               #!/bin/sh
+               set -e
+               cd "$1/.."  # "$1" is repository location
+               exec >> svn-hook.log 2>&1
+               hook="$(basename "$0")"
+               echo "*** Executing $hook $@"
+               set -x
+               . ./$hook-counter
+               cnt="$(($cnt - 1))"
+               echo "cnt=$cnt" > ./$hook-counter
+               [ "$cnt" = "0" ] || exit 0
+EOF1
+       if [ "$hook_type" = "pre-commit" ]; then
+               echo "echo 'commit disallowed' >&2; exit 1" >> "$hook"
+       else
+               echo "PATH=\"$PATH\"; export PATH" >> $hook
+               echo "svnconf=\"$svnconf\"" >> $hook
+               cat >> "$hook" <<- 'EOF2'
+                       cd work-auto-commits.svn
+                       svn up --config-dir "$svnconf"
+                       echo "$$" >> auto_updated_file
+                       svn commit --config-dir "$svnconf" \
+                               -m "auto-committing concurrent change"
+                       exit 0
+EOF2
+       fi
+       chmod 755 "$hook"
+}
+
+check_contents()
+{
+       gitdir="$1"
+       (cd ../work.svn && svn_cmd up) &&
+       test_cmp file ../work.svn/file &&
+       test_cmp auto_updated_file ../work.svn/auto_updated_file
+}
+
+test_expect_success 'check if post-commit hook creates a concurrent commit' '
+       setup_hook post-commit 1 &&
+       (
+               cd work.svn &&
+               cp auto_updated_file au_file_saved &&
+               echo 1 >> file &&
+               svn_cmd commit -m "changing file" &&
+               svn_cmd up &&
+               test_must_fail test_cmp auto_updated_file au_file_saved
+       )
+'
+
+test_expect_success 'check if pre-commit hook fails' '
+       setup_hook pre-commit 2 &&
+       (
+               cd work.svn &&
+               echo 2 >> file &&
+               svn_cmd commit -m "changing file once again" &&
+               echo 3 >> file &&
+               test_must_fail svn_cmd commit -m "this commit should fail" &&
+               svn_cmd revert file
+       )
+'
+
+test_expect_success 'dcommit error handling' '
+       setup_hook pre-commit 2 &&
+       next_N && git svn clone "$svnrepo" work$N.git &&
+       (
+               cd work$N.git &&
+               echo 1 >> file && git commit -am "commit change $N.1" &&
+               echo 2 >> file && git commit -am "commit change $N.2" &&
+               echo 3 >> file && git commit -am "commit change $N.3" &&
+               # should fail to dcommit 2nd and 3rd change
+               # but still should leave the repository in reasonable state
+               test_must_fail git svn dcommit &&
+               git update-index --refresh &&
+               git show HEAD~2   | grep -q git-svn-id &&
+               ! git show HEAD~1 | grep -q git-svn-id &&
+               ! git show HEAD   | grep -q git-svn-id
+       )
+'
+
+test_expect_success 'dcommit concurrent change in non-changed file' '
+       setup_hook post-commit 2 &&
+       next_N && git svn clone "$svnrepo" work$N.git &&
+       (
+               cd work$N.git &&
+               echo 1 >> file && git commit -am "commit change $N.1" &&
+               echo 2 >> file && git commit -am "commit change $N.2" &&
+               echo 3 >> file && git commit -am "commit change $N.3" &&
+               # should rebase and leave the repository in reasonable state
+               git svn dcommit &&
+               git update-index --refresh &&
+               check_contents &&
+               git show HEAD~3 | grep -q git-svn-id &&
+               git show HEAD~2 | grep -q git-svn-id &&
+               git show HEAD~1 | grep -q auto-committing &&
+               git show HEAD   | grep -q git-svn-id
+       )
+'
+
+# An utility function used in the following test
+delete_first_line()
+{
+       file="$1" &&
+       sed 1d < "$file" > "${file}.tmp" &&
+       rm "$file" &&
+       mv "${file}.tmp" "$file"
+}
+
+test_expect_success 'dcommit concurrent non-conflicting change' '
+       setup_hook post-commit 2 &&
+       next_N && git svn clone "$svnrepo" work$N.git &&
+       (
+               cd work$N.git &&
+               cat file >> auto_updated_file &&
+                       git commit -am "commit change $N.1" &&
+               delete_first_line auto_updated_file &&
+                       git commit -am "commit change $N.2" &&
+               delete_first_line auto_updated_file &&
+                       git commit -am "commit change $N.3" &&
+               # should rebase and leave the repository in reasonable state
+               git svn dcommit &&
+               git update-index --refresh &&
+               check_contents &&
+               git show HEAD~3 | grep -q git-svn-id &&
+               git show HEAD~2 | grep -q git-svn-id &&
+               git show HEAD~1 | grep -q auto-committing &&
+               git show HEAD   | grep -q git-svn-id
+       )
+'
+
+test_expect_success 'dcommit --no-rebase concurrent non-conflicting change' '
+       setup_hook post-commit 2 &&
+       next_N && git svn clone "$svnrepo" work$N.git &&
+       (
+               cd work$N.git &&
+               cat file >> auto_updated_file &&
+                       git commit -am "commit change $N.1" &&
+               delete_first_line auto_updated_file &&
+                       git commit -am "commit change $N.2" &&
+               delete_first_line auto_updated_file &&
+                       git commit -am "commit change $N.3" &&
+               # should fail as rebase is needed
+               test_must_fail git svn dcommit --no-rebase &&
+               # but should leave HEAD unchanged
+               git update-index --refresh &&
+               ! git show HEAD~2 | grep -q git-svn-id &&
+               ! git show HEAD~1 | grep -q git-svn-id &&
+               ! git show HEAD   | grep -q git-svn-id
+       )
+'
+
+test_expect_success 'dcommit fails on concurrent conflicting change' '
+       setup_hook post-commit 1 &&
+       next_N && git svn clone "$svnrepo" work$N.git &&
+       (
+               cd work$N.git &&
+               echo a >> file &&
+                       git commit -am "commit change $N.1" &&
+               echo b >> auto_updated_file &&
+                       git commit -am "commit change $N.2" &&
+               echo c >> auto_updated_file &&
+                       git commit -am "commit change $N.3" &&
+               test_must_fail git svn dcommit && # rebase should fail
+               test_must_fail git update-index --refresh
+       )
+'
+
+test_done
index 61c928f6cd85aa9cf60942208423e615c9b99352..cfe098849022fcc56bcb1a57d00e4c89e753492b 100644 (file)
@@ -444,6 +444,21 @@ static int fetch_with_import(struct transport *transport,
        free(fastimport.argv);
        fastimport.argv = NULL;
 
+       /*
+        * The fast-import stream of a remote helper that advertises
+        * the "refspec" capability writes to the refs named after the
+        * right hand side of the first refspec matching each ref we
+        * were fetching.
+        *
+        * (If no "refspec" capability was specified, for historical
+        * reasons we default to *:*.)
+        *
+        * Store the result in to_fetch[i].old_sha1.  Callers such
+        * as "git fetch" can use the value to write feedback to the
+        * terminal, populate FETCH_HEAD, and determine what new value
+        * should be written to peer_ref if the update is a
+        * fast-forward or this is a forced update.
+        */
        for (i = 0; i < nr_heads; i++) {
                char *private;
                posn = to_fetch[i];